#!/usr/bin/env tsx
/**
 * Flock 人机协作录制 — 有头浏览器 + 分步暂停，便于熟悉流程与截图
 *
 * 用法:
 *   npm run visual:flock-human-assist
 *   $env:FLOCK_PATH_ID="F02-register-after-quote"; npm run visual:flock-human-assist
 *
 * 操作:
 *   - 浏览器打开后按 Playwright Inspector 提示继续
 *   - 每步 pause 时人工点击/填写，熟悉按钮位置
 *   - Ctrl+C 结束仍会保存 storageState 与截图目录
 */
import fs from "node:fs";
import path from "node:path";
import { chromium } from "playwright";
import {
  DEFAULT_FLOCK_DEMO,
  DEFAULT_FLOCK_QUOTE_URL,
  FLOCK_CANONICAL_PATHS,
  formatFlockRecordingChecklist,
  type FlockDemoInput,
} from "@/workers/rpa/flock/demo-input";
import { getFlockStorageStatePath } from "@/lib/flock/env";

const ROOT = process.cwd();

function formatTimestamp(): string {
  const d = new Date();
  const pad = (n: number) => String(n).padStart(2, "0");
  return `${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())}`;
}

async function screenshotStep(
  outDir: string,
  page: import("playwright").Page,
  name: string,
): Promise<void> {
  const file = path.join(outDir, `${name}.png`);
  await page.screenshot({ path: file, fullPage: true });
  console.log(`[截图] ${file}`);
}

async function main(): Promise<void> {
  const pathId = process.env.FLOCK_PATH_ID?.trim() ?? "F01-ltl-zip-quote";
  const canonical = FLOCK_CANONICAL_PATHS.find((p) => p.id === pathId);
  const demo: FlockDemoInput = canonical?.input ?? DEFAULT_FLOCK_DEMO;

  const outDir = path.join(ROOT, ".rpa", "recordings", `flock-human-${pathId}-${formatTimestamp()}`);
  fs.mkdirSync(outDir, { recursive: true });

  const checklistPath = path.join(outDir, "checklist.txt");
  fs.writeFileSync(checklistPath, formatFlockRecordingChecklist(demo), "utf8");

  console.log(`\n=== Flock 人机协作录制 ===`);
  console.log(`路径: ${pathId}${canonical ? ` — ${canonical.title}` : ""}`);
  if (canonical?.notes) console.log(`说明: ${canonical.notes}`);
  console.log(`产出目录: ${outDir}`);
  console.log(`\n${formatFlockRecordingChecklist(demo)}\n`);

  const statePath = getFlockStorageStatePath();
  fs.mkdirSync(path.dirname(statePath), { recursive: true });

  const browser = await chromium.launch({
    headless: false,
    slowMo: Number(process.env.RPA_SLOW_MO_MS ?? 80),
  });

  const context = await browser.newContext(
    fs.existsSync(statePath) ? { storageState: statePath } : {},
  );
  const page = await context.newPage();

  const saveAll = async () => {
    try {
      await context.storageState({ path: statePath });
      console.log(`[storage] ${statePath}`);
    } catch {
      /* ignore */
    }
  };

  process.on("SIGINT", async () => {
    console.log("\n[中断] 保存会话…");
    await saveAll();
    await browser.close();
    process.exit(130);
  });

  try {
    await page.goto(DEFAULT_FLOCK_QUOTE_URL, {
      waitUntil: "domcontentloaded",
      timeout: 60_000,
    });
    await screenshotStep(outDir, page, "00-entry");

    console.log("\n【步骤 1】请在浏览器中填写取货日期、ZIP、托盘、总重、尺寸");
    console.log("参考值见上方清单；填完后在 Inspector 点 Resume");
    await page.pause();

    await screenshotStep(outDir, page, "01-form-filled");

    console.log("\n【步骤 2】点击 Next / 下一个，等待进入报价或注册页");
    await page.pause();

    await screenshotStep(outDir, page, "02-after-next");

    console.log("\n【步骤 3】若出现两档报价，录制完成（勿点 Complete your order）");
    console.log("若出现 Create your free account，请填写测试账号并点 Get instant quote");
    await page.pause();

    await screenshotStep(outDir, page, "03-final");

    await saveAll();
    console.log("\n完成。可对照截图 + checklist，再运行 npm run record:flock 生成 codegen 脚本");
  } finally {
    await browser.close();
  }
}

main().catch((error) => {
  console.error(error);
  process.exit(1);
});
