/**
 * acr workflow export <name> / acr workflow import <file> — workflow 可攜原語（t158）。
 *
 * leo 07-31 定調：「你要做的就是一個叫 export，另一個是 import，打包好的幾個工作流
 * 準備好直接 import 就好了。現在如果我要把我做的工作流分享給同事，我要怎麼 export？
 * 他要如何 import？是缺了功能用 search 來湊嗎？在從前就是寫成幾個 yaml 丟過去
 * 讓新的送進 KBDB 不是嗎？」
 *
 * - export：GET /webhooks/named/:name/definition → 寫成 .workflow.yaml 可攜檔
 *   （name/description/flow[從 graph.edges 反推，供人讀]/config/graph[可執行形，引擎產]）。
 * - import：讀可攜檔 → **直接 POST /webhooks/named**。零編圖、零 /cypher/search、
 *   零存在性驗證（部署≠發現，V2 純複製）——缺件的 workflow 照樣進，跑錯再改。
 *   手寫的 yaml（無 graph 欄）請走 acr push（那條才需要編圖）。
 * - 安裝器走同一條路：workflows.json 打包期預編 graph，pushWorkflow 直接 POST——
 *   不准安裝器走私有路徑。
 */
import chalk from 'chalk';
import ora from 'ora';
import yaml from 'js-yaml';
import { readFileSync, writeFileSync } from 'node:fs';
import { loadConfig, getCypherExecutorUrl } from '../lib/config.js';

type GraphShape = {
  nodes?: Array<{ id?: string }>;
  edges?: Array<{ from?: string; to?: string; type?: string }>;
};

/** graph.edges → flow 三元組（人讀用；graph 才是可執行真相）。 */
function flowFromGraph(graph: GraphShape): string[] {
  return (graph.edges ?? [])
    .filter(e => e.from && e.to)
    .map(e => `${e.from} >> ${e.type ?? 'ON_SUCCESS'} >> ${e.to}`);
}

function requireStandardConfig(): { executorUrl: string; apiKey: string } {
  const config = loadConfig();
  if (config.mode === 'local') {
    console.error(chalk.red('Local 模式不支援 workflow export/import（需要連上實例）。'));
    process.exit(1);
  }
  if (!config.api_key) {
    console.error(chalk.red('缺少 api_key／NAMESPACE，請先 acr init。'));
    process.exit(1);
  }
  return { executorUrl: getCypherExecutorUrl(config), apiKey: config.api_key };
}

export async function cmdWorkflowExport(name: string, options: { output?: string }): Promise<void> {
  const { executorUrl, apiKey } = requireStandardConfig();
  const spinner = ora(`從 ${executorUrl} 匯出 "${name}"`).start();
  try {
    const res = await fetch(`${executorUrl}/webhooks/named/${encodeURIComponent(name)}/definition`, {
      headers: { 'X-Arcrun-API-Key': apiKey },
    });
    if (!res.ok) {
      const err = await res.text();
      spinner.fail(chalk.red(`匯出失敗（${res.status}）：${err.slice(0, 200)}`));
      process.exit(1);
    }
    const def = await res.json() as {
      name: string; description: string;
      graph: GraphShape; config: Record<string, unknown>;
    };
    const out = options.output ?? `${def.name}.workflow.yaml`;
    const doc = {
      name: def.name,
      description: def.description,
      // flow＝從 graph 反推的可讀視圖；import 用的是 graph（可執行真相）
      flow: flowFromGraph(def.graph),
      config: def.config ?? {},
      graph: def.graph,
    };
    writeFileSync(out, yaml.dump(doc, { lineWidth: 120, noRefs: true }), 'utf8');
    spinner.succeed(chalk.green(`✓ 已匯出 → ${out}`));
    console.log(chalk.gray(`  給同事：把這個檔傳過去，對方 acr workflow import ${out} 即可。`));
  } catch (e) {
    spinner.fail(chalk.red(`網路錯誤：${e instanceof Error ? e.message : e}`));
    process.exit(1);
  }
}

export async function cmdWorkflowImport(filePath: string): Promise<void> {
  const { executorUrl, apiKey } = requireStandardConfig();
  let doc: { name?: string; description?: string; config?: Record<string, unknown>; graph?: GraphShape };
  try {
    doc = yaml.load(readFileSync(filePath, 'utf8')) as typeof doc;
  } catch (e) {
    console.error(chalk.red(`讀不了 ${filePath}：${e instanceof Error ? e.message : e}`));
    process.exit(1);
  }
  if (!doc?.name) {
    console.error(chalk.red('檔案缺 name 欄位。'));
    process.exit(1);
  }
  if (!doc.graph || !Array.isArray(doc.graph.nodes)) {
    // 手寫 yaml（只有 flow 沒 graph）＝acr push 的場景（那條會編圖）。import 專吃 export 檔。
    console.error(chalk.red('這個檔沒有 graph 欄位（不是 export 產物）。'));
    console.log(chalk.gray('手寫的 workflow.yaml 請改用：acr push ' + filePath));
    process.exit(1);
  }

  const spinner = ora(`匯入 "${doc.name}" → ${executorUrl}`).start();
  try {
    // 純複製：graph 直接送，不編圖、不打 /cypher/search、不驗零件存在（跑錯再改）。
    const res = await fetch(`${executorUrl}/webhooks/named`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', 'X-Arcrun-API-Key': apiKey },
      body: JSON.stringify({
        name: doc.name,
        graph: { ...doc.graph, id: doc.name, name: doc.name },
        config: doc.config ?? {},
        description: doc.description ?? '',
      }),
    });
    if (!res.ok) {
      const err = await res.text();
      spinner.fail(chalk.red(`匯入失敗（${res.status}）：${err.slice(0, 200)}`));
      process.exit(1);
    }
    const data = await res.json() as { webhook_url?: string };
    spinner.succeed(chalk.green(`✓ "${doc.name}" 已匯入`));
    if (data.webhook_url) console.log(chalk.bold(`  Webhook URL：${chalk.cyan(data.webhook_url)}`));
    console.log(chalk.gray('  沒驗零件存在——跑起來若報「找不到零件」，補上零件/recipe 或改 config 再跑。'));
  } catch (e) {
    spinner.fail(chalk.red(`網路錯誤：${e instanceof Error ? e.message : e}`));
    process.exit(1);
  }
}
