/**
 * 自动化审计：Convention Center pickup → place 网络 + DOM 结论
 * 输出：.rpa/pickup-commit-audit.json
 */
process.env.RPA_PLACE_DIAG = "true";
process.env.RPA_HEADLESS = "true";
process.env.RPA_MOCK_MODE = "false";
process.env.RPA_ADDRESS_MODE = "real";

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 { MotherShipAddressAdapter } from "@/workers/rpa/address-adapter/mothership-address-adapter";
import { openAddressSide, visibleStreetInput } from "@/workers/rpa/address-side";
import {
  SCAN_INPUT_GM_AND_DOM,
  SCAN_SUGGESTION_ROWS,
} from "@/workers/rpa/fix-place/axel-anatomy-scripts";
import {
  P0_PLACE_DIAG_INIT,
  P2_FETCH_HIJACK_INIT,
} from "@/workers/rpa/fix-place/place-diagnostic-init";
import { collectPlaceDiagSnapshot } from "@/workers/rpa/fix-place/place-diagnostic-probe";
import { RPAContext } from "@/workers/rpa/kernel/context";
import { getSelector } from "@/lib/rpa/selectors";
import {
  stabilizeQuoteLandingPage,
  waitForQuoterWidgetHydrated,
} from "@/workers/rpa/page-prep";
import { closeBrowser, openQuotePage } from "@/workers/rpa/session-manager";
import { quotePageAdapter } from "@/workers/rpa/quote-page-adapter";
import type { QuoteRequest } from "@/modules/providers/quote-provider";

loadDevEnv();

const OUT = join(process.cwd(), ".rpa", "pickup-commit-audit.json");
const BASE = process.env.PROVE_BASE_URL ?? "http://localhost:3000";

async function evalScan<T>(page: import("playwright").Page, fn: string): Promise<T> {
  return page.evaluate((body) => {
    const runner = eval(`(${body})`) as () => T;
    return runner();
  }, fn);
}

async function main(): Promise<void> {
  const runId = randomUUID().slice(0, 8);
  const pickupDraft = {
    street: "Washington State Convention Center Main Garage, Pike Street",
    city: "Seattle",
    state: "WA",
    zip: "",
    place_id: "draft_pickup",
    formatted_address: "Washington State Convention Center Main Garage, Pike Street, Seattle, WA",
    selected_from_suggestions: true,
  };
  const deliveryDraft = {
    street: "Ocean Drive",
    city: "Miami Beach",
    state: "FL",
    zip: "",
    place_id: "draft_delivery",
    formatted_address: "Ocean Drive, Miami Beach, FL",
    selected_from_suggestions: true,
  };

  const cand = await hostFetchMothershipCandidates(
    BASE,
    "demo-host-token",
    "CUST_001",
    pickupDraft,
    deliveryDraft,
  );
  if (cand.code !== 0 || !cand.data?.pickup_candidates[0]) {
    throw new Error(cand.message ?? "候选失败");
  }
  const pc = cand.data.pickup_candidates[0];
  const applied = applyMothershipCandidate(pickupDraft, pc);
  const pickup: QuoteRequest["pickup"] = {
    street: applied.street,
    city: applied.city,
    state: applied.state,
    zip: applied.zip ?? "",
    placeId: pc.option_id,
    formattedAddress: applied.formatted_address,
    selectedFromSuggestions: true,
    mothershipOptionId: pc.option_id,
    mothershipDisplayLabel: pc.display_label,
    selectedFromMothership: true,
  };

  const net: Array<{ url: string; status?: number; method: string }> = [];
  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" });

  opened.page.on("response", (res) => {
    const url = res.url();
    if (url.includes("axel/location/")) {
      net.push({
        url: url.slice(0, 260),
        status: res.status(),
        method: res.request().method(),
      });
    }
  });

  const ctx = RPAContext.fromSession(opened.page, opened.context);
  await stabilizeQuoteLandingPage(ctx);
  await waitForQuoterWidgetHydrated(ctx.page, 90_000);
  await openAddressSide(ctx, "pickup");
  const street = await visibleStreetInput(ctx, "pickup");
  if (!street) throw new Error("无输入框");

  const adapter = new MotherShipAddressAdapter();
  let adapterError: string | null = null;
  let result: Awaited<ReturnType<MotherShipAddressAdapter["selectAddress"]>> | null =
    null;
  try {
    result = await adapter.selectAddress({
      ctx,
      side: "pickup",
      address: pickup,
      street,
      widgetSelector: getSelector("RPA_SELECTOR_QUOTE_WIDGET"),
    });
  } catch (e) {
    adapterError = e instanceof Error ? e.message : String(e);
  }

  const dom = await evalScan<Record<string, unknown>>(
    ctx.page,
    SCAN_INPUT_GM_AND_DOM,
  );
  const suggestions = await evalScan<Record<string, unknown>>(
    ctx.page,
    SCAN_SUGGESTION_ROWS,
  );
  const p0 = await collectPlaceDiagSnapshot(ctx.page);

  const placeCommits = net.filter(
    (n) =>
      n.url.includes("/axel/location/place/") &&
      !n.url.includes("reverse-geocode") &&
      n.status === 200,
  );

  const report = {
    runId,
    label: pickup.mothershipDisplayLabel,
    placeId: pc.option_id,
    verdict: {
      componentType:
        (dom as { inputs?: Array<{ gmKeys?: string[] }> }).inputs?.some(
          (i) => (i.gmKeys?.length ?? 0) > 0,
        )
          ? "google-pac-hybrid"
          : "axel-styled-search",
      googleMapsOnWindow: Boolean(
        await ctx.page.evaluate(() => typeof google !== "undefined"),
      ),
      adapterCommitted: result?.committed ?? false,
      adapterError,
      commitState: adapter.getCommitState(),
      diagnostics: adapter.getDiagnostics(),
      placeCommitHttp200Count: placeCommits.length,
      placeCommitUrls: placeCommits.map((p) => p.url),
      p0Listeners: p0.listeners?.total ?? 0,
      p0HandlerEvents: (p0.handlerEvents ?? []).length,
      p2FetchPlaceCount: (p0.fetchLog ?? []).filter((f) =>
        String((f as { url?: string }).url ?? "").includes("/place/"),
      ).length,
    },
    dom,
    suggestions,
    network: net,
    p0,
    finishedAt: new Date().toISOString(),
  };

  mkdirSync(join(process.cwd(), ".rpa"), { recursive: true });
  writeFileSync(OUT, JSON.stringify(report, null, 2), "utf8");
  console.log(JSON.stringify(report.verdict, null, 2));
  console.log(`\n完整报告: ${OUT}`);

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

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