/**
 * Flock 结果页报价提取 — testId 来自 flock-manual-20260713-152051.js
 */
import type { Page } from "playwright";
import { getFlockSelectorSpecs } from "@/lib/rpa/flock-selector-specs";
import { firstVisibleFromSpecs } from "@/lib/rpa/selector-specs";
import { waitWithFlockStallWatch } from "@/workers/rpa/flock/stall-watch";
import { flockLocatorCount } from "@/workers/rpa/flock/page-alive";
import type { FlockQuoteLine } from "@/workers/rpa/flock/types";

export function parseFlockMoney(text: string): number | null {
  const m = text.replace(/,/g, "").match(/\$\s*([\d]+(?:\.\d{1,2})?)/);
  if (!m) return null;
  const n = Number(m[1]);
  return Number.isFinite(n) && n > 0 ? n : null;
}

export function parseFlockTransit(text: string): {
  transitDays: string;
  transitDescription: string;
} {
  const weekend =
    text.match(/(\d+)\s*days?/i) ||
    text.match(/(\d+\s*[-–]\s*\d+)\s*(?:business\s*)?days?/i) ||
    text.match(/(\d+)\s*天/);
  const transitDays = weekend?.[1]?.replace(/\s+/g, "") ?? "—";
  const transitDescription =
    weekend?.[0] ??
    (/(business days only)/i.test(text)
      ? "工作日（预估）"
      : /incl\.\s*weekends/i.test(text)
        ? "含周末"
        : transitDays);
  return { transitDays, transitDescription };
}

/** 官网「仍在找价」页（Hold tight…约 15 分钟）— 有参考号但无即时报价卡 */
export function isFlockRatesPendingText(body: string): boolean {
  return (
    /Hold tight[\s\S]{0,80}still looking for the best rates/i.test(body) ||
    /still looking for the best rates/i.test(body) ||
    /rate for you in about\s*15\s*minutes/i.test(body)
  );
}

export function extractFlockPendingReference(body: string): string | null {
  const fromTitle = body.match(
    /#?\s*([A-Z0-9]{2,}-[A-Z0-9]{2,})\s+pricing options/i,
  );
  if (fromTitle?.[1]) return fromTitle[1];
  const fromRef = body.match(
    /Reference\s*#?\s*([A-Z0-9]+-[A-Z0-9]+|FRG-[A-Z0-9]+)/i,
  );
  return fromRef?.[1] ?? null;
}

export function formatFlockRatesPendingMessage(reference: string | null): string {
  const refPart = reference ? `，参考编号 ${reference}` : "";
  return (
    `FLOCK_RATES_PENDING：官网未给出即时报价，提示仍在寻找最优价格（约需 15 分钟后回查）${refPart}。` +
    "本单已结束，不会自动重跑查价。"
  );
}

export async function detectFlockRatesPending(page: Page): Promise<{
  pending: boolean;
  reference: string | null;
  errorMessage: string | null;
}> {
  const body = await page.locator("body").innerText().catch(() => "");
  if (!isFlockRatesPendingText(body)) {
    return { pending: false, reference: null, errorMessage: null };
  }
  const reference = extractFlockPendingReference(body);
  return {
    pending: true,
    reference,
    errorMessage: formatFlockRatesPendingMessage(reference),
  };
}

function lineFromCardText(
  tier: "flock_direct" | "standard",
  text: string,
  reference: string | null,
): FlockQuoteLine | null {
  const price = parseFlockMoney(text);
  if (price == null) return null;
  const { transitDays, transitDescription } = parseFlockTransit(text);
  const isDirect = tier === "flock_direct";
  return {
    tier,
    serviceLevel: isDirect ? "guaranteed" : "standard",
    rateOption: isDirect ? "fastest" : "lowest",
    carrier: "Flock Freight",
    label: isDirect ? "FlockDirect®" : "Standard",
    totalUsd: price,
    transitDays,
    transitDescription,
    reference,
  };
}

async function readQuotesGeneratedCount(page: Page): Promise<number> {
  const body = await page.locator("body").innerText().catch(() => "");
  const m = body.match(/Quotes generated:\s*(\d+)\s*of\s*(\d+)/i);
  return m ? Number(m[1]) : 0;
}

