#ifndef SYMBOL_TABLE_H
#define SYMBOL_TABLE_H

#include <any>
#include <string>
#include <vector>
#include <unordered_map>
#include <stack>
#include <utility>

// 核心类型枚举
enum class SymbolType {
    TYPE_UNKNOWN,   // 未知类型
    TYPE_INT,       // 整型
    TYPE_FLOAT,     // 浮点型
    TYPE_VOID,      // 空类型
    TYPE_ARRAY,     // 数组类型
    TYPE_FUNCTION   // 函数类型
};

// 获取类型名称字符串
inline const char* SymbolTypeToString(SymbolType type) {
    switch (type) {
        case SymbolType::TYPE_INT: return "int";
        case SymbolType::TYPE_FLOAT: return "float";
        case SymbolType::TYPE_VOID: return "void";
        case SymbolType::TYPE_ARRAY: return "array";
        case SymbolType::TYPE_FUNCTION: return "function";
        default: return "unknown";
    }
}

// 变量信息结构体
struct VarInfo {
    SymbolType type = SymbolType::TYPE_UNKNOWN;
    bool is_const = false;
    std::any const_val;
    std::vector<int> array_dims;  // 数组维度，空表示非数组
    void* decl_ctx = nullptr;     // 关联的语法节点
    
    // 检查是否为数组类型
    bool IsArray() const { return !array_dims.empty(); }
    
    // 获取数组元素总数
    int GetArrayElementCount() const {
        int count = 1;
        for (int dim : array_dims) {
            count *= dim;
        }
        return count;
    }
};

// 函数信息结构体
struct FuncInfo {
    SymbolType ret_type = SymbolType::TYPE_UNKNOWN;
    std::string name;
    std::vector<SymbolType> param_types;  // 参数类型列表
    void* decl_ctx = nullptr;             // 关联的语法节点
    
    // 检查参数匹配
    bool CheckParams(const std::vector<SymbolType>& actual_params) const {
        if (actual_params.size() != param_types.size()) {
            return false;
        }
        
        for (size_t i = 0; i < param_types.size(); ++i) {
            if (param_types[i] != actual_params[i] && 
                param_types[i] != SymbolType::TYPE_UNKNOWN && 
                actual_params[i] != SymbolType::TYPE_UNKNOWN) {
                return false;
            }
        }
        return true;
    }
};

// 作用域条目结构体
struct ScopeEntry {
    // 变量符号表：符号名 -> (符号信息, 声明节点)
    std::unordered_map<std::string, std::pair<VarInfo, void*>> var_symbols;
    
    // 函数符号表：符号名 -> (函数信息, 声明节点)
    std::unordered_map<std::string, std::pair<FuncInfo, void*>> func_symbols;
    
    // 清空作用域
    void Clear() {
        var_symbols.clear();
        func_symbols.clear();
    }
};

// 符号表核心类
class SymbolTable {
public:
    // ========== 作用域管理 ==========
    
    // 进入新作用域
    void EnterScope();
    
    // 离开当前作用域
    void LeaveScope();
    
    // 获取当前作用域深度
    size_t GetScopeDepth() const { return scopes_.size(); }
    
    // 检查作用域栈是否为空
    bool IsEmpty() const { return scopes_.empty(); }
    
    // ========== 变量符号管理 ==========
    
    // 检查当前作用域是否包含指定变量
    bool CurrentScopeHasVar(const std::string& name) const;
    
    // 绑定变量到当前作用域
    void BindVar(const std::string& name, const VarInfo& info, void* decl_ctx);
    
    // 查找变量（从当前作用域向上遍历）
    bool LookupVar(const std::string& name, VarInfo& out_info, void*& out_decl_ctx) const;
    
    // 快速查找变量（不获取详细信息）
    bool HasVar(const std::string& name) const {
        VarInfo info;
        void* ctx;
        return LookupVar(name, info, ctx);
    }
    
    // ========== 函数符号管理 ==========
    
    // 检查当前作用域是否包含指定函数
    bool CurrentScopeHasFunc(const std::string& name) const;
    
    // 绑定函数到当前作用域
    void BindFunc(const std::string& name, const FuncInfo& info, void* decl_ctx);
    
    // 查找函数（从当前作用域向上遍历）
    bool LookupFunc(const std::string& name, FuncInfo& out_info, void*& out_decl_ctx) const;
    
    // 快速查找函数（不获取详细信息）
    bool HasFunc(const std::string& name) const {
        FuncInfo info;
        void* ctx;
        return LookupFunc(name, info, ctx);
    }
    
    // ========== 循环状态管理 ==========
    
    // 进入循环
    void EnterLoop();
    
    // 离开循环
    void ExitLoop();
    
    // 检查是否在循环内
    bool InLoop() const;
    
    // 获取循环嵌套深度
    int GetLoopDepth() const { return loop_depth_; }
    
    // ========== 辅助功能 ==========
    
    // 清空所有作用域和状态
    void Clear();
    
    // 获取当前作用域中所有变量名
    std::vector<std::string> GetCurrentScopeVarNames() const;
    
    // 获取当前作用域中所有函数名
    std::vector<std::string> GetCurrentScopeFuncNames() const;
    
    // 调试：打印符号表内容
    void Dump() const;

private:
    // 作用域栈
    std::stack<ScopeEntry> scopes_;
    
    // 循环嵌套深度
    int loop_depth_ = 0;
};

// 类型兼容性检查函数
inline bool IsTypeCompatible(SymbolType expected, SymbolType actual) {
    if (expected == SymbolType::TYPE_UNKNOWN || actual == SymbolType::TYPE_UNKNOWN) {
        return true;  // 未知类型视为兼容
    }
    
    // 基本类型兼容规则
    if (expected == actual) {
        return true;
    }
    
    // int 可以隐式转换为 float
    if (expected == SymbolType::TYPE_FLOAT && actual == SymbolType::TYPE_INT) {
        return true;
    }
    
    return false;
}

#endif // SYMBOL_TABLE_H