#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <chrono>

extern "C" {
#include <tree_sitter/api.h>
}

extern "C" const TSLanguage* tree_sitter_tsf(void);

#include "../../src/language/ast/deserializer.hpp"
#include "../../src/language/symbol/table.hpp"
#include "./debug_printer.hpp"

using namespace lsp::language;

// ==================== 文件读取 ====================

std::string ReadFile(const std::string& filepath)
{
    std::ifstream file(filepath);
    if (!file.is_open())
    {
        throw std::runtime_error("Cannot open file: " + filepath);
    }

    std::ostringstream oss;
    oss << file.rdbuf();
    return oss.str();
}

// ==================== Tree-Sitter 解析器 ====================

class TreeSitterParser
{
public:
    TreeSitterParser()
    {
        parser_ = ts_parser_new();
        if (!parser_)
        {
            throw std::runtime_error("Failed to create parser");
        }

        if (!ts_parser_set_language(parser_, tree_sitter_tsf()))
        {
            ts_parser_delete(parser_);
            throw std::runtime_error("Failed to set language");
        }
    }

    ~TreeSitterParser()
    {
        if (tree_)
        {
            ts_tree_delete(tree_);
        }
        if (parser_)
        {
            ts_parser_delete(parser_);
        }
    }

    TSTree* Parse(const std::string& source)
    {
        if (tree_)
        {
            ts_tree_delete(tree_);
            tree_ = nullptr;
        }

        tree_ = ts_parser_parse_string(
            parser_,
            nullptr,
            source.c_str(),
            source.length());

        if (!tree_)
        {
            throw std::runtime_error("Failed to parse source");
        }

        return tree_;
    }

    TSNode GetRootNode()
    {
        if (!tree_)
        {
            throw std::runtime_error("No tree available");
        }
        return ts_tree_root_node(tree_);
    }

private:
    TSParser* parser_ = nullptr;
    TSTree* tree_ = nullptr;
};

// ==================== 命令行选项 ====================

struct Options
{
    std::string input_file;
    std::string output_file;
    bool print_all = true;
    bool print_definitions = false;
    bool print_scopes = false;
    bool print_references = false;
    bool print_inheritance = false;
    bool print_calls = false;
    bool compact_mode = false;
    bool statistics_only = false;
    std::string search_symbol;
    bool verbose = false;
    bool show_ast = false;
    bool no_color = false;
    bool print_overview = false;
};

void PrintUsage(const char* program_name)
{
    std::cout << "Symbol Table Analyzer - Analyze source code symbols\n\n";
    std::cout << "Usage: " << program_name << " <input_file> [options]\n\n";
    std::cout << "Options:\n";
    std::cout << "  -o, --output <file>     Write output to file instead of stdout\n";
    std::cout << "  -d, --definitions       Print only symbol definitions\n";
    std::cout << "  -s, --scopes            Print only scope hierarchy\n";
    std::cout << "  -r, --references        Print only references\n";
    std::cout << "  -i, --inheritance       Print only inheritance graph\n";
    std::cout << "  -c, --calls             Print only call graph\n";
    std::cout << "  -C, --compact           Use compact output format\n";
    std::cout << "  -S, --stats             Print statistics only\n";
    std::cout << "  -O, --overview          Print overview only\n";
    std::cout << "  -f, --find <name>       Search for a specific symbol\n";
    std::cout << "  -v, --verbose           Enable verbose output\n";
    std::cout << "  -a, --ast               Show AST structure\n";
    std::cout << "  --no-color              Disable colored output\n";
    std::cout << "  -h, --help              Show this help message\n\n";
    std::cout << "Examples:\n";
    std::cout << "  " << program_name << " program.tsf\n";
    std::cout << "  " << program_name << " program.tsf -o symbols.txt\n";
    std::cout << "  " << program_name << " program.tsf --definitions --scopes\n";
    std::cout << "  " << program_name << " program.tsf --find MyClass\n";
    std::cout << "  " << program_name << " program.tsf --compact --stats\n";
    std::cout << "  " << program_name << " program.tsf --overview\n";
}

