import type { Page } from "playwright";
import type { QuoteItem } from "@/modules/providers/quote-provider";
import { isRpaRequireQuoteRates, isRpaAddressRushMode } from "@/lib/rpa/env";
import { RpaError } from "@/modules/rpa/errors";
import { mapPageTextToErrorCode } from "@/modules/rpa/error-mapper";
import { captureQuoteNetworkResponses } from "@/workers/rpa/quote-capture/quote-network-capture";
import { isAxelQuoteResponseUrl } from "@/workers/rpa/quote-capture/axel-contract";
import { decodeQuotePayloads } from "@/workers/rpa/quote-capture/payload-decode";
import { validateQuoteSchema } from "@/workers/rpa/quote-capture/quote-schema-validator";
import { submitQuoteForm } from "@/workers/rpa/quote-capture/thin-browser-driver";
import { supplementWidgetTruckTabQuotes } from "@/workers/rpa/quote-capture/widget-truck-tab-quotes";
import { logQuoteDebugRaw } from "@/workers/rpa/quote-capture/quote-debug";
import type { QuoteCaptureSource, QuoteSubmitOptions } from "@/workers/rpa/quote-capture/types";

export type ScrapeQuotesMeta = {
  source: QuoteCaptureSource;
  contractCount: number;
};

/**
 * Contract-driven pipeline：
 * ThinBrowserDriver(submit) → QuoteNetworkCapture(shape) → QuoteContractGuard → QuoteSchemaValidator
 */
export async function runQuoteCapturePipeline(
  page: Page,
  options?: QuoteSubmitOptions,
): Promise<{ items: QuoteItem[]; meta: ScrapeQuotesMeta }> {
  if (!options?.widgetFallbackAfterDirectFailure) {
    throw new RpaError(
      "RPA_DATA_INVALID",
      "Widget 报价仅允许在 Direct 明确失败后由 quote-strategy 调用",
      { retryable: false },
    );
  }

  console.log("[rpa] quote-capture: Widget fallback pipeline start");

  const signals = await captureQuoteNetworkResponses(page, () =>
    submitQuoteForm(page, options),
  );

  const bodyText = await page.locator("body").innerText().catch(() => "");
  const textCode = mapPageTextToErrorCode(bodyText);
  if (textCode) {
    throw new RpaError(textCode, `结果页：${textCode}`, { retryable: false });
  }

  const decoded = decodeQuotePayloads(signals);
  if (!decoded || decoded.items.length === 0) {
    if (
      isRpaAddressRushMode() &&
      !isRpaRequireQuoteRates() &&
      signals.resultUrl.includes("sign-up-quote")
    ) {
      console.log(
        "[rpa] visual-rush: sign-up-quote 已落页，解析为空仍视为验收通过",
      );
      return {
        items: [],
        meta: { source: "lenient", contractCount: signals.contractPayloads.length },
      };
    }
    logQuoteDebugRaw(signals);
    throw new RpaError(
      "RPA_DATA_INVALID",
      `未捕获满足契约的报价响应（contract=${signals.contractPayloads.length}，json=${signals.jsonPayloads.length}，url=${signals.resultUrl}）`,
      { retryable: true },
    );
  }

  const axelBodies = signals.jsonPayloads
    .filter((p) => isAxelQuoteResponseUrl(p.url))
    .map((p) => p.body);

  const items = validateQuoteSchema(
    await supplementWidgetTruckTabQuotes(page, decoded.items, axelBodies),
  );

  console.log(
    `[rpa] quote-capture: source=${decoded.source} contract=${signals.contractPayloads.length}`,
  );

  return {
    items,
    meta: {
      source: decoded.source,
      contractCount: signals.contractPayloads.length,
    },
  };
}
