#pragma once

#include "./store.hpp"
#include "./scope.hpp"
#include "./location_index.hpp"
#include "./relations.hpp"

namespace lsp::language::symbol
{
    class Builder;

    // 统一的符号表接口
    class SymbolTable
    {
    public:
        SymbolTable();

        // 构建符号表(完整构建)
        void Build(ast::ASTNode& root);

        // 清空所有数据
        void Clear();

        // ===== 第一层: 定义访问 =====
        const SymbolDefinition* GetDefinition(SymbolId id) const;
        std::vector<const SymbolDefinition*> GetAllDefinitions() const;
        std::vector<const SymbolDefinition*> FindDefinitionsByName(const std::string& name) const;

        // ===== 第二层: 作用域和位置查询 =====
        // 名称查找
        std::optional<SymbolId> FindSymbol(const std::string& name, ScopeId scope_id) const;
        std::vector<SymbolId> FindSymbolsByName(const std::string& name) const;

        // 位置查找
        std::optional<SymbolId> FindSymbolAt(const ast::Location& location) const;
        std::optional<ScopeId> FindScopeAt(const ast::Location& location) const;
        std::optional<SymbolId> FindReferenceAt(const ast::Location& location) const;

        // 作用域查询
        std::vector<SymbolId> GetChildren(SymbolId symbol_id) const;
        ScopeId GetGlobalScope() const;

        // ===== 第三层: 关系访问 =====
        // 返回引用避免拷贝，使用指针表示可能为空
        const std::vector<Reference>* GetReferences(SymbolId symbol_id) const;
        std::optional<ast::Location> GetDefinitionLocation(SymbolId symbol_id) const;
        const std::vector<SymbolId>* GetBaseClasses(SymbolId class_id) const;
        const std::vector<SymbolId>* GetDerivedClasses(SymbolId class_id) const;
        const std::vector<CallRelation>* GetCallers(SymbolId function_id) const;
        const std::vector<CallRelation>* GetCallees(SymbolId function_id) const;

        // ===== Unit 导入管理 =====
        // 添加单元导入
        void AddUnitImport(const std::string& unit_name, const ast::Location& location);

        // 获取所有导入的单元
        const std::vector<UnitImport>& GetUnitImports() const;

        // 查找特定单元的导入位置（用于跳转到定义）
        std::optional<ast::Location> FindImportLocation(const std::string& unit_name) const;

        // 检查是否导入了某个单元
        bool HasImport(const std::string& unit_name) const;

        // ===== LSP 便捷接口 =====
        // 获取文档符号(用于 textDocument/documentSymbol)
        std::vector<const SymbolDefinition*> GetDocumentSymbols() const;

        // 获取工作区符号(用于 workspace/symbol)
        std::vector<const SymbolDefinition*> GetWorkspaceSymbols(const std::string& query = "") const;

        // ===== Builder 专用内部接口 =====
        // 统一的符号创建接口，自动处理所有索引更新
        SymbolId CreateSymbol(
            const std::string& name,
            SymbolKind kind,
            const ast::Location& location,
            ScopeId scope_id,
            std::optional<SymbolId> parent_id = std::nullopt,
            const std::optional<std::string>& type_hint = std::nullopt,
            bool is_class_method = false);

        // 创建作用域（可以选择关联符号）
        ScopeId CreateScope(
            ScopeKind kind,
            const ast::Location& range,
            std::optional<ScopeId> parent_scope_id = std::nullopt,
            std::optional<SymbolId> associated_symbol_id = std::nullopt);

        // 添加引用
        void AddReference(SymbolId symbol_id, const ast::Location& location, bool is_write = false);

        // 获取内部组件的访问权限(供 Builder 使用)
        SymbolDefinitionStore& GetDefinitionStore() { return definition_store_; }
        ScopeManager& GetScopeManager() { return scope_manager_; }
        LocationIndex& GetLocationIndex() { return location_index_; }
        ReferenceGraph& GetReferenceGraph() { return reference_graph_; }
        InheritanceGraph& GetInheritanceGraph() { return inheritance_graph_; }
        CallGraph& GetCallGraph() { return call_graph_; }

        const SymbolDefinitionStore& GetDefinitionStore() const { return definition_store_; }
        const ScopeManager& GetScopeManager() const { return scope_manager_; }
        const LocationIndex& GetLocationIndex() const { return location_index_; }
        const ReferenceGraph& GetReferenceGraph() const { return reference_graph_; }
        const InheritanceGraph& GetInheritanceGraph() const { return inheritance_graph_; }
        const CallGraph& GetCallGraph() const { return call_graph_; }

    private:
        // 第一层
        SymbolDefinitionStore definition_store_;

        // 第二层
        ScopeManager scope_manager_;
        LocationIndex location_index_;

        // 第三层
        ReferenceGraph reference_graph_;
        InheritanceGraph inheritance_graph_;
        CallGraph call_graph_;

        // Unit 导入
        std::vector<UnitImport> unit_imports_;
        // 快速查找: unit_name -> index in unit_imports_
        std::unordered_map<std::string, size_t, utils::IHasher, utils::IEqualTo> import_index_;
    };

}
