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

const COMMIT_TIMEOUT_MS = 8_000;

const RESOLVE_WIDGET_ROW_BY_TEXT = `(arg) => {
  var probes = arg.probes || [];
  var widget = document.querySelector("#react-quoter-landing-plugin");
  if (!widget) {
    return null;
  }
  var rows = widget.querySelectorAll("div[class*='sc-']");
  var best = null;
  for (var i = 0; i < rows.length; i += 1) {
    var row = rows[i];
    if (row.querySelector("input, textarea, button")) {
      continue;
    }
    var text = (row.textContent || "").replace(/\\s+/g, " ").trim();
    if (text.length < 12) {
      continue;
    }
    var matched = false;
    for (var j = 0; j < probes.length; j += 1) {
      var probe = probes[j].toLowerCase();
      var lower = text.toLowerCase();
      if (!probe) continue;
      if (lower === probe || lower.indexOf(probe) >= 0 || probe.indexOf(lower) >= 0) {
        matched = true;
        break;
      }
    }
    if (!matched) {
      continue;
    }
    row.scrollIntoView({ block: "center" });
    var rect = row.getBoundingClientRect();
    if (!rect.width || rect.height < 18) {
      continue;
    }
    if (!best || text.length > best.textLength) {
      best = {
        x: rect.left + rect.width / 2,
        y: rect.top + rect.height / 2,
        width: rect.width,
        height: rect.height,
        textLength: text.length,
      };
    }
  }
  if (!best) {
    return null;
  }
  return {
    x: best.x,
    y: best.y,
    width: best.width,
    height: best.height,
  };
}`;

function buildPlaceIdSelectors(placeId: string): string[] {
  const normalized = normalizeAxelPlaceId(placeId);
  const selectors = new Set<string>();
  if (normalized) {
    selectors.add(`[data-place-id="${normalized}"]`);
    selectors.add(`[data-option-id="${normalized}"]`);
  }
  if (placeId.trim() && placeId !== normalized) {
    selectors.add(`[data-place-id="${placeId.trim()}"]`);
    selectors.add(`[data-option-id="${placeId.trim()}"]`);
  }
  return [...selectors];
}

async function cdpClickResolvedTarget(
  page: Page,
  target: { x: number; y: number; width: number; height: number },
): Promise<void> {
  const client = await page.context().newCDPSession(page);
  await client.send("Input.dispatchMouseEvent", {
    type: "mouseMoved",
    x: target.x,
    y: target.y,
    buttons: 0,
  });
  await client.send("Input.dispatchMouseEvent", {
    type: "mousePressed",
    x: target.x,
    y: target.y,
    button: "left",
    clickCount: 1,
    buttons: 1,
  });
  await client.send("Input.dispatchMouseEvent", {
    type: "mouseReleased",
    x: target.x,
    y: target.y,
    button: "left",
    clickCount: 1,
    buttons: 0,
  });
}

/**
 * CDP 真坐标点击：data-place-id → pac-item → styled 联想行。
 */
export async function commitViaCdpDomClick(
  page: Page,
  bridge: AxelSelectionBridge,
  placeId: string,
  description: string,
  options?: {
    candidateIndex?: number;
    query?: AddressLookupInput;
  },
): Promise<{ ok: boolean; method: string }> {
  const normalized = normalizeAxelPlaceId(placeId);
  const index = options?.candidateIndex ?? bridge.getCandidateIndex(normalized);

  for (const selector of buildPlaceIdSelectors(placeId)) {
    const clicked = await cdpClickSelector(page, selector, 0);
    if (!clicked) {
      continue;
    }
    await page.waitForTimeout(300);
    if (await bridge.waitForPlaceCommit(normalized, 2_500)) {
      console.log(`[rpa] cdp-place-commit: ${selector} 成功`);
      return { ok: true, method: "cdp-data-place-id" };
    }
  }

  if (index >= 0) {
    const pacClicked = await cdpClickSelector(
      page,
      ".pac-container .pac-item",
      index,
    );
    if (pacClicked) {
      await page.waitForTimeout(400);
      if (await bridge.waitForPlaceCommit(normalized, COMMIT_TIMEOUT_MS)) {
        console.log(`[rpa] cdp-place-commit: pac-item-${index} 成功`);
        return { ok: true, method: `cdp-pac-item-${index}` };
      }
    }
  }

  if (options?.query) {
    const probes = buildDescriptionProbes(description, options.query);
    const rowTarget = (await page.evaluate(RESOLVE_WIDGET_ROW_BY_TEXT, {
      probes,
    })) as { x: number; y: number; width: number; height: number } | null;
    if (rowTarget) {
      await cdpClickResolvedTarget(page, rowTarget);
      await page.waitForTimeout(400);
      if (await bridge.waitForPlaceCommit(normalized, COMMIT_TIMEOUT_MS)) {
        const matchedProbe = probes.find((probe) => labelsMatch(probe, description));
        console.log(
          `[rpa] cdp-place-commit: styled-row 成功 probe=${matchedProbe?.slice(0, 32) ?? "text"}`,
        );
        return { ok: true, method: "cdp-styled-row" };
      }
    }
  }

  console.log("[rpa] cdp-place-commit: 全部 CDP 路径未观测 place 200");
  return { ok: false, method: "cdp-dom-click-failed" };
}
