/** Priority1 公开询价页报价提取（Feathery custom_request + 页面摘要） */

export type Priority1QuoteLine = {
  rank: number;
  carrier: string;
  carrierCode: string;
  totalUsd: number;
  transitDays: number;
  deliveryDate: string | null;
  expirationDate: string | null;
  serviceLevel: string;
  quoteId: number | null;
  caboUrl: string | null;
  source: "feathery-summary" | "visible-dom" | "api-all" | "dom" | "ftl-calendar" | "legacy-tier";
};

type ApiRateQuote = {
  id?: number;
  carrierName?: string;
  carrierCode?: string;
  transitDays?: number;
  deliveryDate?: string;
  expirationDate?: string;
  serviceLevel?: string;
  serviceLevelDescription?: string;
  rateQuoteDetail?: { total?: number };
};

function asNumber(v: unknown): number {
  if (typeof v === "number" && Number.isFinite(v)) return v;
  if (typeof v === "string") {
    const n = Number(v.replace(/,/g, ""));
    if (Number.isFinite(n)) return n;
  }
  return 0;
}

function parseCustomRequestPayload(body: unknown): Priority1QuoteLine[] {
  if (!body || typeof body !== "object") return [];
  const data = (body as { data?: { id?: number; rateQuotes?: ApiRateQuote[] } })
    .data;
  const list = data?.rateQuotes;
  if (!Array.isArray(list)) return [];

  return list
    .map((q, idx) => ({
      rank: idx + 1,
      carrier: String(q.carrierName ?? "").trim(),
      carrierCode: String(q.carrierCode ?? "").trim(),
      totalUsd: asNumber(q.rateQuoteDetail?.total),
      transitDays: asNumber(q.transitDays),
      deliveryDate: q.deliveryDate ?? null,
      expirationDate: q.expirationDate ?? null,
      serviceLevel: String(
        q.serviceLevelDescription ?? q.serviceLevel ?? "",
      ).trim(),
      quoteId: typeof data?.id === "number" ? data.id : null,
      caboUrl:
        typeof data?.id === "number"
          ? `https://dashboard.priority1.com/ltl/quotes/details/${data.id}`
          : null,
      source: "api-all" as const,
    }))
    .filter((q) => q.carrier && q.totalUsd > 0);
}

function parseFeatherySummaryPayload(body: unknown): Priority1QuoteLine[] {
  if (!body || typeof body !== "object") return [];
  const o = body as Record<string, unknown>;
  const out: Priority1QuoteLine[] = [];

  const slots = [
    {
      prefix: "LTL_best_price_quote",
      rank: 1,
    },
    {
      prefix: "LTL_standard_rate_quote",
      rank: 2,
    },
    {
      prefix: "LTL_second_rate_quote",
      rank: 3,
    },
    {
      prefix: "LTL_expedited_quote",
      rank: 4,
    },
  ];

  for (const slot of slots) {
    const carrier = o[`${slot.prefix}_carrier`];
    const cost = o[`${slot.prefix}_cost`];
    if (!carrier || !cost) continue;
    out.push({
      rank: slot.rank,
      carrier: String(carrier),
      carrierCode: "",
      totalUsd: asNumber(cost),
      transitDays: asNumber(o[`${slot.prefix}_transit`]),
      deliveryDate: o[`${slot.prefix}_del_date`]
        ? String(o[`${slot.prefix}_del_date`])
        : null,
      expirationDate: o[`${slot.prefix}_exp_date`]
        ? String(o[`${slot.prefix}_exp_date`])
        : null,
      serviceLevel: slot.prefix.includes("expedited")
        ? "Expedited"
        : "Standard",
      quoteId: typeof o.quote_id === "number" ? o.quote_id : null,
      caboUrl:
        typeof o.cabo_url === "string"
          ? o.cabo_url
          : typeof o.quote_id === "number"
            ? `https://dashboard.priority1.com/ltl/quotes/details/${o.quote_id}`
            : null,
      source: "feathery-summary",
    });
  }

  /** FTL 日历页 — quote_00 / quote_01 等槽位 */
  const ftlSlots = Object.keys(o).filter((k) => /^quote_\d+$/i.test(k));
  for (let i = 0; i < ftlSlots.length; i += 1) {
    const key = ftlSlots[i]!;
    const cost = o[key];
    const n = asNumber(cost);
    if (n <= 0 || String(cost).includes("{{")) continue;
    out.push({
      rank: out.length + 1,
      carrier: "FTL 日历报价",
      carrierCode: "",
      totalUsd: n,
      transitDays: 0,
      deliveryDate: null,
      expirationDate: null,
      serviceLevel: "FTL",
      quoteId: typeof o.quote_id === "number" ? o.quote_id : null,
      caboUrl: typeof o.cabo_url === "string" ? o.cabo_url : null,
      source: "feathery-summary",
    });
  }

  return out;
}

