/**
 * Flock Direct：浏览器只用于拿匿名会话 cookie，报价走 POST /user/quotes（跳过填表 DOM）
 */
import {
  FLOCK_APP_ORIGIN,
  FLOCK_DIRECT_QUOTE_TIMEOUT_MS,
  FLOCK_QUOTES_URL,
  DEFAULT_FLOCK_USER_AGENT,
} from "@/lib/flock/constants";
import { getFlockMinQuotes, getFlockQuoteUrl } from "@/lib/flock/env";
import { mustForceFlockAccountLogin } from "@/lib/flock/login-context";
import { mapFlockFulfillmentOptionsToLines } from "@/lib/flock/map-fulfillment-options";
import { buildFlockQuotesApiRequest } from "@/lib/flock/quote-payload";
import { createRpaBrowserContext } from "@/lib/rpa/browser-context";
import { launchRpaBrowser } from "@/lib/rpa/browser-launch";
import {
  formatExternalSiteNavigationError,
  gotoWithResilience,
  isTransientNavigationError,
} from "@/lib/rpa/page-goto";
import { waitForFlockQuoteForm } from "@/workers/rpa/flock/form-interactions";
import type {
  FlockQuoteInput,
  FlockRunQuoteResult,
} from "@/workers/rpa/flock/types";

function randomDeviceFingerprint(): string {
  const alphabet =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  let out = "";
  for (let i = 0; i < 20; i += 1) {
    out += alphabet[Math.floor(Math.random() * alphabet.length)]!;
  }
  return out;
}

async function waitForSessionCookies(
  context: Awaited<ReturnType<typeof createRpaBrowserContext>>,
  timeoutMs: number,
): Promise<boolean> {
  const deadline = Date.now() + timeoutMs;
  while (Date.now() < deadline) {
    const cookies = await context.cookies();
    const hasAnon = cookies.some((c) => c.name === "anonymous_token");
    const hasJwt = cookies.some((c) => c.name === "ff_jwt");
    if (hasAnon || hasJwt) return true;
    await new Promise((r) => setTimeout(r, 250));
  }
  return false;
}

/** Direct 询价：bootstrap 匿名 cookie → POST /user/quotes → 映射两档 */
export async function fetchFlockQuotesViaDirect(
  input: FlockQuoteInput,
): Promise<FlockRunQuoteResult> {
  // 防御在深度：客户账密上下文下禁止走 Direct
  if (mustForceFlockAccountLogin()) {
    return {
      ok: false,
      quotes: [],
      errorMessage:
        "FLOCK_PATH_DENIED：客户已绑定官网账密，禁止 Direct /user/quotes，必须 DOM 登录查价",
    };
  }

  const headless = process.env.RPA_HEADLESS !== "false";
  const browser = await launchRpaBrowser({ headless, incognito: true });
  try {
    const context = await createRpaBrowserContext(browser, {
      userAgent: DEFAULT_FLOCK_USER_AGENT,
      extraHTTPHeaders: {
        "Accept-Language": "en-US",
      },
    });
    const page = await context.newPage();
    const url = getFlockQuoteUrl();

    try {
      await gotoWithResilience(page, url);
    } catch (error) {
      const raw = error instanceof Error ? error.message : String(error);
      return {
        ok: false,
        quotes: [],
        errorMessage: isTransientNavigationError({ message: raw })
          ? formatExternalSiteNavigationError("Flock Freight 官网", {
              message: raw,
            })
          : raw,
      };
    }

    await waitForFlockQuoteForm(page).catch(() => false);
    const ready = await waitForSessionCookies(context, 15_000);
    if (!ready) {
      return {
        ok: false,
        quotes: [],
        errorMessage:
          "FLOCK_DIRECT_NO_SESSION：未拿到 anonymous_token/ff_jwt（入口可能变更）",
      };
    }

    const payload = buildFlockQuotesApiRequest(input);
    const fingerprint = randomDeviceFingerprint();

    const response = await context.request.post(FLOCK_QUOTES_URL, {
      timeout: FLOCK_DIRECT_QUOTE_TIMEOUT_MS,
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
        Origin: FLOCK_APP_ORIGIN,
        Referer: `${FLOCK_APP_ORIGIN}/`,
        "x-device-fingerprint": fingerprint,
      },
      data: payload,
    });

    const status = response.status();
    const text = await response.text();
    if (status < 200 || status >= 300) {
      return {
        ok: false,
        quotes: [],
        errorMessage: `FLOCK_DIRECT_HTTP_${status}：${text.slice(0, 240)}`,
      };
    }

    let body: unknown;
    try {
      body = JSON.parse(text) as unknown;
    } catch {
      return {
        ok: false,
        quotes: [],
        errorMessage: "FLOCK_DIRECT_BAD_JSON：报价响应无法解析",
      };
    }

    const { quotes, reference } = mapFlockFulfillmentOptionsToLines(
      body as Parameters<typeof mapFlockFulfillmentOptionsToLines>[0],
    );
    const minQuotes = getFlockMinQuotes();
    if (quotes.length < minQuotes) {
      return {
        ok: false,
        quotes,
        reference,
        errorMessage: `FLOCK_DIRECT_NO_RATES：fulfillmentOptions 映射后不足 ${minQuotes} 档`,
      };
    }

    console.log(
      `[flock-direct] OK ref=${reference ?? "-"} ${quotes
        .map((q) => `${q.label}:$${q.totalUsd}`)
        .join(", ")}`,
    );
    return { ok: true, quotes, reference };
  } finally {
    await browser.close();
  }
}
