/**
 * P0/P2 place commit 诊断探针
 *
 * PowerShell:
 *   $env:RPA_PLACE_DIAG="true"
 *   $env:RPA_HEADLESS="false"
 *   npx tsx scripts/probe-place-diagnostic.ts
 */
process.env.RPA_PLACE_DIAG = "true";

import { randomUUID } from "node:crypto";
import { mkdirSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { loadDevEnv } from "@/lib/dev-env";
import {
  hostFetchMothershipCandidates,
} from "@/lib/frontend/api-client";
import { applyMothershipCandidate } from "@/lib/frontend/mothership-address";
import type { QuoteRequest } from "@/modules/providers/quote-provider";
import { getSelector } from "@/lib/rpa/selectors";
import { AxelSelectionBridge } from "@/workers/rpa/axel-selection-bridge";
import {
  ensureAddressSuggestions,
} from "@/workers/rpa/address-suggestions";
import { openAddressSide, visibleStreetInput } from "@/workers/rpa/address-side";
import { commitPlaceWithStrategy } from "@/workers/rpa/fix-place";
import {
  collectPlaceDiagSnapshot,
  interpretPlaceDiagnostic,
  setPlaceDiagMark,
} from "@/workers/rpa/fix-place/place-diagnostic-probe";
import {
  P0_PLACE_DIAG_INIT,
  P2_FETCH_HIJACK_INIT,
} from "@/workers/rpa/fix-place/place-diagnostic-init";
import { RPAContext } from "@/workers/rpa/kernel/context";
import {
  stabilizeQuoteLandingPage,
  waitForQuoterWidgetHydrated,
} from "@/workers/rpa/page-prep";
import { closeBrowser, openQuotePage } from "@/workers/rpa/session-manager";
import { quotePageAdapter } from "@/workers/rpa/quote-page-adapter";

loadDevEnv();

process.env.RPA_MOCK_MODE = "false";
process.env.RPA_ADDRESS_MODE = "real";
if (!process.env.RPA_HEADLESS) {
  process.env.RPA_HEADLESS = "false";
}

const BASE = process.env.PROVE_BASE_URL ?? "http://localhost:3000";
const TOKEN = "demo-host-token";
const CUSTOMER_ID = "CUST_001";
const OUT_DIR = join(process.cwd(), ".rpa", "place-diagnostic");

const PAIRS = {
  pickup: {
    street: "Washington State Convention Center Main Garage, Pike Street",
    city: "Seattle",
    state: "WA",
  },
  delivery: {
    street: "Ocean Drive",
    city: "Miami Beach",
    state: "FL",
  },
} as const;

function draftAddress(side: keyof typeof PAIRS) {
  const d = PAIRS[side];
  return {
    street: d.street,
    city: d.city,
    state: d.state,
    zip: "",
    place_id: `draft_${side}`,
    formatted_address: `${d.street}, ${d.city}, ${d.state}`,
    selected_from_suggestions: true,
  };
}

async function main(): Promise<void> {
  const runId = randomUUID().slice(0, 8);
  const side = (process.env.PROBE_PLACE_SIDE === "delivery" ? "delivery" : "pickup") as
    | "pickup"
    | "delivery";

  mkdirSync(OUT_DIR, { recursive: true });

  const candRes = await hostFetchMothershipCandidates(
    BASE,
    TOKEN,
    CUSTOMER_ID,
    draftAddress("pickup"),
    draftAddress("delivery"),
  );
  if (candRes.code !== 0 || !candRes.data) {
    throw new Error(candRes.message ?? "候选 API 失败");
  }

  const candidate =
    side === "pickup"
      ? candRes.data.pickup_candidates[0]
      : candRes.data.delivery_candidates[0];
  if (!candidate) {
    throw new Error(`${side} 无候选`);
  }

  const applied = applyMothershipCandidate(draftAddress(side), candidate);
  const address: QuoteRequest["pickup"] = {
    street: applied.street,
    city: applied.city,
    state: applied.state,
    zip: applied.zip ?? "",
    placeId: candidate.option_id,
    formattedAddress: applied.formatted_address,
    selectedFromSuggestions: true,
    mothershipOptionId: candidate.option_id,
    mothershipDisplayLabel: candidate.display_label,
    selectedFromMothership: true,
  };

  const queryHint = {
    street: address.street,
    city: address.city ?? "",
    state: address.state ?? "",
    zip: address.zip ?? "",
  };

  console.log(`\n=== place-diagnostic probe run=${runId} side=${side} ===`);
  console.log(`label: ${address.mothershipDisplayLabel}`);
  console.log(`placeId: ${candidate.option_id?.slice(0, 32)}…\n`);

  const opened = await openQuotePage(quotePageAdapter, false, undefined, {
    freshCargoContext: true,
  });
  await opened.context.addInitScript({ content: P0_PLACE_DIAG_INIT });
  await opened.context.addInitScript({ content: P2_FETCH_HIJACK_INIT });
  await opened.page.reload({ waitUntil: "domcontentloaded" });
  const ctx = RPAContext.fromSession(opened.page, opened.context);
  await stabilizeQuoteLandingPage(ctx);
  await waitForQuoterWidgetHydrated(ctx.page, 60_000);

  await setPlaceDiagMark(ctx.page, `${runId}-page-ready`);
  let baseline = await collectPlaceDiagSnapshot(ctx.page);
  if (!baseline?.ok) {
    console.warn("[probe] baseline 快照失败，P0 可能未就绪", baseline);
    baseline = baseline ?? { ok: false, reason: "snapshot-undefined" };
  }
  writeFileSync(
    join(OUT_DIR, `${runId}-baseline.json`),
    JSON.stringify(baseline, null, 2),
    "utf8",
  );
  for (const line of interpretPlaceDiagnostic(baseline, "baseline")) {
    console.log(line);
  }

  await openAddressSide(ctx, side);
  const street = await visibleStreetInput(ctx, side, {
    deliverySectionOpened: side === "delivery",
  });
  if (!street) {
    throw new Error("地址输入框不可见");
  }

  const bridge = new AxelSelectionBridge();
  bridge.attach(ctx.page);
  bridge.clearCandidates();

  await ensureAddressSuggestions(ctx.page, street, queryHint, {
    mothershipLabel: address.mothershipDisplayLabel!,
    preferConfirmedLabel: true,
  });
  await bridge.waitForSearchResults(12_000);

  const binding = bridge.resolveSelection(address.mothershipDisplayLabel!, queryHint);
  if (!binding?.placeId) {
    throw new Error("search 未绑定 placeId");
  }

  await setPlaceDiagMark(ctx.page, `${runId}-before-fix-place`);
  const fixResult = await commitPlaceWithStrategy(
    ctx.page,
    bridge,
    binding.placeId,
    binding.description,
    side,
    undefined,
    { input: street, query: queryHint },
  );

  const finalSnap = await collectPlaceDiagSnapshot(ctx.page);
  const report = {
    runId,
    side,
    address: {
      label: address.mothershipDisplayLabel,
      placeId: binding.placeId,
    },
    fixResult,
    bridge: {
      placeNetworkLog: bridge.getPlaceNetworkLog(),
      hasPlaceCommit: bridge.hasPlaceCommit(binding.placeId),
      httpOk: bridge.hasSuccessfulPlaceNetworkRequest(binding.placeId),
    },
    interpretation: interpretPlaceDiagnostic(finalSnap, "after-fix-place"),
    snapshot: finalSnap,
    finishedAt: new Date().toISOString(),
  };

  const reportPath = join(OUT_DIR, `${runId}-report.json`);
  writeFileSync(reportPath, JSON.stringify(report, null, 2), "utf8");

  console.log("\n=== fix-place 结果 ===");
  console.log(JSON.stringify(fixResult, null, 2));
  console.log("\n=== P0/P2 结论 ===");
  for (const line of report.interpretation) {
    console.log(line);
  }
  console.log(`\n报告：${reportPath}`);

  await opened.page.close().catch(() => undefined);
  await opened.context.close().catch(() => undefined);
  await closeBrowser();
}

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