import type { Page } from "playwright";
import type { QuoteItem, QuoteRequest } from "@/modules/providers/quote-provider";
import { AXEL_QUOTE_URL } from "@/lib/axel/constants";
import {
  buildAxelShipmentPayload,
  type AxelPlaceLocation,
} from "@/lib/axel/shipment";
import { RpaError } from "@/modules/rpa/errors";
import { decodeQuotePayloads } from "@/workers/rpa/quote-capture/payload-decode";
import { normalizeQuote } from "@/workers/rpa/quote-capture/quote-normalize";
import { validateQuoteSchema } from "@/workers/rpa/quote-capture/quote-schema-validator";

function resolveLocationDescription(
  fallback: string,
  address: QuoteRequest["pickup"],
): string {
  const userStreet = address.street?.trim();
  if (!userStreet) {
    return fallback;
  }
  const num = userStreet.match(/^\d+/)?.[0];
  if (num && !fallback.includes(num)) {
    const city = address.city?.trim();
    const state = address.state?.trim();
    if (city && state) {
      return `${userStreet}, ${city}, ${state}, USA`;
    }
    return userStreet;
  }
  return address.formattedAddress?.trim() || fallback;
}

function summarizeAxelRates(body: unknown): unknown {
  const rates = (body as { data?: { rates?: unknown } })?.data?.rates;
  if (!rates || typeof rates !== "object") {
    return null;
  }
  const out: Record<string, Record<string, number | string | null>> = {};
  for (const [sl, tiers] of Object.entries(rates as Record<string, unknown>)) {
    if (tiers == null || typeof tiers !== "object" || Array.isArray(tiers)) {
      continue;
    }
    out[sl] = {};
    for (const [ro, tier] of Object.entries(tiers as Record<string, unknown>)) {
      if (tier == null || typeof tier !== "object" || Array.isArray(tier)) {
        continue;
      }
      const t = tier as Record<string, unknown>;
      out[sl][ro] =
        typeof t.finalPrice === "number"
          ? t.finalPrice
          : typeof t.price === "number"
            ? t.price
            : null;
      const days = t.days;
      if (typeof days === "number") {
        out[sl][`${ro}_days`] = days;
      }
    }
  }
  return out;
}

/** 使用 prefetch 的 place 详情直接 POST axel/quote（真实 MotherShip 定价） */
export async function scrapeQuotesViaDirectAxel(
  page: Page,
  places: {
    pickup: AxelPlaceLocation;
    delivery: AxelPlaceLocation;
  },
  req: QuoteRequest,
): Promise<QuoteItem[]> {
  const shipment = buildAxelShipmentPayload({
    pickup: places.pickup,
    delivery: places.delivery,
    pickupDescription: resolveLocationDescription(
      req.pickup.formattedAddress ?? req.pickup.mothershipDisplayLabel ?? "",
      req.pickup,
    ),
    deliveryDescription: resolveLocationDescription(
      req.delivery.formattedAddress ?? req.delivery.mothershipDisplayLabel ?? "",
      req.delivery,
    ),
    cargo: {
      palletCount: req.palletCount,
      weightLb: req.weightLb,
      lengthIn: req.dimsIn.l,
      widthIn: req.dimsIn.w,
      heightIn: req.dimsIn.h,
    },
  });

  const body = await page.evaluate(
    async ({ url, payload }) => {
      const res = await fetch(url, {
        method: "POST",
        credentials: "include",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ shipment: payload }),
      });
      const text = await res.text();
      if (!res.ok) {
        const brief = text.slice(0, 200);
        if (res.status === 400 && /unable to find an accurate quote/i.test(text)) {
          throw new Error(`axel/quote UNAVAILABLE 400: ${brief}`);
        }
        throw new Error(`axel/quote HTTP ${res.status}: ${brief}`);
      }
      return JSON.parse(text) as unknown;
    },
    { url: AXEL_QUOTE_URL, payload: shipment },
  );

  if (!normalizeQuote(body)) {
    throw new RpaError(
      "RPA_DATA_INVALID",
      "direct axel/quote 响应不满足报价契约",
      { retryable: true },
    );
  }

  const rateSummary = summarizeAxelRates(body);
  if (rateSummary) {
    console.log(`[rpa] direct axel/quote rates: ${JSON.stringify(rateSummary)}`);
  }

  console.log("[rpa] direct axel/quote: 捕获真实报价响应");
  const decoded = decodeQuotePayloads({
    contractPayloads: [{ url: AXEL_QUOTE_URL, body }],
    jsonPayloads: [{ url: AXEL_QUOTE_URL, body }],
    networkTrace: [],
    resultUrl: page.url(),
  });
  if (!decoded?.items.length) {
    throw new RpaError(
      "RPA_DATA_INVALID",
      "direct axel/quote 无法解析报价档位",
      { retryable: true },
    );
  }
  return validateQuoteSchema(decoded.items);
}