export async function waitForFlockQuoteResults(
  page: Page,
  timeoutMs = 20_000,
): Promise<boolean> {
  const directSpecs = getFlockSelectorSpecs("FLOCK_SELECTOR_CARD_DIRECT");
  const standardSpecs = getFlockSelectorSpecs("FLOCK_SELECTOR_CARD_STANDARD");

  async function anyQuoteReady(): Promise<boolean> {
    const generated = await readQuotesGeneratedCount(page);
    if (generated >= 1) {
      return true;
    }
    const direct = await firstVisibleFromSpecs(page, directSpecs);
    if (direct) {
      return true;
    }
    const standard = await firstVisibleFromSpecs(page, standardSpecs);
    if (standard) {
      return true;
    }
    const body = await page.locator("body").innerText().catch(() => "");
    if (isFlockRatesPendingText(body)) {
      return true;
    }
    return /Explore your custom quote|Prices from\s*\$/i.test(body);
  }

  const { ok } = await waitWithFlockStallWatch(
    page,
    "等待任意报价结果",
    anyQuoteReady,
    { timeoutMs, pollMs: 500 },
  );
  return ok;
}

export async function extractFlockQuoteCards(page: Page): Promise<{
  quotes: FlockQuoteLine[];
  reference: string | null;
}> {
  const bodyText = (await page.locator("body").innerText()).slice(0, 25_000);
  const refMatch = bodyText.match(
    /Reference\s*#?\s*([A-Z0-9]+-[A-Z0-9]+|FRG-[A-Z0-9]+)/i,
  );
  const reference = refMatch?.[1] ?? null;

  const quotes: FlockQuoteLine[] = [];

  const directLoc = page.getByTestId("FlockDirect®-fulfillment-option").first();
  const standardLoc = page.getByTestId("Standard-fulfillment-option").first();

  if ((await flockLocatorCount(directLoc)) > 0) {
    await directLoc
      .getByText(/\$/)
      .first()
      .waitFor({ timeout: 15_000 })
      .catch(() => undefined);
    const text = ((await directLoc.innerText().catch(() => "")) || "").trim();
    const line = lineFromCardText("flock_direct", text, reference);
    if (line) quotes.push(line);
  }

  if ((await flockLocatorCount(standardLoc)) > 0) {
    await standardLoc
      .getByText(/\$/)
      .first()
      .waitFor({ timeout: 15_000 })
      .catch(() => undefined);
    const text = ((await standardLoc.innerText().catch(() => "")) || "").trim();
    const line = lineFromCardText("standard", text, reference);
    if (line) quotes.push(line);
  }

  if (quotes.length >= 2) {
    return { quotes, reference };
  }

  const directFromSpecs = await firstVisibleFromSpecs(
    page,
    getFlockSelectorSpecs("FLOCK_SELECTOR_CARD_DIRECT"),
  );
  if (directFromSpecs) {
    const text = ((await directFromSpecs.innerText().catch(() => "")) || "").trim();
    const line = lineFromCardText("flock_direct", text, reference);
    if (line && !quotes.some((q) => q.tier === "flock_direct")) quotes.push(line);
  }

  const standardFromSpecs = await firstVisibleFromSpecs(
    page,
    getFlockSelectorSpecs("FLOCK_SELECTOR_CARD_STANDARD"),
  );
  if (standardFromSpecs) {
    const text = ((await standardFromSpecs.innerText().catch(() => "")) || "").trim();
    const line = lineFromCardText("standard", text, reference);
    if (line && !quotes.some((q) => q.tier === "standard")) quotes.push(line);
  }

  if (quotes.length >= 2) {
    return { quotes, reference };
  }

  if (quotes.length < 2) {
    const chunks = bodyText.split(/\n{1,}/);
    for (const chunk of chunks) {
      if (/FlockDirect/i.test(chunk) && !quotes.some((q) => q.tier === "flock_direct")) {
        const line = lineFromCardText("flock_direct", chunk, reference);
        if (line) quotes.push(line);
      }
      if (
        /\bStandard\b/i.test(chunk) &&
        !quotes.some((q) => q.tier === "standard")
      ) {
        const line = lineFromCardText("standard", chunk, reference);
        if (line) quotes.push(line);
      }
    }
  }

  return { quotes, reference };
}
