#pragma once

#include <iostream>
#include <string>
#include <optional>
#include "../../src/language/ast/types.hpp"
#include "../../src/language/ast/deserializer.hpp"

namespace lsp::language::ast
{
    // ===== 打印配置 =====
    struct PrintOptions
    {
        bool show_source_code = false; // 是否显示源代码片段
        bool show_location = true; // 是否显示位置信息
        bool use_colors = true; // 是否使用颜色
        bool use_tree_chars = true; // 是否使用树形字符
        bool compact_mode = false; // 紧凑模式
        bool show_node_kind = false; // 是否显示节点类型枚举
        int indent_size = 2; // 缩进大小
        int max_source_length = 60; // 源码最大显示长度

        // 预设配置
        static PrintOptions Verbose()
        {
            PrintOptions opts;
            opts.show_source_code = true;
            opts.show_location = true;
            opts.show_node_kind = true;
            opts.compact_mode = false;
            return opts;
        }

        static PrintOptions Compact()
        {
            PrintOptions opts;
            opts.compact_mode = true;
            opts.use_tree_chars = false;
            opts.show_location = false;
            return opts;
        }

        static PrintOptions Default()
        {
            return PrintOptions();
        }
    };

    // ===== ANSI 颜色代码 =====
    namespace Color
    {
        inline const char* Reset = "\033[0m";
        inline const char* Bold = "\033[1m";
        inline const char* Dim = "\033[2m";

        // 前景色
        inline const char* Red = "\033[31m";
        inline const char* Green = "\033[32m";
        inline const char* Yellow = "\033[33m";
        inline const char* Blue = "\033[34m";
        inline const char* Magenta = "\033[35m";
        inline const char* Cyan = "\033[36m";
        inline const char* White = "\033[37m";
        inline const char* Gray = "\033[90m";

        // 亮色
        inline const char* BrightRed = "\033[91m";
        inline const char* BrightGreen = "\033[92m";
        inline const char* BrightYellow = "\033[93m";
        inline const char* BrightBlue = "\033[94m";
        inline const char* BrightMagenta = "\033[95m";
        inline const char* BrightCyan = "\033[96m";
    }

    class DebugPrinter : public ASTVisitor
    {
    public:
        explicit DebugPrinter(std::ostream& os = std::cout, const PrintOptions& opts = PrintOptions::Default()) :
            os_(os), options_(opts), current_indent_(0), source_code_(nullptr) {}

        void Print(const ASTNode* node);
        void PrintStatements(const std::vector<StatementPtr>& statements);
        void PrintParseResult(const ParseResult& result);

        // 设置源代码用于显示
        void SetSourceCode(const std::string* source) { source_code_ = source; }

        // 设置打印选项
        void SetOptions(const PrintOptions& opts) { options_ = opts; }

        // Visitor 接口实现
        void VisitProgram(Program& node) override;
        void VisitUnitDefinition(UnitDefinition& node) override;
        void VisitClassDefinition(ClassDefinition& node) override;
        void VisitClassMember(ClassMember& node) override;
        void VisitMethodDeclaration(MethodDeclaration& node) override;
        void VisitPropertyDeclaration(PropertyDeclaration& node) override;
        void VisitExternalMethodDefinition(ExternalMethodDefinition& node) override;
        void VisitIdentifier(Identifier& node) override;
        void VisitLiteral(Literal& node) override;
        void VisitBinaryExpression(BinaryExpression& node) override;
        void VisitComparisonExpression(ComparisonExpression& node) override;
        void VisitUnaryExpression(UnaryExpression& node) override;
        void VisitTernaryExpression(TernaryExpression& node) override;
        void VisitCallExpression(CallExpression& node) override;
        void VisitAttributeExpression(AttributeExpression& node) override;
        void VisitSubscriptExpression(SubscriptExpression& node) override;
        void VisitArrayExpression(ArrayExpression& node) override;
        void VisitAnonymousFunctionExpression(AnonymousFunctionExpression& node) override;
        void VisitPrefixIncrementExpression(PrefixIncrementExpression& node) override;
        void VisitPrefixDecrementExpression(PrefixDecrementExpression& node) override;
        void VisitPostfixIncrementExpression(PostfixIncrementExpression& node) override;
        void VisitPostfixDecrementExpression(PostfixDecrementExpression& node) override;
        void VisitFunctionPointerExpression(FunctionPointerExpression& node) override;
        void VisitAssignmentExpression(AssignmentExpression& node) override;
        void VisitExpressionStatement(ExpressionStatement& node) override;
        void VisitVarStatement(VarStatement& node) override;
        void VisitStaticStatement(StaticStatement& node) override;
        void VisitGlobalStatement(GlobalStatement& node) override;
        void VisitConstStatement(ConstStatement& node) override;
        void VisitAssignmentStatement(AssignmentStatement& node) override;
        void VisitBlockStatement(BlockStatement& node) override;
        void VisitIfStatement(IfStatement& node) override;
        void VisitForInStatement(ForInStatement& node) override;
        void VisitForToStatement(ForToStatement& node) override;
        void VisitWhileStatement(WhileStatement& node) override;
        void VisitRepeatStatement(RepeatStatement& node) override;
        void VisitCaseStatement(CaseStatement& node) override;
        void VisitTryStatement(TryStatement& node) override;
        void VisitBreakStatement(BreakStatement&) override;
        void VisitContinueStatement(ContinueStatement&) override;
        void VisitReturnStatement(ReturnStatement& node) override;
        void VisitUsesStatement(UsesStatement& node) override;
        void VisitFunctionDefinition(FunctionDefinition& node) override;
        void VisitFunctionDeclaration(FunctionDeclaration& node) override;
        void VisitVarDeclaration(VarDeclaration& node) override;
        void VisitStaticDeclaration(StaticDeclaration& node) override;
        void VisitGlobalDeclaration(GlobalDeclaration& node) override;
        void VisitFieldDeclaration(FieldDeclaration& node) override;
        void VisitUnpackPattern(UnpackPattern& node) override;
        void VisitTSSQLExpression(TSSQLExpression& node) override;
        void VisitMatrixIterationStatement(MatrixIterationStatement& node) override;
        void VisitCompilerDirectiveStatement(CompilerDirectiveStatement& node) override;
        void VisitConditionalBlockStatement(ConditionalBlockStatement& node) override;
        void VisitConditionalDirectiveStatement(ConditionalDirectiveStatement& node) override;

