#pragma once

#include "./types.hpp"
#include "./deserializer.hpp"
#include <functional>
#include <unordered_map>

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

namespace lsp::language::ast::detail
{
    // ===== 统一的解析上下文 =====

    class ParseContext
    {
    public:
        ParseContext(const std::string& source, std::vector<ParseError>& errors) :
            source_(source), errors_(errors) {}

        const std::string& Source() const { return source_; }

        std::vector<ParseError>& Errors() { return errors_; }
        const std::vector<ParseError>& Errors() const { return errors_; }

        void RecordError(const Location& loc, const std::string& node_type, const std::string& message, ErrorSeverity severity = ErrorSeverity::Error)
        {
            errors_.push_back(ParseError{ loc, node_type, message, severity });
        }

        void RecordMissing(const Location& loc, const std::string& node_type)
        {
            RecordError(loc, node_type, "Syntax error: missing " + node_type);
        }

        void RecordUnexpected(const Location& loc, const std::string& node_type, const std::string& context = "")
        {
            std::string msg = "Syntax error: unexpected token";
            if (!context.empty())
                msg += " in " + context;
            RecordError(loc, node_type, msg);
        }

        void RecordWarning(const Location& loc, const std::string& node_type, const std::string& message)
        {
            RecordError(loc, node_type, message, ErrorSeverity::Warning);
        }

        template<typename T = Expression>
        std::unique_ptr<T> ReportNullNode(const Location& loc, const std::string& expected_type)
        {
            RecordMissing(loc, expected_type);
            return nullptr;
        }

        template<typename T = Expression>
        std::unique_ptr<T> ReportParseFailed(const Location& loc, const std::string& node_type, const std::string& reason = "")
        {
            std::string msg = "Failed to parse " + node_type;
            if (!reason.empty())
                msg += ": " + reason;
            RecordError(loc, node_type, msg);
            return nullptr;
        }

    private:
        const std::string& source_;
        std::vector<ParseError>& errors_;
    };

    // ===== 类成员解析结果 =====

    struct ClassMemberParseResult
    {
        std::unique_ptr<ClassMember> member;
        std::optional<AccessModifier> access_modifier;
        std::optional<ReferenceModifier> reference_modifier;
    };

    // ===== 语句解析器注册表 =====

    class StatementParserRegistry
    {
    public:
        using ParserFunc = std::function<StatementPtr(TSNode, ParseContext&)>;

        static StatementParserRegistry& Instance()
        {
            static StatementParserRegistry instance;
            return instance;
        }

        void Register(const std::string& type, ParserFunc parser)
        {
            parsers_[type] = parser;
        }

        ParserFunc Get(const std::string& type) const
        {
            auto it = parsers_.find(type);
            return it != parsers_.end() ? it->second : nullptr;
        }

    private:
        StatementParserRegistry() = default;
        StatementParserRegistry(const StatementParserRegistry&) = delete;
        StatementParserRegistry& operator=(const StatementParserRegistry&) = delete;

    private:
        std::unordered_map<std::string, ParserFunc> parsers_;
    };

    // ===== 初始化 =====
    void RegisterStatementParsers();

    // ===== 操作符映射 =====
    BinaryOperator ParseBinaryOperator(const std::string& op_text);
    UnaryOperator ParseUnaryOperator(const std::string& op_text);
    AssignmentOperator ParseAssignmentOperator(const std::string& op_text);

    // ===== 基础辅助函数 =====
    TSNode FindChildByType(TSNode parent, const std::string& type);
    bool IsSyntaxErrorNode(TSNode node);
    std::vector<ParseError> CollectSyntaxErrors(TSNode node, std::string_view source);

    // 访问修饰符和方法修饰符解析
    AccessModifier ParseAccessModifier(TSNode node, ParseContext& ctx);
    MethodModifier ParseMethodModifier(TSNode node, ParseContext& ctx);
    ReferenceModifier ParseReferenceModifier(TSNode node, ParseContext& ctx);

    // 方法和属性声明解析
    std::unique_ptr<MethodDeclaration> ParseMethodDeclaration(TSNode node, ParseContext& ctx);
    std::unique_ptr<PropertyDeclaration> ParsePropertyDeclaration(TSNode node, ParseContext& ctx);

