#include <memory>
#include <spdlog/spdlog.h>
#include <vector>
#include "./event_bus.hpp"
#include "../document.hpp"
#include "../symbol.hpp"
#include "../parser.hpp"
#include "../../utils/args_parser.hpp"
#include "./registry.hpp"
#include "./bootstrap.hpp"

namespace lsp::service
{
    void RegisterAllServices(Registry& registry, scheduler::AsyncExecutor& async_executor)
    {
        spdlog::info("Registering LSP services...");

        auto& config = utils::ArgsParser::Instance().GetConfig();
        std::shared_ptr<EventBus> event_bus = std::make_shared<EventBus>();
        std::shared_ptr<Document> document = std::make_shared<Document>(event_bus);
        std::shared_ptr<Parser> parser = std::make_shared<Parser>(event_bus);
        std::shared_ptr<Symbol> symbol = std::make_shared<Symbol>(event_bus);

        registry.RegisterService(document);
        registry.RegisterService(parser);
        registry.RegisterService(symbol);

        // 异步加载全局符号
        std::vector<std::pair<std::string, std::string>> paths = {
            { "funcext", config.interpreter_path + "funcext" },
            { "data", config.interpreter_path + "data" }
        };

        for (const auto& [name, path] : paths)
        {
            std::string task_name = fmt::format("Load system {} symbols", name);
            async_executor.Submit(task_name, [symbol, path]() -> std::optional<std::string> {
                                    try
                                    {
                                        symbol->LoadSystemSymbols(path);
                                        return fmt::format("Loaded system {} symbols", path);
                                    }
                                    catch (const std::exception& e)
                                    {
                                        spdlog::error("Failed to load system {} symbols: {}", path, e.what());
                                        throw; // Request会处理异常
                                    } }, [path](const std::string& result) { spdlog::info("{}: {}", path, result); });
        }

        spdlog::info("Successfully registered {} LSP services", registry.ServiceCount());
    }
};
