import type { Locator, Page } from "playwright";
import type { AddressLookupInput } from "@/modules/address/types";
import {
  AxelSelectionBridge,
  axelPlaceFetchCandidates,
  normalizeAxelPlaceId,
} from "@/workers/rpa/axel-selection-bridge";
import { cdpClickSelector } from "@/workers/rpa/fix-place/cdp-click";

const AXEL_PLACE_BASE = "https://services.mothership.com/axel/location/place/";

export type AxelPlaceLocation = Record<string, unknown>;

const DISPATCH_PAC_ITEM_AT_INDEX = `(idx) => {
  const items = document.querySelectorAll(".pac-container .pac-item");
  const item = items[idx];
  if (!item) {
    return false;
  }
  item.scrollIntoView({ block: "center" });
  const target = item.querySelector(".pac-item-query") || item;
  const types = ["mousedown", "mouseup", "click"];
  for (let i = 0; i < types.length; i += 1) {
    target.dispatchEvent(
      new MouseEvent(types[i], {
        bubbles: true,
        cancelable: true,
        view: window,
      }),
    );
  }
  return true;
}`;

async function dispatchPacItemAtIndex(page: Page, index: number): Promise<boolean> {
  return page.evaluate(DISPATCH_PAC_ITEM_AT_INDEX, index);
}

async function buildCookieHeader(page: Page): Promise<string> {
  const cookies = await page.context().cookies();
  return cookies.map((c) => `${c.name}=${c.value}`).join("; ");
}

/**
 * Node 侧 GET axel/location/place（不经过 page.evaluate fetch，避免污染 AxelSelectionBridge）。
 */
export async function fetchAxelPlaceLocation(
  page: Page,
  placeId: string,
): Promise<{ ok: boolean; status: number; location: AxelPlaceLocation | null }> {
  const cookieHeader = await buildCookieHeader(page);
  const request = page.context().request;

  for (const candidate of axelPlaceFetchCandidates(placeId)) {
    const url = `${AXEL_PLACE_BASE}${encodeURIComponent(candidate)}`;
    try {
      const res = await request.get(url, {
        headers: {
          cookie: cookieHeader,
          accept: "application/json",
        },
      });
      const status = res.status();
      if (!res.ok()) {
        continue;
      }
      const location = (await res.json()) as Record<string, unknown>;
      return { ok: true, status, location };
    } catch {
      continue;
    }
  }
  return { ok: false, status: 0, location: null };
}

/**
 * DOM 点选未触发 selection handler 时：GET place + 尝试 pac 点选，最后才 fill 回退。
 */
export async function commitViaAxelPlacePrefetch(
  page: Page,
  bridge: AxelSelectionBridge,
  placeId: string,
  description: string,
  input: Locator,
  options?: { query?: AddressLookupInput; candidateIndex?: number },
): Promise<{ ok: boolean; location: AxelPlaceLocation | null }> {
  const fetched = await fetchAxelPlaceLocation(page, placeId);
  if (!fetched.ok || !fetched.location) {
    console.log(
      `[rpa] axel-place-prefetch: GET place 失败 status=${fetched.status}`,
    );
    return { ok: false, location: null };
  }

  const normalized = normalizeAxelPlaceId(placeId);
  bridge.setPlaceDetails(normalized, fetched.location);

  const index =
    options?.candidateIndex ?? bridge.getCandidateIndex(normalized);
  const text = description.replace(/\s+/g, " ").trim();

  await input.click({ force: true }).catch(() => undefined);
  if (index >= 0) {
    const cdpPac = await cdpClickSelector(page, ".pac-container .pac-item", index);
    if (cdpPac) {
      await page.waitForTimeout(400);
      if (bridge.hasPlaceCommit(normalized)) {
        await page.keyboard.press("Escape").catch(() => undefined);
        await page.keyboard.press("Tab").catch(() => undefined);
        console.log(
          `[rpa] axel-place-prefetch: cdp-pac place/${normalized} status=${fetched.status}`,
        );
        return { ok: true, location: fetched.location };
      }
    }
    await dispatchPacItemAtIndex(page, index);
    await page.waitForTimeout(400);
    if (bridge.hasPlaceCommit(normalized)) {
      await page.keyboard.press("Escape").catch(() => undefined);
      await page.keyboard.press("Tab").catch(() => undefined);
      console.log(
        `[rpa] axel-place-prefetch: pac-dispatch place/${normalized} status=${fetched.status}`,
      );
      return { ok: true, location: fetched.location };
    }
  }

  await input.fill(text).catch(() => undefined);
  await page.keyboard.press("Escape").catch(() => undefined);
  await page.keyboard.press("Tab").catch(() => undefined);
  await page.waitForTimeout(300);

  console.log(
    `[rpa] axel-place-prefetch: place/${normalized} status=${fetched.status}（fill 回退，未合成 commit）`,
  );
  return { ok: false, location: fetched.location };
}
