// server/stardom/stardom-mcp.ts
/**
 * MCP Server — registers stardom_search and stardom_collaborate tools.
 *
 * Uses createSdkMcpServer + tool API for in-process MCP server.
 * Pattern follows server/web-access/mcp-server.ts.
 */
import { z } from 'zod';
import { createSdkMcpServer, tool } from '@anthropic-ai/claude-agent-sdk';
import type { McpSdkServerConfigWithInstance } from '@anthropic-ai/claude-agent-sdk';
import type { StardomMcpDeps } from './types.js';

type ToolResult = { content: Array<{ type: 'text'; text: string }>; isError?: boolean };

function textResult(text: string, isError = false): ToolResult {
  return { content: [{ type: 'text', text }], isError };
}

function errorResult(message: string): ToolResult {
  return textResult(message, true);
}

/**
 * 临时拦截 StardomClient.onMessage 回调，等待特定消息类型。
 * StardomClient 使用 onMessage 回调而非 EventEmitter，所以需要保存/恢复原始 handler。
 */
function waitForMessage(
  client: StardomMcpDeps['client'],
  type: string,
  timeoutMs: number,
): Promise<Record<string, unknown>> {
  return new Promise((resolve, reject) => {
    const originalHandler = client.onMessage;
    const timer = setTimeout(() => {
      client.onMessage = originalHandler;
      reject(new Error(`等待 ${type} 消息超时 (${timeoutMs}ms)`));
    }, timeoutMs);

    client.onMessage = (msg: { type: string; payload: Record<string, unknown> }) => {
      if (msg.type === type) {
        clearTimeout(timer);
        client.onMessage = originalHandler;
        resolve(msg.payload);
      } else {
        // 非目标消息，传递给原始 handler
        if (originalHandler) originalHandler(msg);
      }
    };
  });
}

export function createStardomMcpServer(deps: StardomMcpDeps): McpSdkServerConfigWithInstance {
  const searchTool = tool(
    'stardom_search',
    '搜索集市上其他 Agent 的能力。当你无法完成某个任务时（比如缺少某个项目的代码访问权限、不了解特定业务逻辑），'
      + '用此工具搜索能帮你的人。\n\n'
      + '能力查找顺序：先自己尝试 → sman capabilities list 查本地能力包 → stardom_search 搜索其他 Agent → sman capabilities search 搜索集市能力包\n\n'
      + '返回匹配的 Agent 列表（名称、能力、在线状态、声望、协作历史），'
      + '然后用 stardom_collaborate 发起协作。',
    {
      query: z.string().describe('搜索关键词，描述你需要的能力，如 "支付查询" 或 "风控规则"'),
    },
    async (args: any) => {
      try {
        const query = args.query as string;

        // 1. 查本地经验路由
        const localRoutes = deps.store.findLearnedRoutes(query);

        // 2. 查 pair history 用于排名
        const pairHistories = (() => {
          try {
            return deps.store.listPairHistories();
          } catch {
            return []; // 数据损坏时静默降级
          }
        })();

        // 3. 远程搜索
        const remoteMatches = await searchRemoteAgents(deps, query);

        // 4. 合并结果并按磨合程度排名
        const pairMap = new Map(pairHistories.map(p => [p.partnerId, p]));

        const localAgentIds = new Set(localRoutes.map(r => r.agentId));
        const filteredRemote = remoteMatches.filter(m => !localAgentIds.has(m.agentId));

        const allResults = [
          ...localRoutes.map(r => {
            const pair = pairMap.get(r.agentId);
            let badge = r.experience ? '有经验' : '历史协作';
            if (pair && pair.taskCount >= 3 && pair.avgRating >= 4) {
              badge = '老搭档';
            } else if (pair && pair.taskCount >= 1) {
              badge = '历史协作';
            }
            return {
              source: 'local' as const,
              agentId: r.agentId,
              name: r.agentName,
              capability: r.capability,
              badge,
              priority: badge === '老搭档' ? 0 : badge === '历史协作' ? 1 : badge === '有经验' ? 2 : 3,
            };
          }),
          ...filteredRemote.map(m => ({
            source: 'remote' as const,
            agentId: m.agentId,
            name: m.name,
            capability: '',
            badge: '',
            priority: 4,
          })),
        ];

        // 按优先级排序
        allResults.sort((a, b) => a.priority - b.priority);

        if (allResults.length === 0) {
          return textResult(`没有找到拥有 "${query}" 能力的 Agent。你可以尝试换个关键词搜索，或者稍后再试。`);
        }

        const lines = allResults.map((r, i) => {
          const local = r.source === 'local' ? ` [${r.badge || '历史协作'}]` : '';
          return `${i + 1}. ${r.name} (${r.agentId})${local}`;
        });

        return textResult(
          `找到 ${allResults.length} 个匹配的 Agent：\n${lines.join('\n')}\n\n`
          + `用 stardom_collaborate 向其中任何一个发起协作。`,
        );
      } catch (e: any) {
        return errorResult(`搜索失败: ${e.message}`);
      }
    },
  );

  const collaborateTool = tool(
    'stardom_collaborate',
    '向指定 Agent 发起协作请求。先用 stardom_search 找到合适的 Agent，然后用此工具请求对方协助。'
      + '对方接受后，你们可以实时对话解决问题。协作过程会在前端传送门页面实时显示。',
    {
      targetAgentId: z.string().describe('目标 Agent 的 ID（从 stardom_search 结果中获取）'),
      question: z.string().describe('你需要对方帮助解决的问题'),
    },
    async (args: any) => {
      try {
        const { targetAgentId, question } = args;

        // 发送 task.create 获取搜索结果（含 taskId）
        const searchPayload = await searchRemoteWithId(deps, question);
        const taskId = searchPayload.taskId as string;

        // 发送 task.offer 给目标 Agent
        deps.client.send({
          id: `mcp-offer-${Date.now()}`,
          type: 'task.offer',
          payload: { taskId, targetAgent: targetAgentId },
        });

        return textResult(
          `协作请求已发送！任务 ID: ${taskId}\n`
          + `正在等待 ${targetAgentId} 接受。对方接受后，你可以直接在这里继续对话。`,
        );
      } catch (e: any) {
        return errorResult(`发起协作失败: ${e.message}`);
      }
    },
  );

  return createSdkMcpServer({
    name: 'stardom',
    version: '1.0.0',
    tools: [searchTool, collaborateTool],
  });
}

// ── Helper：远程搜索（返回 matches 列表）──

async function searchRemoteAgents(
  deps: StardomMcpDeps,
  query: string,
): Promise<Array<{ agentId: string; name: string; repo: string }>> {
  deps.client.send({
    id: `mcp-search-${Date.now()}`,
    type: 'task.create',
    payload: { question: query, capabilityQuery: query },
  });

  try {
    const payload = await waitForMessage(deps.client, 'task.search_result', 5000);
    const matches = (payload as any).matches ?? [];
    return matches.map((m: any) => ({
      agentId: m.agentId,
      name: m.name,
      repo: m.repo,
    }));
  } catch {
    return []; // 搜索超时，返回空
  }
}

// ── Helper：远程搜索并返回含 taskId 的 payload ──

async function searchRemoteWithId(
  deps: StardomMcpDeps,
  query: string,
): Promise<Record<string, unknown>> {
  deps.client.send({
    id: `mcp-create-${Date.now()}`,
    type: 'task.create',
    payload: { question: query, capabilityQuery: query },
  });

  return waitForMessage(deps.client, 'task.search_result', 5000);
}
