/**
 * MotherShip 登录态 ×10：遵守官网硬限（禁周末 / 单件≤5000lb）
 *   DIAG_HEADED=true npx tsx scripts/diag-mothership-rules-x10.ts
 */
import fs from "node:fs";
import path from "node:path";
import { loadDevEnv } from "@/lib/dev-env";

loadDevEnv();

const wantHeaded = process.env.DIAG_HEADED !== "false";
process.env.RPA_HEADED = wantHeaded ? "true" : "false";
process.env.RPA_HEADLESS = wantHeaded ? "false" : "true";
if (wantHeaded && !process.env.RPA_SLOW_MO_MS?.trim()) {
  process.env.RPA_SLOW_MO_MS = "80";
}
if (!wantHeaded) delete process.env.RPA_SLOW_MO_MS;

import { resolveAxelMothershipSuggest } from "@/lib/axel/candidates";
import {
  snapMothershipReadyDateToWeekday,
  MOTHERSHIP_MAX_WEIGHT_EACH_LB,
} from "@/lib/mothership/logged-in-constraints";
import { runWithMothershipLoginContext } from "@/lib/rpa/mothership-login-context";
import { getCustomerProviderLogin } from "@/modules/customer/provider-credentials";
import type { QuoteRequest } from "@/modules/providers/quote-provider";
import {
  buildLoggedInAddressSearchQuery,
  runMothershipLoggedInDashboardQuote,
} from "@/workers/rpa/mothership-logged-in-quote";

const READY_DATE = snapMothershipReadyDateToWeekday(
  process.env.DIAG_READY_DATE?.trim() || "2026-07-20",
);
const READY_TIME = process.env.DIAG_READY_TIME?.trim() || "12:00 PM";

/** 10 组线路；单件重量均 ≤5000 */
const LANES = [
  {
    name: "Brea→Fairhope",
    pickup: "789 East Elm Street suite 301, Brea, CA, USA",
    delivery: "456 Oak Avenue unit 207, Fairhope, AL, USA",
    weightEach: 250,
    qty: 2,
    dims: [60, 60, 60] as const,
  },
  {
    name: "LA→SF",
    pickup:
      "2020 West Washington Boulevard floor 5 rm 508, Los Angeles, CA, USA",
    delivery: "555 Market St ste 1001, San Francisco, CA, USA",
    weightEach: 480,
    qty: 2,
    dims: [48, 40, 48] as const,
  },
  {
    name: "Albany→SF",
    pickup: "101 South Pine Avenue, Albany, NY 12208, USA",
    delivery: "555 Market St ste 1001, San Francisco, CA, USA",
    weightEach: 120,
    qty: 2,
    dims: [48, 40, 48] as const,
  },
  {
    name: "MA→OR",
    pickup: "789 Elm Street, East Bridgewater, MA, USA",
    delivery: "888 Liberty Street Northeast, Salem, OR, USA",
    weightEach: 200,
    qty: 1,
    dims: [48, 40, 48] as const,
  },
  {
    name: "Dallas→Chicago",
    pickup: "1234 Main Street, Dallas, TX, USA",
    delivery: "200 East Randolph Street, Chicago, IL, USA",
    weightEach: 500,
    qty: 2,
    dims: [48, 40, 40] as const,
  },
  {
    name: "Atlanta→Denver",
    pickup: "100 Peachtree Street NW, Atlanta, GA, USA",
    delivery: "1701 California Street, Denver, CO, USA",
    weightEach: 300,
    qty: 2,
    dims: [48, 40, 48] as const,
  },
  {
    name: "Brea→LA",
    pickup: "789 East Elm Street, Brea, CA, USA",
    delivery:
      "2020 West Washington Boulevard floor 5 rm 508, Los Angeles, CA, USA",
    weightEach: 50,
    qty: 1,
    dims: [40, 40, 40] as const,
  },
  {
    name: "SF→Albany",
    pickup: "555 Market St ste 1001, San Francisco, CA, USA",
    delivery: "101 South Pine Avenue, Albany, NY 12208, USA",
    weightEach: 150,
    qty: 2,
    dims: [48, 40, 48] as const,
  },
  {
    name: "Chicago→Dallas",
    pickup: "200 East Randolph Street, Chicago, IL, USA",
    delivery: "1234 Main Street, Dallas, TX, USA",
    weightEach: 400,
    qty: 1,
    dims: [48, 40, 48] as const,
  },
  {
    name: "Denver→Atlanta",
    pickup: "1701 California Street, Denver, CO, USA",
    delivery: "100 Peachtree Street NW, Atlanta, GA, USA",
    weightEach: 220,
    qty: 2,
    dims: [48, 40, 40] as const,
  },
] as const;

type Row = {
  n: number;
  name: string;
  ok: boolean;
  ms: number;
  lastStep: string;
  detail: string;
};

const timingBuf: string[] = [];
const origLog = console.log.bind(console);
console.log = (...args: unknown[]) => {
  const line = args.map(String).join(" ");
  if (
    line.includes("[rpa] logged-in timing:") ||
    line.includes("[rpa] logged-in step:") ||
    line.includes("still no rate-card") ||
    line.includes("patched details") ||
    line.includes("rate-card ready") ||
    line.includes("FAILED") ||
    line.includes("weekend")
  ) {
    timingBuf.push(line);
  }
  origLog(...args);
};

