/**
 * 内置工具：分享项目模板
 *
 * AI 调用 Bash(__share_project_template__ '<json>') 命令，
 * 由 PreToolUse hook 拦截 → 通过 WebSocket 打开前端弹窗 → 等待用户操作 → 返回结果。
 *
 * 飞书端不支持此工具（检测 mutableWriter.current.ws）。
 */

import { loadProjectConfig, addProjectManually } from '../../projects.js';

const TIMEOUT_MS = 5 * 60 * 1000; // 5 分钟（用户需要时间审阅和修改模板）

export default {
  name: '__share_project_template__',
  responseType: 'share-project-template-response',

  systemPrompt: `

## 分享项目模板工具

当用户想要分享项目、创建项目模板、发布共享项目时，使用以下 Bash 命令打开分享弹窗：

\`\`\`bash
__share_project_template__ '{"path":"/项目路径","displayName":"显示名称","description":"描述","updateNotes":"更新说明","skills":["skill1"],"mcps":["mcp1"],"files":["file1.md"],"gitRepos":[{"name":"子目录名","repo":"git远程地址","branch":"分支名"}]}'
\`\`\`

参数说明：
- path (必填): 项目文件夹路径，可以是当前项目、子文件夹或其他项目路径
- displayName (可选): 模板显示名称，仅首次创建时使用（更新时忽略）
- description (可选): 模板描述，仅首次创建时使用（更新时忽略）
- updateNotes (可选): 更新说明，仅更新已有模板时使用
- skills (可选): 要包含的技能名称数组，空数组=让用户在弹窗中选择
- mcps (可选): 要包含的 MCP 服务名称数组，空数组=让用户在弹窗中选择
- files (可选): 要包含的文件相对路径数组，空数组=让用户在弹窗中选择
- gitRepos (可选): 要包含的 Git 仓库依赖数组，每项包含 name(子目录名)、repo(远程地址)、branch(分支)，空数组=让用户在弹窗中选择

该命令会打开一个 UI 弹窗供用户确认和修改，等待用户操作完成后返回结果。
`,

  match(hookInput) {
    return hookInput.tool_name === 'Bash' &&
      hookInput.tool_input?.command?.trimStart().startsWith('__share_project_template__');
  },

  async execute(hookInput, context) {
    const { userUuid, mutableWriter, createRequestId, waitForResponse } = context;

    // 检测飞书模式：MutableWriter.current 有 .ws 属性（WebSocketWriter），FakeSendWriter 没有
    if (!mutableWriter?.current?.ws) {
      return { decision: 'deny', reason: '分享项目模板功能仅支持网页端使用。' };
    }

    // 解析参数
    const rawArgs = hookInput.tool_input.command.replace(/^\s*__share_project_template__\s*/, '');
    let jsonStr = rawArgs.trim();
    if ((jsonStr.startsWith("'") && jsonStr.endsWith("'")) ||
        (jsonStr.startsWith('"') && jsonStr.endsWith('"'))) {
      jsonStr = jsonStr.slice(1, -1);
    }
    const params = JSON.parse(jsonStr);

    if (!params.path) {
      return { decision: 'deny', reason: '缺少必需参数 path（项目路径）。' };
    }

    // 解析 path → projectKey，并判断是否为已有项目
    const config = await loadProjectConfig(userUuid);
    let projectKey = null;
    let isExistingProject = false;
    for (const [key, entry] of Object.entries(config)) {
      if ((entry.originalPath || key.replace(/-/g, '/')) === params.path) {
        projectKey = key;
        isExistingProject = true;
        break;
      }
    }
    if (!projectKey) {
      // 路径不在项目列表中（可能是子文件夹），自动添加为新项目
      try {
        const project = await addProjectManually(params.path, params.displayName, userUuid);
        projectKey = project.name;
        isExistingProject = false;
      } catch (e) {
        return { decision: 'deny', reason: `无法解析项目路径: ${e.message}` };
      }
    }

    // 发送 WebSocket 消息打开分享弹窗
    const shareRequestId = createRequestId();
    mutableWriter.send({
      type: 'share-project-template-request',
      requestId: shareRequestId,
      prefillData: {
        projectKey,
        projectPath: params.path,
        isExistingProject,
        displayName: params.displayName || '',
        description: params.description || '',
        updateNotes: params.updateNotes || '',
        skills: params.skills || [],
        mcps: params.mcps || [],
        files: params.files || [],
        gitRepos: params.gitRepos || [],
      }
    });

    // 等待前端响应（5 分钟超时）
    const response = await waitForResponse(shareRequestId, TIMEOUT_MS);

    let reason;
    if (!response) {
      reason = '分享项目模板请求超时（5分钟内未收到响应）。';
    } else if (response.cancelled) {
      reason = '用户取消了分享项目模板操作。';
    } else if (response.success) {
      reason = `项目模板已成功提交！提交 ID: ${response.submissionId}。${response.message || ''}`;
    } else {
      reason = `提交失败: ${response.error || '未知错误'}`;
    }

    return { decision: 'deny', reason };
  }
};
