/**
 * Flock Freight get-a-quote RPA（PRD §14 / 技术设计 §7.6）
 * Direct：POST api.flockfreight.com/user/quotes；失败可回退 DOM 填表
 * 客户账密：强制 DOM 登录，跳过 Direct
 */
import {
  formatExternalSiteNavigationError,
  isTransientNavigationError,
} from "@/lib/rpa/page-goto";
import { fetchFlockQuotesViaDirect } from "@/lib/flock/direct-quote";
import {
  getFlockLoginCredentials,
  getFlockQuoteMode,
  getFlockSessionMaxRotations,
  isFlockDirectQuoteEnabled,
  isFlockDomQuoteFallbackEnabled,
  isFlockWorkerReuseSession,
} from "@/lib/flock/env";
import {
  getFlockLoginSource,
  hasEffectiveFlockLogin,
  runWithFlockLoginContext,
} from "@/lib/flock/login-context";
import { withFlockExclusiveLock } from "@/lib/flock/exclusive-lock";
import { getCustomerProviderLogin, hasCustomerProviderCredential } from "@/modules/customer/provider-credentials";
import { runFlockVisualChain } from "@/workers/rpa/flock/visual-chain";
import {
  runFlockQuoteWithWorkerSession,
  shouldRotateFlockSession,
} from "@/workers/rpa/flock/worker-session";
import type { FlockStageReporter } from "@/lib/flock/rpa-progress";
import { reportFlockStage } from "@/lib/flock/rpa-progress";
import type {
  FlockQuoteInput,
  FlockQuoteLine,
  FlockRunQuoteResult,
} from "@/workers/rpa/flock/types";

export type { FlockStageReporter };

function isFlockQuoteLimitError(errorMessage?: string): boolean {
  return /flock_quote_limit|thank you for your interest/i.test(
    errorMessage ?? "",
  );
}

/** 无痕全链：拒号/撞号时换邮箱重试（每轮新浏览器，对齐 batch 有效路径） */
export async function runFlockVisualChainWithRotations(
  input: FlockQuoteInput,
  onStage?: FlockStageReporter,
): Promise<FlockRunQuoteResult> {
  const maxRotations = getFlockSessionMaxRotations();
  let lastResult: FlockRunQuoteResult = {
    ok: false,
    quotes: [],
    errorMessage: "FLOCK_QUOTE_LIMIT：未执行查价",
  };

  for (let rotation = 0; rotation < maxRotations; rotation += 1) {
    const result = await runFlockVisualChain({ input, onStage });
    lastResult = result;

    if (result.ok) {
      return result;
    }
    if (isFlockQuoteLimitError(result.errorMessage)) {
      return result;
    }
    if (shouldRotateFlockSession(result.errorMessage)) {
      console.warn(
        `[flock-rpa] ${result.errorMessage?.slice(0, 80)}… 无痕换新邮箱 (${rotation + 1}/${maxRotations})`,
      );
      continue;
    }
    return result;
  }

  return {
    ok: false,
    quotes: [],
    errorMessage:
      lastResult.errorMessage ??
      `FLOCK_ACCOUNT_REJECTED：已换 ${maxRotations} 个邮箱仍无法查价`,
  };
}

function mockFlockQuotes(): FlockQuoteLine[] {
  return [
    {
      tier: "flock_direct",
      serviceLevel: "guaranteed",
      rateOption: "fastest",
      carrier: "Flock Freight",
      label: "FlockDirect®",
      totalUsd: 2330,
      transitDays: "4",
      transitDescription: "4 天（含周末）",
      reference: "FRG-MOCK",
    },
    {
      tier: "standard",
      serviceLevel: "standard",
      rateOption: "lowest",
      carrier: "Flock Freight",
      label: "Standard",
      totalUsd: 769,
      transitDays: "3-4",
      transitDescription: "3–4 个工作日（预估）",
      reference: "FRG-MOCK",
    },
  ];
}

async function runFlockDomPath(
  input: FlockQuoteInput,
  onStage?: FlockStageReporter,
): Promise<FlockRunQuoteResult> {
  if (hasEffectiveFlockLogin()) {
    console.log(
      `[flock-rpa] DOM 使用登录凭据 source=${getFlockLoginSource()}，跳过邮箱轮换`,
    );
    if (isFlockWorkerReuseSession()) {
      return runFlockQuoteWithWorkerSession(input, onStage);
    }
    return runFlockVisualChain({ input, onStage });
  }
  if (isFlockWorkerReuseSession()) {
    return runFlockQuoteWithWorkerSession(input, onStage);
  }
  return runFlockVisualChainWithRotations(input, onStage);
}

export type RunFlockQuoteOptions = {
  customerId?: string;
  onStage?: FlockStageReporter;
};

/** 执行 Flock 官网查价（Mock / Direct / DOM） */
export async function runFlockQuoteRpa(
  input: FlockQuoteInput,
  options?: RunFlockQuoteOptions,
): Promise<FlockRunQuoteResult> {
  if (process.env.RPA_MOCK_MODE === "true") {
    return { ok: true, quotes: mockFlockQuotes(), reference: "FRG-MOCK" };
  }

  const customerId = options?.customerId?.trim();
  let customerLogin = customerId
    ? await getCustomerProviderLogin(customerId, "flock")
    : null;

  const onStage = options?.onStage;

  // 已配置账密但解密失败：禁止回落 Direct API（否则拿不到折扣价）
  if (customerId && !customerLogin) {
    const configured = await hasCustomerProviderCredential(customerId, "flock");
    if (configured) {
      await reportFlockStage(onStage, "login");
      return {
        ok: false,
        quotes: [],
        errorMessage:
          "FLOCK_LOGIN_FAILED：客户已配置 Flock 账密但解密失败，请检查 JWT_SECRET 后重新保存账密（禁止改走 Direct API）",
      };
    }
  }

  const envLogin = getFlockLoginCredentials();
  const login = customerLogin ?? envLogin;
  const source = customerLogin ? "customer" : envLogin ? "env" : null;

  try {
    return await withFlockExclusiveLock(
      "embed-worker",
      () =>
        runWithFlockLoginContext(login, source, async () => {
          const mode = getFlockQuoteMode();
          console.log(
            `[flock-rpa] quoteMode=${mode} hasLogin=${Boolean(login)} source=${source ?? "none"} path=${login ? "dom-login" : "direct_or_dom"}`,
          );

          // 客户/环境账密：强制官网登录 DOM，禁止匿名 Direct API
          if (login) {
            console.log(
              `[flock-rpa] 已配置登录账密，强制 DOM 登录查价（禁止 Direct /user/quotes）source=${source}`,
            );
            return runFlockDomPath(input, onStage);
          }

          if (isFlockDirectQuoteEnabled()) {
            const direct = await fetchFlockQuotesViaDirect(input);
            if (direct.ok) {
              await reportFlockStage(onStage, "done");
              return direct;
            }
            console.warn(
              `[flock-rpa] Direct 失败: ${direct.errorMessage?.slice(0, 160) ?? "unknown"}`,
            );
            if (!isFlockDomQuoteFallbackEnabled()) {
              return direct;
            }
            console.warn("[flock-rpa] 回退 DOM 填表路径…");
          }

          return runFlockDomPath(input, onStage);
        }),
      { waitMs: 30_000, pollMs: 500 },
    );
  } 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,
    };
  }
}