    private:
        std::ostream& os_;
        PrintOptions options_;
        int current_indent_;
        const std::string* source_code_;
        std::vector<bool> is_last_child_stack_; // 用于树形结构绘制

        // 缩进控制
        void IncreaseIndent() { current_indent_ += options_.indent_size; }
        void DecreaseIndent() { current_indent_ -= options_.indent_size; }

        // 输出辅助
        // is_last: if nullopt, will read from stack; if provided, uses the given value
        void PrintIndent(std::optional<bool> is_last = std::nullopt);
        void PrintTreePrefix(bool is_last = false);
        std::string GetIndent() const;

        // 颜色辅助
        const char* GetColor(const char* color) const;
        void PrintColored(const std::string& text, const char* color);

        // 节点信息输出
        void PrintNodeHeader(const std::string& type_name, const Location& loc);
        void PrintLocation(const Location& loc);
        void PrintSourceSnippet(const Location& loc);
        void PrintKeyValue(const std::string& key, const std::string& value, const Location& location, const char* value_color);
        void PrintKeyValue(const std::string& key, const std::string& value, const char* value_color = nullptr);
        void PrintKeyValue(const std::string& key, int value);
        void PrintKeyValue(const std::string& key, bool value);

        // 表达式和语句打印
        void PrintExpression(const Expression* expr, const std::string& label = "", bool is_last = false);
        void PrintStatement(const Statement* stmt, const std::string& label = "", bool is_last = false);
        void PrintSignature(const Signature& sig);
        void PrintParameter(const Parameter& param, bool is_last = false);
        void PrintLeftHandSide(const LeftHandSide& lhs, const std::string& label = "", bool is_last = false);

        // 枚举值打印
        void PrintOperator(BinaryOperator op);
        void PrintOperator(UnaryOperator op);
        void PrintOperator(AssignmentOperator op);
        void PrintLiteralKind(LiteralKind kind);
        void PrintAccessModifier(AccessModifier modifier);
        void PrintMethodModifier(MethodModifier modifier);
        void PrintReferenceModifier(ReferenceModifier modifier);
        void PrintConditionalCompilationType(ConditionalCompilationType type);
        void PrintError(const ParseError& error);

        // 工具函数
        std::string EscapeString(const std::string& str) const;
        std::string TruncateString(const std::string& str, size_t max_len) const;
        std::string GetSourceText(const Location& loc) const;
    };

    // 便捷函数
    std::string DebugString(const ASTNode* node, const PrintOptions& opts = PrintOptions::Default());
    std::string DebugString(const ParseResult& result, const PrintOptions& opts = PrintOptions::Default());

    void DebugPrint(const ASTNode* node, const PrintOptions& opts = PrintOptions::Default());
    void DebugPrint(const ParseResult& result, const PrintOptions& opts = PrintOptions::Default());

    // 带源码的打印
    void DebugPrint(const ASTNode* node, const std::string& source, const PrintOptions& opts = PrintOptions::Default());
    void DebugPrint(const ParseResult& result, const std::string& source, const PrintOptions& opts = PrintOptions::Default());
}
