using System.Text.Json;

namespace AxCopilot.Services.Agent;

/// <summary>
/// MCP 서버의 도구를 에이전트 도구로 래핑합니다.
/// 하나의 McpTool 인스턴스가 하나의 MCP 도구를 나타냅니다.
/// </summary>
public class McpTool : IAgentTool
{
    private readonly McpClientService _client;
    private readonly Models.McpToolDefinition _def;

    public McpTool(McpClientService client, Models.McpToolDefinition def)
    {
        _client = client;
        _def = def;
    }

    public string Name => $"mcp_{_def.ServerName}_{_def.Name}";
    public string Description => $"[MCP:{_def.ServerName}] {_def.Description}";

    public ToolParameterSchema Parameters
    {
        get
        {
            var schema = new ToolParameterSchema
            {
                Properties = new(),
                Required = new(),
            };
            foreach (var (name, param) in _def.Parameters)
            {
                schema.Properties[name] = new ToolProperty
                {
                    Type = param.Type,
                    Description = param.Description,
                };
                if (param.Required) schema.Required.Add(name);
            }
            return schema;
        }
    }

    public async Task<ToolResult> ExecuteAsync(
        JsonElement args, AgentContext context, CancellationToken ct = default)
    {
        try
        {
            if (!_client.IsConnected)
                return ToolResult.Fail($"MCP 서버 '{_def.ServerName}'에 연결되어 있지 않습니다.");

            var arguments = new Dictionary<string, object>();
            if (args.ValueKind == JsonValueKind.Object)
            {
                foreach (var prop in args.EnumerateObject())
                {
                    arguments[prop.Name] = prop.Value.ValueKind switch
                    {
                        JsonValueKind.String => prop.Value.GetString()!,
                        JsonValueKind.Number => prop.Value.GetDouble(),
                        JsonValueKind.True => true,
                        JsonValueKind.False => false,
                        _ => prop.Value.ToString(),
                    };
                }
            }

            var result = await _client.CallToolAsync(_def.Name, arguments, ct);
            return ToolResult.Ok(result);
        }
        catch (Exception ex)
        {
            return ToolResult.Fail($"MCP 도구 실행 실패: {ex.Message}");
        }
    }
}