bool ParseArguments(int argc, char* argv[], Options& options)
{
    if (argc < 2)
        return false;

    options.input_file = argv[1];
    bool any_specific_print = false;

    for (int i = 2; i < argc; ++i)
    {
        std::string arg = argv[i];

        if (arg == "-h" || arg == "--help")
        {
            return false;
        }
        else if (arg == "-o" || arg == "--output")
        {
            if (i + 1 < argc)
            {
                options.output_file = argv[++i];
            }
            else
            {
                std::cerr << "Error: " << arg << " requires an argument\n";
                return false;
            }
        }
        else if (arg == "-d" || arg == "--definitions")
        {
            options.print_definitions = true;
            any_specific_print = true;
        }
        else if (arg == "-s" || arg == "--scopes")
        {
            options.print_scopes = true;
            any_specific_print = true;
        }
        else if (arg == "-r" || arg == "--references")
        {
            options.print_references = true;
            any_specific_print = true;
        }
        else if (arg == "-i" || arg == "--inheritance")
        {
            options.print_inheritance = true;
            any_specific_print = true;
        }
        else if (arg == "-c" || arg == "--calls")
        {
            options.print_calls = true;
            any_specific_print = true;
        }
        else if (arg == "-C" || arg == "--compact")
        {
            options.compact_mode = true;
        }
        else if (arg == "-S" || arg == "--stats")
        {
            options.statistics_only = true;
            any_specific_print = true;
        }
        else if (arg == "-O" || arg == "--overview")
        {
            options.print_overview = true;
            any_specific_print = true;
        }
        else if (arg == "-f" || arg == "--find")
        {
            if (i + 1 < argc)
            {
                options.search_symbol = argv[++i];
            }
            else
            {
                std::cerr << "Error: " << arg << " requires an argument\n";
                return false;
            }
        }
        else if (arg == "-v" || arg == "--verbose")
        {
            options.verbose = true;
        }
        else if (arg == "-a" || arg == "--ast")
        {
            options.show_ast = true;
        }
        else if (arg == "--no-color")
        {
            options.no_color = true;
        }
        else
        {
            std::cerr << "Error: Unknown option: " << arg << "\n";
            return false;
        }
    }

    if (any_specific_print)
        options.print_all = false;

    return true;
}

std::string NodeKindToString(ast::NodeKind kind)
{
    switch (kind)
    {
    case ast::NodeKind::kProgram: return "Program";
    case ast::NodeKind::kFunctionDefinition: return "FunctionDefinition";
    case ast::NodeKind::kClassDefinition: return "ClassDefinition";
    case ast::NodeKind::kUnitDefinition: return "UnitDefinition";
    case ast::NodeKind::kVarStatement: return "VarStatement";
    case ast::NodeKind::kConstStatement: return "ConstStatement";
    case ast::NodeKind::kIfStatement: return "IfStatement";
    case ast::NodeKind::kForInStatement: return "ForInStatement";
    case ast::NodeKind::kWhileStatement: return "WhileStatement";
    // ... 添加其他类型
    default: return "Unknown";
    }
}

void PrintASTStructure(const ast::ParseResult& parse_result, std::ostream& os)
{
    os << "\n╔════════════════════════════════════════════════════════════╗\n";
    os << "║                    AST STRUCTURE                           ║\n";
    os << "╚════════════════════════════════════════════════════════════╝\n\n";

    os << "Statements: " << parse_result.root->statements.size() << "\n\n";

    for (size_t i = 0; i < parse_result.root->statements.size(); ++i)
    {
        const auto& stmt = parse_result.root->statements[i];
        if (!stmt)
            continue;

        // 修复：使用 kind 和 span
        os << "[" << i << "] " << NodeKindToString(stmt->kind)
           << " at [" << stmt->span.start_line << ":" << stmt->span.start_column << "]";

        // 打印特定类型的详细信息
        if (auto* func_def = dynamic_cast<ast::FunctionDefinition*>(stmt.get()))
        {
            os << " - Function: " << func_def->name;
        }
        else if (auto* class_def = dynamic_cast<ast::ClassDefinition*>(stmt.get()))
        {
            os << " - Class: " << class_def->name;
        }
        else if (auto* unit_def = dynamic_cast<ast::UnitDefinition*>(stmt.get()))
        {
            os << " - Unit: " << unit_def->name;
        }

        os << "\n";
    }

    os << "\n";
}

// ==================== 主分析函数 ====================

