/**
 * MCP 工具适配器
 * 将 MCP 工具转换为内部工具格式
 */

import type { ToolParameter, ToolResult } from '../types/index.js';
import type { ToolWithMetadata, ToolCategory } from '../tools/types.js';
import type { MCPTool, MCPToolCallResult, MCPContent } from './types.js';
import type { MCPManager } from './manager.js';

/**
 * 将 JSON Schema 类型转换为内部参数类型
 */
function convertJsonSchemaType(
  schemaType: string | string[] | undefined
): 'string' | 'number' | 'boolean' | 'object' | 'array' {
  if (Array.isArray(schemaType)) {
    // 取第一个非 null 类型
    const type = schemaType.find((t) => t !== 'null');
    return convertJsonSchemaType(type);
  }

  switch (schemaType) {
    case 'string':
      return 'string';
    case 'number':
    case 'integer':
      return 'number';
    case 'boolean':
      return 'boolean';
    case 'array':
      return 'array';
    case 'object':
    default:
      return 'object';
  }
}

/**
 * 将 JSON Schema 转换为内部参数定义
 */
function convertInputSchema(
  schema: MCPTool['inputSchema']
): Record<string, ToolParameter> {
  const parameters: Record<string, ToolParameter> = {};

  if (!schema || typeof schema !== 'object') {
    return parameters;
  }

  const properties = schema.properties as Record<string, {
    type?: string | string[];
    description?: string;
  }> | undefined;

  const required = (schema.required as string[]) || [];

  if (properties) {
    for (const [name, prop] of Object.entries(properties)) {
      parameters[name] = {
        type: convertJsonSchemaType(prop.type),
        description: prop.description || '',
        required: required.includes(name),
      };
    }
  }

  return parameters;
}

/**
 * 将 MCP 内容转换为字符串输出
 */
function contentToString(content: MCPContent[]): string {
  const parts: string[] = [];

  for (const item of content) {
    switch (item.type) {
      case 'text':
        parts.push(item.text);
        break;
      case 'image':
        parts.push(`[Image: ${item.mimeType}]`);
        break;
      case 'resource':
        if (item.resource.text) {
          parts.push(item.resource.text);
        } else {
          parts.push(`[Resource: ${item.resource.uri}]`);
        }
        break;
    }
  }

  return parts.join('\n');
}

/**
 * 将 MCP 调用结果转换为内部 ToolResult
 */
function convertToolResult(result: MCPToolCallResult): ToolResult {
  const output = contentToString(result.content);

  if (result.isError || !result.success) {
    return {
      success: false,
      output: '',
      error: output || 'Tool execution failed',
    };
  }

  return {
    success: true,
    output,
  };
}

/**
 * MCP 工具适配器类
 */
export class MCPToolAdapter {
  constructor(private manager: MCPManager) {}

  /**
   * 将 MCP 工具适配为内部工具格式
   */
  adaptToInternalTool(mcpTool: MCPTool): ToolWithMetadata {
    const parameters = convertInputSchema(mcpTool.inputSchema);

    return {
      name: mcpTool.name,
      description: mcpTool.description || `MCP tool: ${mcpTool.originalName}`,
      parameters,
      execute: async (params: Record<string, unknown>): Promise<ToolResult> => {
        const result = await this.manager.callTool(mcpTool.name, params);
        return convertToolResult(result);
      },
      metadata: {
        name: mcpTool.name,
        category: 'agent' as ToolCategory, // MCP 工具归类为 agent
        description: mcpTool.description || `MCP tool from ${mcpTool.server}`,
        keywords: [
          'mcp',
          mcpTool.server,
          mcpTool.originalName,
          ...mcpTool.originalName.split(/[_-]/),
        ],
        deferLoading: false, // MCP 工具不延迟加载
      },
    };
  }

  /**
   * 批量适配工具
   */
  adaptTools(mcpTools: MCPTool[]): ToolWithMetadata[] {
    return mcpTools.map((tool) => this.adaptToInternalTool(tool));
  }
}

/**
 * 创建 MCP 工具适配器
 */
export function createMCPToolAdapter(manager: MCPManager): MCPToolAdapter {
  return new MCPToolAdapter(manager);
}