async function pickFirst(query: string) {
  const list = await resolveAxelMothershipSuggest(query);
  const hit = list.find((c) => c.selectable !== false && c.option_id.trim());
  if (!hit) throw new Error(`无联想: ${query.slice(0, 50)}`);
  return hit;
}

function toAddr(c: Awaited<ReturnType<typeof pickFirst>>) {
  return {
    street: c.street,
    city: c.city,
    state: c.state,
    zip: c.zip || "",
    placeId: c.option_id,
    formattedAddress: c.formatted_address || c.display_label,
    selectedFromSuggestions: true,
    mothershipOptionId: c.option_id,
    mothershipDisplayLabel: c.display_label,
    selectedFromMothership: true,
  };
}

function lastStep(): string {
  for (let i = timingBuf.length - 1; i >= 0; i -= 1) {
    const m = timingBuf[i]!.match(/step="([^"]+)"/);
    if (m) return m[1]!;
    if (timingBuf[i]!.includes("still no rate-card")) return "wait rate-card";
  }
  return "(none)";
}

async function main(): Promise<void> {
  for (const lane of LANES) {
    if (lane.weightEach > MOTHERSHIP_MAX_WEIGHT_EACH_LB) {
      throw new Error(`lane ${lane.name} weightEach 超限`);
    }
  }

  const customerId = process.env.DIAG_CUSTOMER_ID?.trim() || "CUST_001";
  const login = await getCustomerProviderLogin(customerId, "mothership");
  if (!login) {
    console.error(`[diag] 无 MotherShip 账密 customer=${customerId}`);
    process.exit(1);
  }

  console.log("=== MotherShip rules ×10（禁周末 / 单件≤5000）===");
  console.log(
    `headed=${wantHeaded} ready=${READY_DATE} ${READY_TIME} maxWeightEach=${MOTHERSHIP_MAX_WEIGHT_EACH_LB}`,
  );

  const rows: Row[] = [];
  for (let n = 0; n < LANES.length; n += 1) {
    const lane = LANES[n]!;
    timingBuf.length = 0;
    const t0 = Date.now();
    console.log(`\n---------- ${n + 1}/10 ${lane.name} wt=${lane.weightEach} ----------`);
    try {
      const [p, d] = await Promise.all([
        pickFirst(lane.pickup),
        pickFirst(lane.delivery),
      ]);
      const req: QuoteRequest = {
        cargoHash: `diag-rules-${n}-${Date.now()}`,
        pickup: toAddr(p),
        delivery: toAddr(d),
        weightLb: lane.weightEach,
        dimsIn: { l: lane.dims[0], w: lane.dims[1], h: lane.dims[2] },
        palletCount: lane.qty,
        cargoType: "general_freight",
        readyDate: READY_DATE,
        readyTime: READY_TIME,
        cargoLines: [
          {
            cargoType: "pallet",
            quantity: lane.qty,
            weightLb: lane.weightEach,
            lengthIn: lane.dims[0],
            widthIn: lane.dims[1],
            heightIn: lane.dims[2],
          },
        ],
      };
      console.log(
        `[diag] ${buildLoggedInAddressSearchQuery(req.pickup)} → ${buildLoggedInAddressSearchQuery(req.delivery)}`,
      );
      const items = await runWithMothershipLoginContext(login, "customer", () =>
        runMothershipLoggedInDashboardQuote(req),
      );
      const ms = Date.now() - t0;
      const carriers = items.map((i) => `${i.carrier}=$${i.rawTotal}`).join(", ");
      rows.push({
        n: n + 1,
        name: lane.name,
        ok: true,
        ms,
        lastStep: lastStep(),
        detail: carriers,
      });
      console.log(`[diag] OK ${ms}ms ${carriers}`);
    } catch (err) {
      const ms = Date.now() - t0;
      const msg = err instanceof Error ? err.message : String(err);
      rows.push({
        n: n + 1,
        name: lane.name,
        ok: false,
        ms,
        lastStep: lastStep(),
        detail: msg.slice(0, 220),
      });
      console.log(`[diag] FAIL ${ms}ms step=${lastStep()} ${msg.slice(0, 160)}`);
    }
  }

  const okN = rows.filter((r) => r.ok).length;
  const reportPath = path.join(
    process.cwd(),
    ".rpa",
    "diag",
    `rules-x10-${new Date().toISOString().replace(/[:.]/g, "-")}.md`,
  );
  const md = [
    `# MotherShip rules ×10`,
    "",
    `- ready=${READY_DATE}（已 snap 工作日）`,
    `- maxWeightEach=${MOTHERSHIP_MAX_WEIGHT_EACH_LB}`,
    `- ok=${okN}/10`,
    "",
    "| # | lane | ok | ms | lastStep | detail |",
    "|---|------|----|----|----------|--------|",
    ...rows.map(
      (r) =>
        `| ${r.n} | ${r.name} | ${r.ok ? "Y" : "N"} | ${r.ms} | ${r.lastStep} | ${r.detail.replace(/\|/g, "/")} |`,
    ),
    "",
  ].join("\n");
  fs.mkdirSync(path.dirname(reportPath), { recursive: true });
  fs.writeFileSync(reportPath, md, "utf8");
  console.log(`\n=== SUMMARY ok=${okN}/10 report=${reportPath} ===`);
  for (const r of rows) {
    console.log(
      `  #${r.n} ${r.ok ? "OK" : "FAIL"} ${r.name} ${r.ms}ms ${r.lastStep}`,
    );
  }
  process.exit(okN === 10 ? 0 : 1);
}

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