#pragma once

#include <iostream>
#include <string>
#include "../../src/language/symbol/table.hpp"

namespace lsp::language::symbol::debug
{
    // ==================== 颜色和样式 ====================

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

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

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

    // ==================== 打印选项 ====================

    struct PrintOptions
    {
        bool use_color = true; // 使用颜色
        bool show_location = true; // 显示位置信息
        bool show_details = true; // 显示详细信息
        bool show_children = true; // 显示子符号
        bool show_references = false; // 显示引用列表
        bool compact_mode = false; // 紧凑模式
        int indent_size = 2; // 缩进大小
        int max_depth = -1; // 最大深度 (-1 = 无限制)

        static PrintOptions Default();
        static PrintOptions Compact();
        static PrintOptions Verbose();
        static PrintOptions NoColor();
    };

    // ==================== 统计信息 ====================

    struct Statistics
    {
        size_t total_symbols = 0;
        size_t total_scopes = 0;
        size_t total_references = 0;

        std::unordered_map<SymbolKind, size_t> symbol_counts;
        std::unordered_map<ScopeKind, size_t> scope_counts;

        size_t symbols_with_refs = 0;
        size_t max_references = 0;
        SymbolId most_referenced = kInvalidSymbolId;

        void Compute(const SymbolTable& table);
        void Print(std::ostream& os, bool use_color = true) const;
    };

    // ==================== 核心打印器 ====================

    class DebugPrinter
    {
    public:
        explicit DebugPrinter(const SymbolTable& table, const PrintOptions& options = PrintOptions::Default());

        // ===== 顶层打印接口 =====
        void PrintAll(std::ostream& os = std::cout);
        void PrintOverview(std::ostream& os = std::cout);
        void PrintStatistics(std::ostream& os = std::cout);

        // ===== 符号打印 =====
        void PrintSymbol(SymbolId id, std::ostream& os = std::cout, int depth = 0);
        void PrintSymbolTree(SymbolId id, std::ostream& os = std::cout, int depth = 0);
        void PrintSymbolList(std::ostream& os = std::cout);
        void PrintSymbolsByKind(SymbolKind kind, std::ostream& os = std::cout);

        // ===== 作用域打印 =====
        void PrintScope(ScopeId id, std::ostream& os = std::cout, int depth = 0);
        void PrintScopeTree(ScopeId id, std::ostream& os = std::cout, int depth = 0);
        void PrintScopeHierarchy(std::ostream& os = std::cout);

        // ===== 关系打印 =====
        void PrintReferences(SymbolId id, std::ostream& os = std::cout);
        void PrintInheritance(SymbolId class_id, std::ostream& os = std::cout);
        void PrintCallGraph(SymbolId function_id, std::ostream& os = std::cout);
        void PrintAllReferences(std::ostream& os = std::cout);
        void PrintAllInheritance(std::ostream& os = std::cout);
        void PrintAllCalls(std::ostream& os = std::cout);

        // ===== 搜索和查询 =====
        void FindAndPrint(const std::string& name, std::ostream& os = std::cout);
        void FindAtLocation(const ast::Location& loc, std::ostream& os = std::cout);

        // ===== 选项管理 =====
        void SetOptions(const PrintOptions& options) { options_ = options; }
        const PrintOptions& GetOptions() const { return options_; }

    private:
        const SymbolTable& table_;
        PrintOptions options_;
        Statistics stats_;

        // ===== 辅助方法 =====
        std::string Indent(int depth) const;
        std::string ColorizeSymbolKind(SymbolKind kind) const;
        std::string ColorizeSymbolName(const std::string& name, SymbolKind kind) const;
        std::string FormatLocation(const ast::Location& loc) const;
        std::string FormatSymbolKind(SymbolKind kind) const;
        std::string FormatScopeKind(ScopeKind kind) const;
        std::string SymbolIcon(SymbolKind kind) const;

        void PrintSeparator(std::ostream& os, char ch = '=', int width = 80) const;
        void PrintHeader(const std::string& title, std::ostream& os) const;
        void PrintSubHeader(const std::string& title, std::ostream& os) const;

        std::string Color(const char* color_code) const;
        std::string Bold(const std::string& text) const;
        std::string Dim(const std::string& text) const;
    };

    // ==================== 快速打印函数 ====================

    // 打印所有内容（带统计）
    void Print(const SymbolTable& table, std::ostream& os = std::cout);

    // 打印概览
    void PrintOverview(const SymbolTable& table, std::ostream& os = std::cout);

    // 打印统计信息
    void PrintStats(const SymbolTable& table, std::ostream& os = std::cout);

    // 打印符号树
    void PrintSymbolTree(const SymbolTable& table, std::ostream& os = std::cout);

    // 打印作用域树
    void PrintScopeTree(const SymbolTable& table, std::ostream& os = std::cout);

    // 搜索并打印
    void Find(const SymbolTable& table, const std::string& name, std::ostream& os = std::cout);

    // 紧凑打印
    void PrintCompact(const SymbolTable& table, std::ostream& os = std::cout);

    // 详细打印
    void PrintVerbose(const SymbolTable& table, std::ostream& os = std::cout);

} // namespace lsp::language::symbol::debug