void AnalyzeFile(const Options& options)
{
    // 打印头部
    if (!options.compact_mode)
    {
        std::cout << "\n╔════════════════════════════════════════════════════════════╗\n";
        std::cout << "║          SYMBOL TABLE ANALYZER                             ║\n";
        std::cout << "╚════════════════════════════════════════════════════════════╝\n\n";
        std::cout << "Input file: " << options.input_file << "\n";
    }

    // 1. 读取源文件
    if (options.verbose)
        std::cout << "Reading file...\n";

    std::string source = ReadFile(options.input_file);

    if (options.verbose)
    {
        std::cout << "File size: " << source.length() << " bytes\n";
        std::cout << "----------------------------------------\n";
        std::cout << source << "\n";
        std::cout << "----------------------------------------\n\n";
    }

    // 2. 使用 Tree-Sitter 解析
    if (options.verbose)
        std::cout << "Parsing with Tree-Sitter...\n";

    TreeSitterParser ts_parser;
    [[maybe_unused]] TSTree* tree = ts_parser.Parse(source);
    TSNode root = ts_parser.GetRootNode();

    if (options.verbose)
    {
        std::cout << "Root node type: " << ts_node_type(root) << "\n";
        std::cout << "Root node child count: " << ts_node_child_count(root) << "\n\n";
    }

    // 3. 反序列化为 AST
    if (options.verbose)
        std::cout << "Deserializing to AST...\n";

    ast::Deserializer deserializer;
    ast::ParseResult parse_result = deserializer.Parse(root, source);

    if (parse_result.HasErrors())
    {
        std::cerr << "\n⚠️  Parse Errors:\n";
        for (const auto& error : parse_result.errors)
        {
            std::cerr << "  [" << error.location.start_line << ":"
                      << error.location.start_column << "] "
                      << error.message << "\n";
        }
        std::cerr << "\n";
    }

    if (options.show_ast)
    {
        PrintASTStructure(parse_result, std::cout);
    }

    // 4. 构建符号表
    if (options.verbose)
        std::cout << "Building symbol table...\n";

    symbol::SymbolTable table;
    auto start = std::chrono::high_resolution_clock::now();

    table.Build(*parse_result.root);

    auto end = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

    if (options.verbose)
        std::cout << "Symbol table built in " << duration.count() << " ms\n\n";

    // 5. 准备输出流
    std::ostream* out = &std::cout;
    std::ofstream file_out;

    if (!options.output_file.empty())
    {
        file_out.open(options.output_file);
        if (!file_out.is_open())
        {
            std::cerr << "Error: Cannot write to file: " << options.output_file << "\n";
            return;
        }
        out = &file_out;

        // 写入文件头
        *out << "Symbol Table Analysis\n";
        *out << "Source: " << options.input_file << "\n";
        auto now = std::chrono::system_clock::now();
        auto time = std::chrono::system_clock::to_time_t(now);
        *out << "Generated: " << std::ctime(&time);
        *out << std::string(80, '=') << "\n\n";
    }

    // 6. ✅ 使用新的 debug_print API

    // 配置打印选项
    symbol::debug::PrintOptions print_opts;
    if (options.compact_mode)
        print_opts = symbol::debug::PrintOptions::Compact();
    else if (options.verbose)
        print_opts = symbol::debug::PrintOptions::Verbose();
    else
        print_opts = symbol::debug::PrintOptions::Default();

    if (options.no_color || !options.output_file.empty())
        print_opts.use_color = false;

    print_opts.show_references = options.print_references || options.verbose;

    // 创建打印器
    symbol::debug::DebugPrinter printer(table, print_opts);

    // 7. 执行查询或打印
    if (!options.search_symbol.empty())
    {
        // 搜索符号
        printer.FindAndPrint(options.search_symbol, *out);
    }
    else if (options.statistics_only)
    {
        // 只打印统计
        printer.PrintStatistics(*out);
    }
    else if (options.print_overview)
    {
        // 只打印概览
        printer.PrintOverview(*out);
    }
    else if (options.compact_mode)
    {
        // 紧凑模式
        symbol::debug::PrintCompact(table, *out);
    }
    else if (options.print_all)
    {
        // 打印所有内容
        printer.PrintAll(*out);
    }
    else
    {
        // 自定义打印
        bool printed_anything = false;

        if (options.print_definitions)
        {
            printer.PrintSymbolList(*out);
            printed_anything = true;
        }

        if (options.print_scopes)
        {
            printer.PrintScopeHierarchy(*out);
            printed_anything = true;
        }

        if (options.print_references)
        {
            printer.PrintAllReferences(*out);
            printed_anything = true;
        }

        if (options.print_inheritance)
        {
            printer.PrintAllInheritance(*out);
            printed_anything = true;
        }

        if (options.print_calls)
        {
            printer.PrintAllCalls(*out);
            printed_anything = true;
        }

        // 总是打印统计信息
        if (printed_anything)
        {
            *out << "\n";
        }
        printer.PrintStatistics(*out);
    }

    // 8. 完成
    if (file_out.is_open())
    {
        file_out.close();
        std::cout << "✓ Symbol table exported to: " << options.output_file << "\n";
    }

    // 9. 打印摘要
    if (!options.compact_mode)
    {
        std::cout << "\n========================================\n";
        std::cout << "Summary:\n";
        std::cout << "  File: " << options.input_file << "\n";
        std::cout << "  Size: " << source.length() << " bytes\n";
        std::cout << "  Lines: " << std::count(source.begin(), source.end(), '\n') + 1 << "\n";
        std::cout << "  Statements: " << parse_result.root->statements.size() << "\n";
        std::cout << "  Symbols: " << table.GetAllDefinitions().size() << "\n";
        std::cout << "  Scopes: " << table.GetScopeManager().GetAllScopes().size() << "\n";
        std::cout << "  Parse Errors: " << parse_result.errors.size() << "\n";
        std::cout << "  Build Time: " << duration.count() << " ms\n";

        if (parse_result.HasErrors())
        {
            std::cout << "  Status: ⚠️  COMPLETED WITH ERRORS\n";
        }
        else
        {
            std::cout << "  Status: ✓ SUCCESS\n";
        }
        std::cout << "========================================\n\n";
    }
}

// ==================== 主程序 ====================

int main(int argc, char* argv[])
{
    Options options;

    if (!ParseArguments(argc, argv, options))
    {
        PrintUsage(argv[0]);
        return 1;
    }

    try
    {
        AnalyzeFile(options);
        return 0;
    }
    catch (const std::exception& e)
    {
        std::cerr << "❌ Fatal error: " << e.what() << "\n";
        return 1;
    }
}
