import type { BrowserContext, Page } from "playwright";
import { REQUIRED_QUOTE_TIERS } from "@/lib/constants/quote";
import { isRpaMockMode } from "@/lib/rpa/selectors";
import type {
  QuoteItem,
  QuoteProvider,
  QuoteRequest,
  QuoteResult,
} from "@/modules/providers/quote-provider";
import { RpaError } from "@/modules/rpa/errors";
import { getConfidenceScore } from "@/modules/quote/confidence";
import { fetchAxelQuoteItems } from "@/lib/axel/quote-from-request";
import { hasEffectiveMothershipLogin } from "@/lib/rpa/mothership-login-context";
import { runMothershipLoggedInDashboardQuote } from "@/workers/rpa/mothership-logged-in-quote";
import {
  isDirectErrorFatalWithoutWidget,
  shouldFallbackToWidgetAfterDirectError,
} from "@/lib/rpa/direct-quote-fallback";
import {
  isParkedSessionEnabled,
  shouldKeepBrowserOpen,
  isWidgetQuoteFallbackEnabled,
} from "@/lib/rpa/env";
import { getRpaAddressMode, isRpaAddressMockMode } from "@/lib/rpa/address-mode";
import { storageStateExists } from "@/lib/rpa/storage-state";
import { RPAContext } from "@/workers/rpa/kernel/context";
import { runMothershipQuoteKernel } from "@/workers/rpa/kernel/orchestrator";
import { fillAddressStep } from "@/workers/rpa/kernel/steps/address-step";
import { fillCargoStep } from "@/workers/rpa/kernel/steps/cargo-step";
import {
  validateResult,
} from "@/workers/rpa/kernel/steps/quote-step";
import { quotePageAdapter } from "@/workers/rpa/quote-page-adapter";
import {
  openQuotePage,
  persistContext,
  withRpaSessionLock,
} from "@/workers/rpa/session-manager";
import {
  takeParkedQuoteSession,
  prepareParkedQuotePage,
} from "@/workers/rpa/parked-quote-session";
import { captureRpaDebugScreenshot } from "@/workers/rpa/page-prep";

function mockQuoteItems(): QuoteItem[] {
  const base = [
    { freight: 320, surcharges: 45, days: "3-5" },
    { freight: 380, surcharges: 45, days: "2-3" },
    { freight: 420, surcharges: 50, days: "3-5" },
    { freight: 480, surcharges: 50, days: "2-3" },
  ];
  return REQUIRED_QUOTE_TIERS.map((tier, index) => {
    const sample = base[index] ?? base[0];
    const rawTotal = sample.freight + sample.surcharges;
    return {
      serviceLevel: tier.service_level as QuoteItem["serviceLevel"],
      rateOption: tier.rate_option as QuoteItem["rateOption"],
      carrier: "Mock Carrier",
      transitDays: sample.days,
      transitDescription: `${sample.days} business days`,
      rawFreight: sample.freight,
      surcharges: sample.surcharges,
      rawTotal,
    };
  });
}

export { validateResult } from "@/workers/rpa/kernel/steps/quote-step";

/** @deprecated 使用 fillAddressStep(ctx, req) */
export async function fillAddress(page: Page, req: QuoteRequest): Promise<void> {
  await fillAddressStep(RPAContext.fromSession(page), req);
}

/** @deprecated 使用 fillCargoStep(ctx, req) */
export async function fillCargo(page: Page, req: QuoteRequest): Promise<void> {
  await fillCargoStep(RPAContext.fromSession(page), req);
}

/** @deprecated 使用 runMothershipQuoteKernel / captureQuotesDirectFirst */
export async function scrapeQuotes(_page: Page): Promise<QuoteItem[]> {
  throw new RpaError(
    "RPA_DATA_INVALID",
    "scrapeQuotes 已废弃：报价须走 Direct 优先策略（runMothershipQuoteKernel）",
    { retryable: false },
  );
}

