/**
 * Widget 地址 commit 稳定性探针（单测 + 可选实网循环）
 *
 * 默认：跑金样本/定位器/策略相关单测并输出摘要
 * 实网：需 dev:start + RPA_MOCK_MODE=false，设置 PROBE_WIDGET_LOOPS=5
 *
 * PowerShell:
 *   npm run probe:widget-address
 *   $env:PROBE_WIDGET_LOOPS="3"; npm run probe:widget-address
 */
import { spawnSync } from "node:child_process";
import { existsSync, readFileSync, readdirSync } from "node:fs";
import { join } from "node:path";
import {
  findGoldStandardTargets,
  loadAllGoldStandardTargets,
} from "@/workers/rpa/gold-standard-targets";
import { loadReconVerdict } from "@/workers/rpa/fix-place/recon-helpers";

const loops = Number(process.env.PROBE_WIDGET_LOOPS ?? "0");

function runUnitSuite(): boolean {
  const result = spawnSync(
    "npx",
    [
      "vitest",
      "run",
      "__tests__/workers/rpa/gold-standard-targets.test.ts",
      "__tests__/workers/rpa/mothership-styled-locator.test.ts",
      "__tests__/workers/rpa/address-adapter-diagnostics.test.ts",
      "__tests__/workers/rpa/place-commit-strategy.test.ts",
      "__tests__/workers/rpa/mothership-styled-suggestion-click.test.ts",
      "__tests__/workers/rpa/axel-selection-bridge.test.ts",
    ],
    { stdio: "inherit", shell: true },
  );
  return result.status === 0;
}

function summarizeGoldCoverage(): void {
  const targets = loadAllGoldStandardTargets();
  const verdict = loadReconVerdict();
  console.log("\n[widget-address-probe] 金样本条目:", targets.length);
  console.log("[widget-address-probe] recon verdict:", verdict.verdict);
  console.log(
    "[widget-address-probe] googleMapsLoaded:",
    verdict.googleMapsLoaded,
    "reactFiberKey:",
    verdict.reactFiberKey,
  );

  const sample = findGoldStandardTargets(
    "La Concha Key West, Autograph Collection, Duval Street, Key West, Florida, USA",
    { street: "Duval Street", city: "Key West", state: "FL", zip: "" },
    "pickup",
    40,
  );
  console.log(
    "[widget-address-probe] Key West 金样本匹配:",
    sample.length,
    sample[0]?.textPreview.slice(0, 48) ?? "—",
  );
}

function runRealLoop(): { pass: number; fail: number } {
  let pass = 0;
  let fail = 0;
  for (let i = 0; i < loops; i += 1) {
    console.log(`\n[widget-address-probe] prove:rpa-chain loop ${i + 1}/${loops}`);
    const result = spawnSync("npm", ["run", "prove:rpa-chain"], {
      stdio: "inherit",
      shell: true,
      env: {
        ...process.env,
        RPA_MOCK_MODE: "false",
        RPA_ADDRESS_MODE: "real",
      },
    });
    if (result.status === 0) {
      pass += 1;
    } else {
      fail += 1;
    }
  }
  return { pass, fail };
}

function readLatestChainProof(): { verdict?: string; placeHits?: number } {
  const dir = join(process.cwd(), ".rpa");
  if (!existsSync(dir)) {
    return {};
  }
  const files = readdirSync(dir)
    .filter((name: string) => name.startsWith("chain-proof-") && name.endsWith(".json"))
    .sort()
    .reverse();
  if (!files.length) {
    return {};
  }
  const raw = JSON.parse(readFileSync(join(dir, files[0]!), "utf8")) as {
    verdict?: string;
    workerLogSnippet?: string;
  };
  const snippet = raw.workerLogSnippet ?? "";
  const placeHits = (snippet.match(/axel\/location\/place/g) ?? []).length;
  return { verdict: raw.verdict, placeHits };
}

async function main(): Promise<void> {
  console.log("=== Widget Address Commit Stability Probe ===\n");
  summarizeGoldCoverage();

  const unitOk = runUnitSuite();
  if (!unitOk) {
    console.error("\n[widget-address-probe] 单测失败");
    process.exit(1);
  }

  if (loops > 0) {
    const { pass, fail } = runRealLoop();
    const rate = loops > 0 ? (pass / loops) * 100 : 0;
    const latest = readLatestChainProof();
    console.log("\n[widget-address-probe] 实网循环结果:", {
      loops,
      pass,
      fail,
      successRate: `${rate.toFixed(1)}%`,
      latestVerdict: latest.verdict,
      latestLogPlaceHits: latest.placeHits,
    });
    if (rate < 95) {
      console.error("[widget-address-probe] 成功率低于 95% 目标");
      process.exit(1);
    }
  } else {
    console.log(
      "\n[widget-address-probe] 单测通过。实网循环请设置 PROBE_WIDGET_LOOPS=3~10",
    );
  }
}

void main();
