/**
 * Introspection / debug MCP tools — LI SDD M2.2
 *
 * arcrun_validate_yaml          — dry-run YAML 校驗，不部署
 * arcrun_get_execution_trace    — 看 paused workflow state（task_id 細節）
 * arcrun_list_paused_executions — 列當前所有等 callback 的 workflow
 * arcrun_list_recent_executions — 列某 workflow 最近 N 次執行 verdict
 *
 * 對應 cypher-executor 新路由（commit 989fbeb）+ 既有 /validate。
 * 所有 tool 都需要 api_key (ak_xxx) 參數 — 跟 MCP partner-auth 的 pk_live 是兩層 auth。
 */

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { toolName } from "../brand.js";
import { z } from "zod";
import type { Env } from "../types.js";
import { cypherFetch, errorResponse, successResponse } from "../lib/cypher-client.js";

const apiKeyDesc =
  "你 (用戶) 的 arcrun api_key (ak_xxx)。從 https://arcrun.dev/me 取得。注意：跟 MCP 連線用的 pk_live token 是不同層 auth — pk_live 給 MCP 用，ak_xxx 給 workflow 操作用";

export function registerValidateYaml(server: McpServer, env: Env) {
  server.tool(
    toolName("validate_yaml"),
    "Dry-run YAML 校驗。不部署、無 side effect。回 {valid, errors?, nodeCount, edgeCount}。**永遠先 call 此 tool 再 push_workflow**，避免反覆 deploy 失敗。",
    {
      api_key: z.string().describe(apiKeyDesc),
      graph: z.object({
        nodes: z.array(z.unknown()).describe("workflow 節點陣列"),
        edges: z.array(z.unknown()).describe("workflow 邊陣列 (cypher binding 三元組)"),
      }).passthrough().describe("workflow graph object（已 parse 過 YAML 的結構，非 raw YAML string）"),
    },
    async ({ api_key, graph }) => {
      try {
        const res = await cypherFetch(env, "/validate", {
          apiKey: api_key,
          method: "POST",
          body: graph,
        });
        const body = await res.json().catch(() => null) as {
          valid?: boolean;
          errors?: unknown[];
          nodeCount?: number;
          edgeCount?: number;
        } | null;

        if (!res.ok || !body?.valid) {
          return errorResponse(
            "validation_failed",
            body?.errors ? `校驗失敗，${(body.errors as unknown[]).length} 個錯誤` : `校驗失敗 HTTP ${res.status}`,
            [
              "依 errors 陣列逐項修改 YAML",
              "若 errors 提到 '未知關係詞'，看 design.md §3 列出的合法關係詞",
              "若 errors 提到 'node 不存在'，檢查 edges 的 from/to 是否拼錯",
            ],
            JSON.stringify(body?.errors ?? body),
          );
        }

        return successResponse(body, [
          `校驗通過：${body.nodeCount} 個節點 / ${body.edgeCount} 條邊`,
          "可以 call arcrun_push_workflow 部署了",
        ]);
      } catch (e) {
        return errorResponse(
          "internal_error",
          `validate 內部錯：${e instanceof Error ? e.message : String(e)}`,
          ["重試一次", "若持續失敗，告訴 leo 並貼錯誤訊息"],
        );
      }
    },
  );
}

export function registerListPausedExecutions(server: McpServer, env: Env) {
  server.tool(
    toolName("list_paused_executions"),
    "列當前 api_key 下所有 paused workflow（等 daemon callback resume 的）。給 debug 用：claude_api 等 async 零件會把 workflow 暫停，此 tool 告訴你哪些還沒回來。",
    {
      api_key: z.string().describe(apiKeyDesc),
      limit: z.number().int().min(1).max(100).optional().describe("最多回幾個（預設 20，最多 100）"),
    },
    async ({ api_key, limit }) => {
      try {
        const res = await cypherFetch(env, "/executions/paused", {
          apiKey: api_key,
          query: limit ? { limit } : undefined,
        });
        const body = await res.json().catch(() => null);
        if (!res.ok) {
          return errorResponse(
            "fetch_failed",
            `撈 paused 列表失敗 HTTP ${res.status}`,
            ["檢查 api_key 是否正確", "稍後重試"],
            JSON.stringify(body),
          );
        }
        return successResponse(body);
      } catch (e) {
        return errorResponse(
          "internal_error",
          e instanceof Error ? e.message : String(e),
          ["重試一次"],
        );
      }
    },
  );
}

