import { Injectable, ServiceUnavailableException } from '@nestjs/common';
import { createLogger } from '@core/observability/logging/config/winston.config';
import type { AgentTool, ToolDescriptor, ToolInvocation, ToolResult } from './tool.types';

const logger = createLogger('McpClient');

/**
 * PR5 MCP Client 骨架。
 *
 * **状态**：接口齐全；**实际跑通需要 MCP Server 实例**（stdio 或 SSE），不在本 session 范围。
 *
 * 真实实现路径：
 *   1. spawn 子进程跑 MCP server CLI（或连远程 SSE endpoint）
 *   2. 走 JSON-RPC 2.0 握手 → tools/list 拿 server 提供的 tool 列表
 *   3. 把 server tool 包成 AgentTool 注入到 ToolRegistry
 *   4. invoke 时转发 tools/call 给 server，等结果回来包成 ToolResult
 *
 * 当前 controller / registry 已能识别 MCP 来源工具——只是 spawn / 协议握手没接入。
 * 落地需要：选定 MCP 客户端库（@modelcontextprotocol/sdk）+ 进程隔离 + 错误处理 + 超时。
 * Phase 1 GA 不强求；Phase 2 desktop 上 client tool 时一起落（PRD §1.7）。
 */
@Injectable()
export class McpClient {
  /** 已连接的 MCP server connection map（实现接入后填充）*/
  private readonly connections = new Map<string, McpServerConnection>();

  isEnabled(): boolean {
    return process.env.FFAI_MCP_ENABLED === 'true';
  }

  async connect(_serverId: string, _spec: McpServerSpec): Promise<McpServerConnection> {
    if (!this.isEnabled()) {
      throw new ServiceUnavailableException(
        'MCP client disabled — set FFAI_MCP_ENABLED=true to enable',
      );
    }
    // TODO: spawn child_process / connect SSE; perform JSON-RPC initialize handshake
    throw new Error('not yet implemented — needs @modelcontextprotocol/sdk + spec resolution');
  }

  async listAvailableTools(): Promise<ToolDescriptor[]> {
    if (!this.isEnabled()) return [];
    // TODO: aggregate across connections
    return [];
  }

  buildToolAdapter(_serverId: string, _serverToolName: string): AgentTool {
    const self = this;
    return {
      descriptor: {
        name: `mcp:${_serverId}:${_serverToolName}`,
        description: `MCP tool from ${_serverId}`,
        inputSchema: {},
      },
      async invoke(_inv: ToolInvocation): Promise<ToolResult> {
        if (!self.isEnabled()) {
          return { ok: false, errorMessage: 'MCP disabled' };
        }
        return { ok: false, errorMessage: 'MCP invocation not yet implemented' };
      },
    };
  }
}

export interface McpServerSpec {
  /** 启动方式 */
  transport: 'stdio' | 'sse';
  /** stdio 时 = 命令；sse 时 = URL */
  endpoint: string;
  /** stdio 子进程参数（可选）*/
  args?: string[];
  /** 环境变量 */
  env?: Record<string, string>;
}

export interface McpServerConnection {
  readonly serverId: string;
  /** 关闭连接（清理子进程 / 关 SSE） */
  close(): Promise<void>;
}

logger.log('MCP Client skeleton loaded (set FFAI_MCP_ENABLED=true + impl handshake to use)');