    // 类成员解析
    std::vector<ClassMemberParseResult> ParseClassMember(TSNode node, ParseContext& ctx, AccessModifier current_access, ReferenceModifier current_reference);

    // ===== 通用解析函数 =====
    Signature ParseSignature(TSNode node, ParseContext& ctx);
    std::vector<Parameter> ParseParameters(TSNode params_node, ParseContext& ctx);

    // ===== 表达式解析 =====
    ExpressionPtr ParseExpression(TSNode node, ParseContext& ctx);
    ExpressionPtr ParsePrimaryExpression(TSNode node, ParseContext& ctx);
    ExpressionPtr ParseBinaryExpression(TSNode node, ParseContext& ctx);
    ExpressionPtr ParseUnaryExpression(TSNode node, ParseContext& ctx);
    ExpressionPtr ParseCallExpression(TSNode node, ParseContext& ctx);
    ExpressionPtr ParseAttributeExpression(TSNode node, ParseContext& ctx);
    ExpressionPtr ParseSubscriptExpression(TSNode node, ParseContext& ctx);
    ExpressionPtr ParseArrayExpression(TSNode node, ParseContext& ctx);
    ExpressionPtr ParseTernaryExpression(TSNode node, ParseContext& ctx);
    ExpressionPtr ParseAssignmentExpression(TSNode node, ParseContext& ctx);
    ExpressionPtr ParseAnonymousFunctionExpression(TSNode node, ParseContext& ctx);
    ExpressionPtr ParseTSSQLExpression(TSNode node, ParseContext& ctx);
    ExpressionPtr ParseEchoExpression(TSNode node, ParseContext& ctx);
    ExpressionPtr ParseRaiseExpression(TSNode node, ParseContext& ctx);
    ExpressionPtr ParseNewExpression(TSNode node, ParseContext& ctx);
    ExpressionPtr ParseInheritedExpression(TSNode node, ParseContext& ctx);

    // ===== 左值解析 =====
    LeftHandSide ParseLeftHandSide(TSNode node, ParseContext& ctx);
    std::unique_ptr<UnpackPattern> ParseUnpackPattern(TSNode node, ParseContext& ctx);

    // ===== 语句解析 =====
    StatementPtr ParseUnitDefinition(TSNode node, ParseContext& ctx);
    StatementPtr ParseStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseSingleSuite(TSNode node, ParseContext& ctx);
    StatementPtr ParseBlockSuite(TSNode node, ParseContext& ctx);
    StatementPtr ParseExpressionStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseAssignmentStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseVarStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseStaticStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseGlobalStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseConstStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseIfStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseForInStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseForToStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseWhileStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseRepeatStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseCaseStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseTryStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseBreakStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseContinueStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseReturnStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseUsesStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseInheritedStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseFunctionDefinition(TSNode node, ParseContext& ctx);
    StatementPtr ParseFunctionDeclaration(TSNode node, ParseContext& ctx);
    StatementPtr ParseClassDefinition(TSNode node, ParseContext& ctx);
    StatementPtr ParseExternalMethodStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseMatrixIterationStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseCompilerDirectiveStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseConditionalBlockStatement(TSNode node, ParseContext& ctx);
    StatementPtr ParseConditionalDirectiveStatement(TSNode node, ParseContext& ctx);

    // ===== TSLX 模板解析 =====
    StatementPtr ParseTSLXOpenTag(TSNode node, ParseContext& ctx);
    StatementPtr ParseTSLXCloseTag(TSNode node, ParseContext& ctx);
    StatementPtr ParseTSLXOutputTag(TSNode node, ParseContext& ctx);
    StatementPtr ParseTSLXExpressionTag(TSNode node, ParseContext& ctx);
    StatementPtr ParseHTMLSelfClosingTag(TSNode node, ParseContext& ctx);
    StatementPtr ParseHTMLPairedTag(TSNode node, ParseContext& ctx);
    StatementPtr ParseHTMLComment(TSNode node, ParseContext& ctx);

    // ===== 通用声明解析模板 =====
    template<typename DeclType, typename StmtType>
    StatementPtr ParseDeclarationStatement(TSNode node, ParseContext& ctx, NodeKind decl_kind, NodeKind stmt_kind, const std::string& keyword);
}
