#include <spdlog/spdlog.h>
#include "./definition.hpp"
#include "../../protocol/transform/facade.hpp"
#include "../../service/document.hpp"

namespace lsp::provider::text_document
{
    std::string Definition::GetMethod() const
    {
        return "textDocument/definition";
    }

    std::string Definition::GetProviderName() const
    {
        return "TextDocumentDefinition";
    }

    std::string Definition::ProvideResponse(const protocol::RequestMessage& request, ExecutionContext& context)
    {
        spdlog::debug("TextDocumentDefinitionProvider: Providing response for method {}", request.method);

        if (!request.params.has_value())
        {
            spdlog::warn("{}: Missing params in request", GetProviderName());
            return BuildErrorResponseMessage(request, protocol::ErrorCodes::InvalidParams, "Missing params");
        }

        protocol::DefinitionParams params = transform::As<protocol::DefinitionParams>(request.params.value());

        auto location = BuildDefinitionResponse(params, context);

        protocol::ResponseMessage response;
        response.id = request.id;

        if (location.has_value())
        {
            response.result = transform::LSPAny(*location);
        }
        else
        {
            response.result = std::nullopt;
        }

        std::optional<std::string> json = transform::Serialize(response);
        if (!json.has_value())
            return BuildErrorResponseMessage(request, protocol::ErrorCodes::InternalError, "Failed to serialize response");
        return json.value();
    }

    std::optional<protocol::Location> Definition::BuildDefinitionResponse(const protocol::DefinitionParams& params, ExecutionContext& context)
    {
        spdlog::trace("{}: Processing definition request for URI='{}', Position=({}, {})", GetProviderName(), params.textDocument.uri, params.position.line, params.position.character);
        return std::nullopt;
    }
}
