#pragma once
#include <string>
#include <optional>
#include "../base/interface.hpp"
#include "../../service/detail/symbol/types.hpp"

namespace lsp::provider::completion_item
{
    class Resolve : public IRequestProvider
    {
    public:
        Resolve() = default;

        std::string GetMethod() const override;
        std::string GetProviderName() const override;
        std::string ProvideResponse(const protocol::RequestMessage& request, ExecutionContext& execution_context) override;

    private:
        protocol::CompletionItem ResolveCompletionItem(const protocol::CompletionItem& item, ExecutionContext& execution_context);

        void ResolveKeyword(protocol::CompletionItem& item);
        void ResolveFunction(protocol::CompletionItem& item, ExecutionContext& execution_context);
        void ResolveClass(protocol::CompletionItem& item, ExecutionContext& execution_context);
        void ResolveClassMethod(protocol::CompletionItem& item, ExecutionContext& execution_context);
        void ResolveVariable(protocol::CompletionItem& item, ExecutionContext& execution_context);
        void ResolveUnit(protocol::CompletionItem& item, ExecutionContext& execution_context);

        // 辅助函数：查找符号
        struct SymbolLookupResult
        {
            std::optional<service::symbol::MemberSymbol> symbol;
            std::string source_file;
            std::string source_type; // "Workspace", "System"
        };

        SymbolLookupResult FindFunctionSymbol(const std::string& name, ExecutionContext& execution_context);
        SymbolLookupResult FindClassSymbol(const std::string& name, ExecutionContext& execution_context);
        SymbolLookupResult FindClassMethodSymbol(const std::string& class_name, const std::string& method_name, ExecutionContext& execution_context);
    };

    namespace documentation
    {
        protocol::MarkupContent BuildKeywordDocumentation(const std::string& description);
        protocol::MarkupContent BuildFunctionDocumentation(
            const service::symbol::MemberSymbol& symbol,
            const std::string& file_path,
            const std::string& source_type);
        protocol::MarkupContent BuildClassDocumentation(
            const std::string& class_name,
            const std::string& file_path,
            const std::string& source_type);
        protocol::MarkupContent BuildClassMethodDocumentation(
            const std::string& class_name,
            const service::symbol::MemberSymbol& symbol,
            const std::string& file_path,
            const std::string& source_type);
        std::string FormatFunctionMarkdown(const service::symbol::MemberSymbol& symbol);
        protocol::MarkupContent BuildUnitDocumentation(
            const std::string& unit_name,
            const std::string& file_path,
            const std::string& source_type);
    }

    namespace snippet
    {
        std::string BuildFunctionCallSnippet(const service::symbol::MemberSymbol& symbol);
        std::string BuildConstructorSnippet(const std::string& class_name, const service::symbol::MemberSymbol* constructor);
    }
}
