import type { Locator, Page } from "playwright";
import { firstVisibleLocator } from "@/lib/rpa/locator";

/** env 未配时的中英双语内置回退（MotherShip 首页 widget） */
const BUILTIN_SELECTOR_FALLBACKS: Record<string, string[]> = {
  RPA_SELECTOR_PICKUP_SECTION: [
    "#react-quoter-landing-plugin >> text=Pick up from",
    "#react-quoter-landing-plugin >> text=Where to pick up",
    "#react-quoter-landing-plugin >> text=从何处取货",
  ],
  RPA_SELECTOR_DELIVERY_SECTION: [
    "#react-quoter-landing-plugin >> text=Deliver to",
    "#react-quoter-landing-plugin >> text=Where to?",
    "#react-quoter-landing-plugin >> text=Delivery to",
    "#react-quoter-landing-plugin >> text=送货至",
  ],
  RPA_SELECTOR_PICKUP_STREET: [
    "#react-quoter-landing-plugin >> placeholder=Search by address",
    "#react-quoter-landing-plugin >> role=textbox[name=\"Search by address\"]",
    "#react-quoter-landing-plugin >> role=textbox[name=\"Search address\"]",
    "#react-quoter-landing-plugin >> role=textbox[name=\"搜索地址\"]",
    "role=textbox[name=\"Search by address\"]",
    "role=textbox[name=\"Search address\"]",
    "role=textbox[name=\"搜索地址\"]",
  ],
  RPA_SELECTOR_DELIVERY_STREET: [
    "#react-quoter-landing-plugin >> placeholder=Search by address",
    "#react-quoter-landing-plugin >> role=textbox[name=\"Search by address\"]",
    "#react-quoter-landing-plugin >> role=textbox[name=\"Search address\"]",
    "#react-quoter-landing-plugin >> role=textbox[name=\"搜索地址\"]",
    "role=textbox[name=\"Search by address\"]",
    "role=textbox[name=\"Search address\"]",
    "role=textbox[name=\"搜索地址\"]",
  ],
  RPA_SELECTOR_CARGO_SECTION: [
    "#react-quoter-landing-plugin >> text=What are you shipping",
    "#react-quoter-landing-plugin >> text=What are you shipping?",
    "#react-quoter-landing-plugin >> filter:text=Shipment details>>nth=4",
    "#react-quoter-landing-plugin >> filter:text=Freight details>>nth=4",
    "#react-quoter-landing-plugin >> filter:text=货运详情>>nth=4",
  ],
  RPA_SELECTOR_SUBMIT: [
    "#react-quoter-landing-plugin >> text=Get a freight quote",
    "role=button[name=\"GET QUOTE\"]",
    "role=button[name=\"Get freight quote\"]",
    "role=button[name=\"Get a freight quote\"]",
    "role=button[name=\"获取货运报价\"]",
  ],
  RPA_SELECTOR_STANDARD_TAB: [
    "filter:text=/^Standard$/>>first",
    "filter:text=/^标准$/>>first",
  ],
  RPA_SELECTOR_GUARANTEED_TAB: [
    "filter:text=/^Guaranteed$/>>first",
    "filter:text=/^保证送达$/>>first",
  ],
  RPA_SELECTOR_LOWEST_OPTION: ["text=Lowest price", "text=最低价格"],
  RPA_SELECTOR_ADDRESS_SUGGESTION: [
    "#react-quoter-landing-plugin >> [role=\"listbox\"] [role=\"option\"]",
    "#react-quoter-landing-plugin >> li",
    ".pac-item",
    '[role="option"]',
  ],
  RPA_SELECTOR_PALLET_QTY: [
    "placeholder=How many pallets?",
    "placeholder=需要几个托盘？",
  ],
  RPA_SELECTOR_WEIGHT: [
    "placeholder=Weight (lbs)",
    "placeholder=Weight (kg)",
    "placeholder=重量（公斤）",
  ],
  RPA_SELECTOR_LENGTH: ["placeholder=Length", "placeholder=长度"],
  RPA_SELECTOR_WIDTH: ["placeholder=Width", "placeholder=宽度"],
  RPA_SELECTOR_HEIGHT: ["placeholder=Height", "placeholder=高度"],
  RPA_SELECTOR_PRICE: ["text=$"],
  RPA_SELECTOR_QUOTE_WIDGET: ["#react-quoter-landing-plugin"],
  RPA_SELECTOR_FREIGHT_REMOVE: [
    'role=button[name=/remove/i]',
    'role=button[name=/delete/i]',
    'role=button[name=/删除/i]',
  ],
  RPA_SELECTOR_FREIGHT_ADD: [
    'role=button[name="ADD ITEM"]',
    'role=button[name=/Add item/i]',
    'role=button[name=/Add freight/i]',
    'role=button[name=/添加/i]',
  ],
};

/** 逗号分隔的多 selector 规格（中英双语） */
export function parseSelectorSpecs(raw: string | undefined): string[] {
  if (!raw?.trim()) {
    return [];
  }
  return raw.split(",").map((item) => item.trim()).filter(Boolean);
}

/** env 优先，再合并内置回退，去重保序 */
export function getSelectorSpecs(envKey: string): string[] {
  const fromEnv = parseSelectorSpecs(process.env[envKey]);
  const fallbacks = BUILTIN_SELECTOR_FALLBACKS[envKey] ?? [];
  const seen = new Set<string>();
  const merged: string[] = [];
  for (const spec of [...fromEnv, ...fallbacks]) {
    if (seen.has(spec)) {
      continue;
    }
    seen.add(spec);
    merged.push(spec);
  }
  return merged;
}

export async function firstVisibleFromSpecs(
  page: Page,
  specs: string[],
): Promise<Locator | null> {
  for (const spec of specs) {
    const loc = await firstVisibleLocator(page, spec);
    if (loc) {
      return loc;
    }
  }
  return null;
}

export async function clickFirstVisibleFromSpecs(
  page: Page,
  specs: string[],
): Promise<boolean> {
  const loc = await firstVisibleFromSpecs(page, specs);
  if (!loc) {
    return false;
  }
  await loc.click().catch(() => undefined);
  return true;
}

/** 可选字段：按 spec 列表尝试 fill（React 重渲染导致 detach 时重试） */
export async function fillFirstVisibleFromSpecs(
  page: Page,
  specs: string[],
  value: string,
  options?: { retries?: number },
): Promise<boolean> {
  const retries = options?.retries ?? 1;

  for (let attempt = 0; attempt < retries; attempt += 1) {
    const loc = await firstVisibleFromSpecs(page, specs);
    if (!loc) {
      if (attempt < retries - 1) {
        await page.waitForTimeout(200);
        continue;
      }
      return false;
    }

    try {
      await loc.fill(value, { timeout: 8_000 });
      return true;
    } catch (error) {
      const message = error instanceof Error ? error.message : String(error);
      const retriable =
        message.includes("detached") ||
        message.includes("not attached") ||
        message.includes("not visible");
      if (!retriable || attempt >= retries - 1) {
        throw error;
      }
      await page.waitForTimeout(250);
    }
  }

  return false;
}
