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

namespace lsp::provider::text_document
{
    struct CompletionContext
    {
        protocol::DocumentUri uri;
        protocol::Position position;
        std::string prefix;
        std::string line_content;
        bool is_unit_context = false; // unit( 上下文
        bool is_class_context = false; // class( 上下文
        bool is_new_context = false; // new 上下文
        bool is_class_method_context = false; // class(xxx)
        std::string class_name;
    };

    // 临时设计
    struct CompletionInfo
    {
        protocol::string type;
        protocol::string class_name;
    };

    enum class CompletionSource
    {
        kEditing, // 当前编辑文档
        kWorkspace, // 工作区符号
        kSystem, // 系统库符号
        kKeyword // 关键字
    };

    struct SourcedCompletionItem
    {
        protocol::CompletionItem item;
        CompletionSource source;
    };

    namespace context_analyzer
    {
        CompletionContext Analyze(const protocol::CompletionParams& params, const std::optional<std::string>& document_content);

        bool IsUnitContext(const std::string& line);
        bool IsClassContext(const std::string& line);
        bool IsNewContext(const std::string& line);
        bool IsClassMethodContext(const std::string& line, std::string& class_name, std::string& method_prefix);
        std::string ExtractPrefix(size_t cursor_pos, size_t line_start, const std::string& content);
        std::string ExtractUnitPrefix(const std::string& line);
        std::string ExtractClassPrefix(const std::string& line);
        std::string ExtractNewPrefix(const std::string& line);
    }

    class Completion : public IRequestProvider
    {
    public:
        std::string GetMethod() const override;
        std::string GetProviderName() const override;
        std::string ProvideResponse(const protocol::RequestMessage& request, ExecutionContext& execution_context) override;

    private:
        protocol::CompletionList BuildCompletionList(const protocol::CompletionParams& params, ExecutionContext& execution_context);

        // 符号收集
        std::vector<SourcedCompletionItem> CollectKeywords(const std::string& prefix);
        std::vector<SourcedCompletionItem> CollectClassMethods(const CompletionContext& comp_context, const service::Symbol& symbol_service);
        std::vector<SourcedCompletionItem> CollectUnitNames(const CompletionContext& comp_context, const service::Symbol& symbol_service);
        std::vector<SourcedCompletionItem> CollectClassNames(const CompletionContext& comp_context, const service::Symbol& symbol_service, bool is_new_context = false);
        std::vector<SourcedCompletionItem> CollectEditingFunctions(const CompletionContext& comp_context, const service::Symbol& symbol_service);
        std::vector<SourcedCompletionItem> CollectWorkspaceFunctions(const CompletionContext& comp_context, const service::Symbol& symbol_service);
        std::vector<SourcedCompletionItem> CollectSystemFunctions(const CompletionContext& comp_context, const service::Symbol& symbol_service);

        // 过滤和排序
        std::vector<protocol::CompletionItem> FilterAndSort(const std::vector<SourcedCompletionItem>& items, const std::string& prefix);
        static int GetMatchScore(const std::string& label, const std::string& prefix);

        // 格式化辅助
        static protocol::CompletionItemKind ToCompletionItemKind(language::symbol::SymbolKind kind);
        // static std::string FormatSignature(const service::SymbolSignature& sig);
    };
}
