import type { Page } from "playwright";

export type CdpClickTarget = {
  x: number;
  y: number;
  width: number;
  height: number;
};

/** 在页面内解析选择器并返回视口中心坐标 */
export const RESOLVE_CLICK_TARGET = `(arg) => {
  var selector = arg.selector;
  var index = arg.index;
  var nodes = document.querySelectorAll(selector);
  var el = nodes[index];
  if (!el) {
    return null;
  }
  el.scrollIntoView({ block: "center", inline: "nearest" });
  var rect = el.getBoundingClientRect();
  if (!rect.width || !rect.height) {
    return null;
  }
  return {
    x: rect.left + rect.width / 2,
    y: rect.top + rect.height / 2,
    width: rect.width,
    height: rect.height,
  };
}`;

async function dispatchCdpClick(
  page: Page,
  target: CdpClickTarget,
): Promise<void> {
  const client = await page.context().newCDPSession(page);
  const x = target.x;
  const y = target.y;

  await client.send("Input.dispatchMouseEvent", {
    type: "mouseMoved",
    x,
    y,
    buttons: 0,
  });
  await client.send("Input.dispatchMouseEvent", {
    type: "mousePressed",
    x,
    y,
    button: "left",
    clickCount: 1,
    buttons: 1,
  });
  await client.send("Input.dispatchMouseEvent", {
    type: "mouseReleased",
    x,
    y,
    button: "left",
    clickCount: 1,
    buttons: 0,
  });
}

/**
 * 通过 CDP Input.dispatchMouseEvent 在元素中心点击（绕过 evaluate 合成 MouseEvent）。
 */
export async function cdpClickSelector(
  page: Page,
  selector: string,
  index = 0,
): Promise<boolean> {
  const target = (await page.evaluate(RESOLVE_CLICK_TARGET, {
    selector,
    index,
  })) as CdpClickTarget | null;

  if (!target) {
    return false;
  }

  await dispatchCdpClick(page, target);
  return true;
}