/** FTL 报价页 — YOUR INSTANT QUOTE OPTIONS 日历表格（价格常无 $ 前缀） */
export function parseFtlCalendarQuotes(text: string): Priority1QuoteLine[] {
  if (!/YOUR INSTANT QUOTE OPTIONS|INSTANT QUOTE OPTIONS/i.test(text)) {
    return [];
  }
  const out: Priority1QuoteLine[] = [];
  const pairRe =
    /\b(?:SUN|MON|TUE|WED|THU|FRI|SAT)\b\s+(\d{1,2})\s+(\d{4,5}\.\d{2})/gi;
  let pair: RegExpExecArray | null;
  while ((pair = pairRe.exec(text)) !== null) {
    const day = Number(pair[1]);
    const totalUsd = asNumber(pair[2]);
    if (!Number.isFinite(day) || day < 1 || day > 31) continue;
    if (totalUsd < 200 || totalUsd > 100_000) continue;
    out.push({
      rank: out.length + 1,
      carrier: "FTL 日历报价",
      carrierCode: "",
      totalUsd,
      transitDays: 0,
      deliveryDate: `DAY:${day}`,
      expirationDate: null,
      serviceLevel: "FTL Calendar",
      quoteId: null,
      caboUrl: null,
      source: "ftl-calendar" as const,
    });
  }
  if (out.length > 0) {
    return out;
  }

  const prices: number[] = [];
  const re = /(?<![.\d])(\d{4,5}\.\d{2})(?![.\d])/g;
  let m: RegExpExecArray | null;
  while ((m = re.exec(text)) !== null) {
    const n = asNumber(m[1]);
    if (n >= 200 && n <= 100_000) {
      prices.push(n);
    }
  }
  const unique = [...new Set(prices)].sort((a, b) => a - b);
  return unique.map((totalUsd, idx) => ({
    rank: idx + 1,
    carrier: "FTL 日历报价",
    carrierCode: "",
    totalUsd,
    transitDays: 0,
    deliveryDate: null,
    expirationDate: null,
    serviceLevel: "FTL Calendar",
    quoteId: null,
    caboUrl: null,
    source: "ftl-calendar" as const,
  }));
}

/** 站点无即时报价、需销售人工确认时的标准返回文案 */
export const PRIORITY1_MANUAL_FOLLOWUP_MESSAGE =
  "表单已提交，站点判定需人工确认细节后报价";

export type Priority1QuoteOutcome = "instant_quote" | "manual_followup" | "no_result";

/** FTL 温控 / Expedited 等 — 「MORE INFORMATION NEEDED」终态（无金额） */
export function isPriority1ManualFollowupPage(domText: string): boolean {
  return (
    /MORE\s+INFORMATION\s+NEEDED/i.test(domText) &&
    /freight\s+specialist|Confirm\s+Details\s+&\s+Lock\s+In\s+Your\s+Rate|REQUEST\s+NEW\s+QUOTE/i.test(
      domText,
    )
  );
}

export function resolvePriority1SubmitOutcome(
  bodies: string[],
  domText: string,
): {
  outcome: Priority1QuoteOutcome;
  quotes: Priority1QuoteLine[];
  message?: string;
} {
  const quotes = extractPriority1VisibleQuotes(bodies, domText);
  if (quotes.length > 0) {
    return { outcome: "instant_quote", quotes };
  }
  if (isPriority1ManualFollowupPage(domText)) {
    return {
      outcome: "manual_followup",
      quotes: [],
      message: PRIORITY1_MANUAL_FOLLOWUP_MESSAGE,
    };
  }
  return { outcome: "no_result", quotes: [] };
}