export function registerGetExecutionTrace(server: McpServer, env: Env) {
  server.tool(
    toolName("get_execution_trace"),
    "看單一 paused workflow 的 state 細節（trace、graph、context、pending_result）。task_id 從 paused 錯誤訊息或 list_paused_executions 取得。",
    {
      api_key: z.string().describe(apiKeyDesc),
      task_id: z.string().describe(
        "Paused workflow 的 task_id。來源：workflow 觸發後若 paused，error 訊息含 'waiting for task task_XXX'；或 list_paused_executions 回的 task_id 欄位",
      ),
    },
    async ({ api_key, task_id }) => {
      try {
        const res = await cypherFetch(env, `/executions/${encodeURIComponent(task_id)}`, {
          apiKey: api_key,
        });
        const body = await res.json().catch(() => null);

        if (res.status === 404) {
          return errorResponse(
            "not_found",
            `task_id "${task_id}" 沒對應的 paused state`,
            [
              "call list_paused_executions 看當前所有 paused，確認 task_id 正確",
              "若該 workflow 不是 paused 型，看 list_recent_executions 查歷史 verdict",
            ],
          );
        }

        if (!res.ok) {
          return errorResponse(
            "fetch_failed",
            `撈 execution trace 失敗 HTTP ${res.status}`,
            ["檢查 task_id 格式是否正確"],
            JSON.stringify(body),
          );
        }
        return successResponse(body);
      } catch (e) {
        return errorResponse(
          "internal_error",
          e instanceof Error ? e.message : String(e),
          ["重試一次"],
        );
      }
    },
  );
}

export function registerListRecentExecutions(server: McpServer, env: Env) {
  server.tool(
    toolName("list_recent_executions"),
    "列某 workflow 最近 N 次執行 verdict（成功 / 失敗 / duration）。資料來源是 D1 執行紀錄表，稽核資料——預設保留 90 天（3 個月）過期即清，管理者可在 portal 改保留天數或設為不刪除；用量過大時系統會自動降成只記失敗、甚至暫停記錄——工作流本身執行不受影響。",
    {
      api_key: z.string().describe(apiKeyDesc),
      workflow_name: z.string().describe("workflow 名稱（acr push 時的 name 欄）"),
      limit: z.number().int().min(1).max(100).optional().describe("最多回幾筆（預設 10，最多 100）"),
    },
    async ({ api_key, workflow_name, limit }) => {
      try {
        const res = await cypherFetch(
          env,
          `/workflows/${encodeURIComponent(workflow_name)}/executions`,
          {
            apiKey: api_key,
            query: limit ? { limit } : undefined,
          },
        );
        const body = await res.json().catch(() => null);

        if (res.status === 404) {
          return errorResponse(
            "not_found",
            `workflow "${workflow_name}" 不存在或不屬於你`,
            [
              "call list_workflows 看你有什麼 workflow",
              "確認 workflow 名稱拼寫正確",
            ],
          );
        }
        if (!res.ok) {
          return errorResponse(
            "fetch_failed",
            `撈執行歷史失敗 HTTP ${res.status}`,
            ["稍後重試"],
            JSON.stringify(body),
          );
        }
        return successResponse(body);
      } catch (e) {
        return errorResponse(
          "internal_error",
          e instanceof Error ? e.message : String(e),
          ["重試一次"],
        );
      }
    },
  );
}

export function registerAllIntrospectionTools(server: McpServer, env: Env) {
  registerValidateYaml(server, env);
  registerListPausedExecutions(server, env);
  registerGetExecutionTrace(server, env);
  registerListRecentExecutions(server, env);
}
