using ColaFlow.Modules.Mcp.Contracts.JsonRpc;
using Microsoft.Extensions.Logging;

namespace ColaFlow.Modules.Mcp.Application.Handlers;

/// <summary>
/// Main MCP protocol handler that routes requests to method handlers
/// </summary>
public class McpProtocolHandler : IMcpProtocolHandler
{
    private readonly ILogger<McpProtocolHandler> _logger;
    private readonly Dictionary<string, IMcpMethodHandler> _methodHandlers;

    public McpProtocolHandler(
        ILogger<McpProtocolHandler> logger,
        IEnumerable<IMcpMethodHandler> methodHandlers)
    {
        _logger = logger;
        _methodHandlers = methodHandlers.ToDictionary(h => h.MethodName, h => h);

        _logger.LogInformation("MCP Protocol Handler initialized with {Count} method handlers: {Methods}",
            _methodHandlers.Count,
            string.Join(", ", _methodHandlers.Keys));
    }

    public async Task<JsonRpcResponse> HandleRequestAsync(
        JsonRpcRequest request,
        CancellationToken cancellationToken)
    {
        try
        {
            // Validate request structure
            if (!request.IsValid(out var errorMessage))
            {
                _logger.LogWarning("Invalid JSON-RPC request: {ErrorMessage}", errorMessage);
                return JsonRpcResponse.InvalidRequest(errorMessage, request.Id);
            }

            _logger.LogDebug("Processing MCP request: method={Method}, id={Id}, isNotification={IsNotification}",
                request.Method, request.Id, request.IsNotification);

            // Find method handler
            if (!_methodHandlers.TryGetValue(request.Method, out var handler))
            {
                _logger.LogWarning("Method not found: {Method}", request.Method);
                return JsonRpcResponse.MethodNotFound(request.Method, request.Id);
            }

            // Execute method handler
            var result = await handler.HandleAsync(request.Params, cancellationToken);

            _logger.LogDebug("MCP request processed successfully: method={Method}, id={Id}",
                request.Method, request.Id);

            // Return success response
            return JsonRpcResponse.Success(result, request.Id);
        }
        catch (ArgumentException ex)
        {
            _logger.LogWarning(ex, "Invalid parameters for method {Method}", request.Method);
            return JsonRpcResponse.InvalidParams(ex.Message, request.Id);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Internal error processing MCP request: method={Method}, id={Id}",
                request.Method, request.Id);
            return JsonRpcResponse.InternalError(ex.Message, request.Id);
        }
    }
}