/** 页面是否已进入报价结果（LTL 卡片 / FTL 日历 / 含 $ 金额） */
export function isPriority1QuotePageReady(domText: string): boolean {
  if (/\$[\d,]+\.\d{2}/.test(domText)) return true;
  if (/QUOTE\s+\d+/i.test(domText) && /\$[\d,]+\.\d{2}/.test(domText)) return true;
  if (parseFtlCalendarQuotes(domText).length > 0) return true;
  if (
    /YOUR INSTANT QUOTE OPTIONS|INSTANT QUOTE OPTIONS|REQUEST A NEW QUOTE/i.test(
      domText,
    ) &&
    /\b\d{4,5}\.\d{2}\b/.test(domText)
  ) {
    return true;
  }
  return false;
}

function parseUsDashOrSlashDate(raw: string | null | undefined): string | null {
  if (!raw) return null;
  const s = raw.trim();
  const dash = s.match(/^(\d{2})-(\d{2})-(\d{4})$/);
  if (dash) return `${dash[1]}/${dash[2]}/${dash[3]}`;
  const slash = s.match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
  if (slash) return s;
  const iso = s.match(/^(\d{4})-(\d{2})-(\d{2})/);
  if (iso) return `${iso[2]}/${iso[3]}/${iso[1]}`;
  return s;
}