export class MothershipRPAProvider implements QuoteProvider {
  async getQuote(req: QuoteRequest): Promise<QuoteResult> {
    if (isRpaMockMode()) {
      const items = mockQuoteItems();
      validateResult(items);
      return {
        items,
        sourceType: "rpa",
        confidenceScore: getConfidenceScore("rpa"),
      };
    }

    // 有账密：强制 dashboard rate-card（ABF/XPO/SAIA），禁止匿名 Axel Direct
    if (hasEffectiveMothershipLogin()) {
      console.log(
        "[rpa] getQuote: 已配置 MotherShip 账密，跳过 Axel Direct → dashboard DOM",
      );
      const items = await runMothershipLoggedInDashboardQuote(req);
      validateResult(items);
      return {
        items,
        sourceType: "rpa",
        confidenceScore: getConfidenceScore("rpa"),
      };
    }

    try {
      const items = await fetchAxelQuoteItems(req);
      validateResult(items);
      console.log(
        `[rpa] getQuote: node-direct 成功 tiers=${items.length}（不启动浏览器）`,
      );
      return {
        items,
        sourceType: "rpa",
        confidenceScore: getConfidenceScore("rpa"),
      };
    } catch (error) {
      const brief = error instanceof Error ? error.message : String(error);
      console.log(
        `[rpa] getQuote: node-direct 失败 — ${brief.slice(0, 200)}`,
      );
      if (shouldFallbackToWidgetAfterDirectError(error)) {
        console.log(
          "[rpa] getQuote: CARRIER_NO_CAPACITY，回退 Widget 浏览器抓价",
        );
      }
      const directFatal = isDirectErrorFatalWithoutWidget(error);
      if (!isWidgetQuoteFallbackEnabled() || directFatal) {
        if (error instanceof RpaError) {
          throw error;
        }
        throw new RpaError("RPA_DATA_INVALID", brief, { retryable: true });
      }
    }

    const session: {
      page: Page | null;
      context: BrowserContext | null;
      rpaCtx: RPAContext | null;
    } = {
      page: null,
      context: null,
      rpaCtx: null,
    };

    const executeQuote = async (
      relogin: boolean,
      tryParked: boolean,
    ): Promise<QuoteItem[]> => {
      return withRpaSessionLock(async () => {
        console.log(
          `[rpa] executeQuote start relogin=${relogin} addressMode=${getRpaAddressMode()}`,
        );
        if (!relogin && tryParked && req.quoteSessionId) {
          const parked = await takeParkedQuoteSession(req.quoteSessionId, {
            waitMs: 5_000,
          });
          if (parked) {
            const reuseStarted = Date.now();
            session.page = parked.page;
            session.context = parked.context;
            session.rpaCtx = RPAContext.fromSession(
              parked.page,
              parked.context,
            );
            console.log(
              "[rpa] step: reuseParkedSession（候选+询价单次会话续跑）",
            );
            await prepareParkedQuotePage(session.page);
            const items = await runMothershipQuoteKernel(
              session.rpaCtx,
              req,
            );
            await persistContext(session.context);
            console.log(
              `[rpa] reuseParkedSession 完成 ${Date.now() - reuseStarted}ms`,
            );
            return items;
          }
          console.log(
            "[rpa] 驻留会话不可用，回退 storageState 开页",
          );
        }

        const opened = await openQuotePage(
          quotePageAdapter,
          relogin,
          undefined,
          { freshCargoContext: true },
        );
        session.page = opened.page;
        session.context = opened.context;
        session.rpaCtx = RPAContext.fromSession(
          opened.page,
          opened.context,
        );
        console.log("[rpa] step: preCheck");
        await quotePageAdapter.preCheck(session.page, {
          reuseSession: false,
        });
        const items = await runMothershipQuoteKernel(session.rpaCtx, req);
        console.log("[rpa] 询价完成，跳过 persistContext（freshCargoContext）");
        return items;
      });
    };

    try {
      let items: QuoteItem[];
      try {
        items = await executeQuote(false, isParkedSessionEnabled());
      } catch (error) {
        if (
          error instanceof RpaError &&
          error.code === "SESSION_EXPIRED"
        ) {
          await session.page?.close().catch(() => undefined);
          await session.context?.close().catch(() => undefined);
          session.page = null;
          session.context = null;
          session.rpaCtx = null;
          items = await executeQuote(true, false);
        } else {
          throw error;
        }
      }

      return {
        items,
        sourceType: "rpa",
        confidenceScore: getConfidenceScore("rpa"),
      };
    } catch (error) {
      if (session.page) {
        await captureRpaDebugScreenshot(session.page, "failure");
      }
      if (error instanceof RpaError) {
        throw error;
      }
      throw new RpaError(
        "PAGE_LOAD_TIMEOUT",
        error instanceof Error ? error.message : "RPA 执行异常",
      );
    } finally {
      if (!shouldKeepBrowserOpen()) {
        await session.page?.close().catch(() => undefined);
        await session.context?.close().catch(() => undefined);
      } else if (isRpaAddressMockMode()) {
        // mock 探通：避免保活 Browser 僵死拖垮后续 job
        await session.page?.close().catch(() => undefined);
        await session.context?.close().catch(() => undefined);
      }
    }
  }

  async healthCheck(): Promise<boolean> {
    if (isRpaMockMode()) {
      return true;
    }
    try {
      const { ensureMothershipStorageState } = await import(
        "@/lib/rpa/ensure-storage-state"
      );
      await ensureMothershipStorageState();
      return storageStateExists();
    } catch {
      return false;
    }
  }
}

export const mothershipProvider = new MothershipRPAProvider();

/** @deprecated 使用 quotePageAdapter.preCheck */
export async function preCheck(page: Page): Promise<boolean> {
  return quotePageAdapter.preCheck(page);
}