const UNRESOLVED_CARRIER_RE = /未解析承运商|\(页面/;

function isUnresolvedCarrier(carrier: string | undefined | null): boolean {
  const c = String(carrier ?? "").trim();
  return !c || UNRESOLVED_CARRIER_RE.test(c);
}

function isLtlFeatherySummaryLine(line: Priority1QuoteLine): boolean {
  return (
    line.source === "feathery-summary" &&
    line.carrier !== "FTL 日历报价" &&
    !/^quote_\d+$/i.test(line.serviceLevel) &&
    line.serviceLevel !== "FTL"
  );
}

function pickOfficialUsd(
  summaryUsd: number,
  domUsd: number,
  domCarrierUnresolved: boolean,
): number {
  if (summaryUsd <= 0) return domUsd;
  if (domUsd <= 0) return summaryUsd;
  const drift = Math.abs(summaryUsd - domUsd) / summaryUsd;
  if (drift <= 0.02) return domUsd;
  return domCarrierUnresolved ? summaryUsd : domUsd;
}

function parseCarrierFromQuoteBlock(block: string): string {
  const afterQuote = block.match(
    /QUOTE\s+\d+\s+([A-Za-z][A-Za-z0-9\s&.'-]{1,48}?)\s+\$/i,
  );
  if (afterQuote?.[1]) {
    return afterQuote[1].replace(/\s+/g, " ").trim();
  }

  const beforeTransit = block.match(
    /STANDARD\s+LTL\s+(.+?)\s+Transit:/i,
  );
  if (beforeTransit?.[1]) {
    const c = beforeTransit[1].replace(/\s+/g, " ").trim();
    if (c && !/^QUOTE\s+\d/i.test(c)) return c;
  }

  const inline = block.match(
    /STANDARD\s+LTL\s+(.+?)\s+Quote Expiration Date/i,
  );
  if (inline?.[1]) {
    const c = inline[1].replace(/\s+/g, " ").trim();
    if (c && !/^QUOTE\s+\d/i.test(c)) return c;
  }

  const lines = block.split(/\n/).map((l) => l.trim()).filter(Boolean);
  for (let i = 0; i < lines.length; i += 1) {
    if (!/^STANDARD\s+LTL/i.test(lines[i]!)) continue;
    for (let j = i + 1; j < lines.length; j += 1) {
      const line = lines[j]!;
      if (
        /^(Transit:|Quote Expiration|Estimated Delivery|\$|QUOTE\s+\d+)/i.test(
          line,
        )
      ) {
        break;
      }
      if (line.length >= 2 && !/^STANDARD/i.test(line)) {
        return line.replace(/\s+/g, " ").trim();
      }
    }
  }
  return "";
}

function extractPriceFromQuoteBlock(block: string): number {
  const nearQuote = block.match(
    /QUOTE\s+\d+[\s\S]{0,120}?\$\s*([\d,]+\.\d{2})/i,
  );
  if (nearQuote?.[1]) return asNumber(nearQuote[1]);

  const prices = [...block.matchAll(/\$\s*([\d,]+\.\d{2})/g)].map((m) =>
    asNumber(m[1]),
  );
  return prices.find((p) => p > 0) ?? 0;
}

function mergeLtlSummaryWithDomCards(
  summary: Priority1QuoteLine[],
  domCards: Priority1QuoteLine[],
): Priority1QuoteLine[] {
  const ltlSummary = summary
    .filter(isLtlFeatherySummaryLine)
    .sort((a, b) => a.rank - b.rank);
  if (ltlSummary.length === 0) return [];

  const sortedDom = [...domCards].sort((a, b) => a.rank - b.rank);

  return ltlSummary.map((s, idx) => {
    const dom = sortedDom[idx];
    if (!dom) return s;
    return {
      ...s,
      rank: dom.rank,
      transitDays: dom.transitDays > 0 ? dom.transitDays : s.transitDays,
      deliveryDate: dom.deliveryDate ?? s.deliveryDate,
      expirationDate: dom.expirationDate ?? s.expirationDate,
      carrierCode: s.carrierCode || dom.carrierCode,
      source: "feathery-summary",
    };
  });
}

function enrichDomCardsFromNetwork(
  cards: Priority1QuoteLine[],
  bodies: string[],
): Priority1QuoteLine[] {
  if (cards.length === 0) return cards;
  const summary = extractFeatherySummaryQuotes(bodies)
    .filter(isLtlFeatherySummaryLine)
    .sort((a, b) => a.rank - b.rank);
  const api = extractPriority1AllApiQuotes(bodies);
  const sortedCards = [...cards].sort((a, b) => a.rank - b.rank);
  return sortedCards.map((card, idx) => {
    const unresolved = isUnresolvedCarrier(card.carrier);
    const match =
      summary.find((p) => p.rank === card.rank) ??
      summary[idx] ??
      (!unresolved
        ? api.find(
            (p) =>
              p.carrier.toLowerCase() === card.carrier.toLowerCase(),
          )
        : undefined) ??
      api[idx];
    if (!match) return card;
    return {
      ...card,
      carrier: unresolved ? match.carrier : card.carrier,
      carrierCode: card.carrierCode || match.carrierCode,
      totalUsd: pickOfficialUsd(match.totalUsd, card.totalUsd, unresolved),
      deliveryDate: card.deliveryDate ?? match.deliveryDate,
      expirationDate: card.expirationDate ?? match.expirationDate,
      transitDays: card.transitDays > 0 ? card.transitDays : match.transitDays,
      quoteId: card.quoteId ?? match.quoteId,
      caboUrl: card.caboUrl ?? match.caboUrl,
    };
  });
}

function parseVisibleQuoteCardsDom(text: string): Priority1QuoteLine[] {
  const out: Priority1QuoteLine[] = [];
  const blocks = text.split(/(?=QUOTE\s+\d+)/i).filter((b) => /QUOTE\s+\d+/i.test(b));

  for (const block of blocks) {
    const rankM = block.match(/QUOTE\s+(\d+)/i);
    const totalUsd = extractPriceFromQuoteBlock(block);
    if (!rankM || totalUsd <= 0) continue;

    const transitM = block.match(/Transit:\s*(\d+)\s+Business\s+Days?/i);
    const expM = block.match(
      /Quote Expiration Date:\s*(\d{2}[-/]\d{2}[-/]\d{4})/i,
    );
    const delM = block.match(
      /Estimated Delivery Date:\s*(\d{2}[-/]\d{2}[-/]\d{4})/i,
    );
    const carrier = parseCarrierFromQuoteBlock(block);

    out.push({
      rank: Number(rankM[1]),
      carrier: carrier || "(页面未解析承运商)",
      carrierCode: "",
      totalUsd,
      transitDays: transitM ? Number(transitM[1]) : 0,
      deliveryDate: parseUsDashOrSlashDate(delM?.[1]),
      expirationDate: parseUsDashOrSlashDate(expM?.[1]),
      serviceLevel: "STANDARD LTL",
      quoteId: null,
      caboUrl: null,
      source: "visible-dom",
    });
  }

  return out.sort((a, b) => a.rank - b.rank);
}

function parseDomTextQuotes(text: string): Priority1QuoteLine[] {
  const prices = [...text.matchAll(/\$([\d,]+\.\d{2})/g)].map((m) =>
    asNumber(m[1]),
  );
  const unique = [...new Set(prices)].filter((p) => p > 0).sort((a, b) => a - b);
  return unique.map((totalUsd, idx) => ({
    rank: idx + 1,
    carrier: "(页面未解析承运商)",
    carrierCode: "",
    totalUsd,
    transitDays: 0,
    deliveryDate: null,
    expirationDate: null,
    serviceLevel: "",
    quoteId: null,
    caboUrl: null,
    source: "dom",
  }));
}

export function extractPriority1AllApiQuotes(
  bodies: string[],
): Priority1QuoteLine[] {
  let apiQuotes: Priority1QuoteLine[] = [];
  for (const raw of bodies) {
    let parsed: unknown;
    try {
      parsed = JSON.parse(raw);
    } catch {
      continue;
    }
    const fromApi = parseCustomRequestPayload(parsed);
    if (fromApi.length > apiQuotes.length) {
      apiQuotes = fromApi;
    }
  }
  return dedupeQuotes(apiQuotes);
}

function extractFeatherySummaryQuotes(bodies: string[]): Priority1QuoteLine[] {
  const summaryQuotes: Priority1QuoteLine[] = [];
  for (const raw of bodies) {
    let parsed: unknown;
    try {
      parsed = JSON.parse(raw);
    } catch {
      continue;
    }
    summaryQuotes.push(...parseFeatherySummaryPayload(parsed));
  }
  return dedupeQuotes(summaryQuotes);
}

/** 页面用户可见报价：可见 QUOTE 卡片 DOM > 摘要 > FTL 日历 > 全量 API */
export function extractPriority1VisibleQuotes(
  bodies: string[],
  domText = "",
): Priority1QuoteLine[] {
  const domCards = parseVisibleQuoteCardsDom(domText);
  const summary = extractFeatherySummaryQuotes(bodies);
  const ltlSummary = summary.filter(isLtlFeatherySummaryLine);

  if (ltlSummary.length > 0) {
    const merged = mergeLtlSummaryWithDomCards(ltlSummary, domCards);
    if (merged.length > 0) {
      return merged;
    }
  }

  if (domCards.length > 0) {
    return enrichDomCardsFromNetwork(domCards, bodies);
  }

  if (summary.length > 0) {
    return summary;
  }

  const ftlCalendar = parseFtlCalendarQuotes(domText);
  if (ftlCalendar.length > 0) {
    return ftlCalendar;
  }

  return extractPriority1AllApiQuotes(bodies).slice(0, 4).map((line, idx) => ({
    ...line,
    rank: idx + 1,
  }));
}

export function extractPriority1QuotesFromNetworkBodies(
  bodies: string[],
): Priority1QuoteLine[] {
  return extractPriority1VisibleQuotes(bodies);
}

export function extractPriority1QuotesFromDomText(text: string): Priority1QuoteLine[] {
  const cards = parseVisibleQuoteCardsDom(text);
  if (cards.length > 0) return cards;
  const ftl = parseFtlCalendarQuotes(text);
  if (ftl.length > 0) return ftl;
  return parseDomTextQuotes(text);
}

export function resolvePriority1QuoteBundles(
  bodies: string[],
  domText = "",
): { visible: Priority1QuoteLine[]; allApi: Priority1QuoteLine[] } {
  return {
    visible: extractPriority1VisibleQuotes(bodies, domText),
    allApi: extractPriority1AllApiQuotes(bodies),
  };
}

function dedupeQuotes(lines: Priority1QuoteLine[]): Priority1QuoteLine[] {
  const seen = new Set<string>();
  const out: Priority1QuoteLine[] = [];
  for (const line of lines) {
    const key = `${line.carrier}|${line.totalUsd}|${line.transitDays}`;
    if (seen.has(key)) continue;
    seen.add(key);
    out.push({ ...line, rank: out.length + 1 });
  }
  return out;
}

export function formatPriority1QuoteOutcomeMessage(
  outcome: Priority1QuoteOutcome,
  message?: string,
): string {
  if (outcome === "manual_followup") {
    return message ?? PRIORITY1_MANUAL_FOLLOWUP_MESSAGE;
  }
  if (outcome === "instant_quote") return "(即时报价)";
  return "(无报价结果)";
}

export function formatPriority1QuotesTable(lines: Priority1QuoteLine[]): string {
  if (!lines.length) return "(无报价)";
  const rows = lines.map(
    (q) =>
      `${String(q.rank).padStart(2)}. ${q.carrier.padEnd(22)} $${q.totalUsd.toFixed(2).padStart(9)}  ${q.transitDays}天  [${q.source}]`,
  );
  return rows.join("\n");
}
