const { chromium } = require('playwright');

(async () => {
  // 启动浏览器并打开页面
  const browser = await chromium.launch({ headless: true });
  const page = await browser.newPage();
  // await page.goto('https://www.baidu.com');
  // await page.goto('https://play.grafana.org/a/grafana-synthetic-monitoring-app/probes', { waitUntil: 'domcontentloaded' });
  await page.goto('https://play.grafana.org/d/be9htelw63ke8b/metrics-rename-example?orgId=1&from=now-6h&to=now&timezone=utc', { waitUntil: 'domcontentloaded' });

  await page.waitForTimeout(10000);

  console.log('page loaded');

  // 提取完整的 AXTree（设置 interestingOnly: false 可获取全部节点）
  const axTree = await page.accessibility.snapshot({ interestingOnly: false });

  // 全局计数器和编号到"伪选择器"映射的对象
  let idCounter = 1;
  const idToSelector = {};

  // 在文件开头添加一个全局变量来存储父子关系
  const nodeParents = new Map();

  function traverse(node, depth = 0, parent = null) {
    // 记录父节点关系
    nodeParents.set(node, parent);

    // 增加 InlineTextBox 到过滤条件中
    if (((node.role === 'none' || node.role === 'generic' || node.role === 'InlineTextBox') && 
        !node.name && 
        !node.focusable && 
        !node.focused && 
        node.expanded === undefined) ||
        node.role === 'InlineTextBox'  // 无论如何都跳过 InlineTextBox
    ) {
      // 直接处理子节点
      if (node.children && node.children.length > 0) {
        for (const child of node.children) {
          traverse(child, depth, node);
        }
      }
      return;
    }

    const currentId = idCounter++;
    
    // 构建更详细的 selector
    let selectorParts = [`role=${node.role}`];
    
    if (node.name) {
      selectorParts.push(`[name="${node.name}"]`);
    }
    
    // 添加其他可能的属性
    if (node.selected) selectorParts.push('[selected=true]');
    if (node.checked !== undefined) selectorParts.push(`[checked=${node.checked}]`);
    if (node.pressed !== undefined) selectorParts.push(`[pressed=${node.pressed}]`);
    
    // 如果有父节点，添加父节点信息
    if (parent && parent.role !== 'WebArea') {
      let parentSelector = `role=${parent.role}`;
      if (parent.name) {
        parentSelector += `[name="${parent.name}"]`;
      }
      selectorParts.unshift(`${parentSelector} >>`);
    }
    
    // 如果是列表项，添加位置信息
    if (parent && parent.children) {
      const siblingIndex = parent.children.findIndex(child => child === node);
      if (siblingIndex !== -1) {
        selectorParts.push(`:nth-match(${siblingIndex + 1})`);
      }
    }
    
    idToSelector[currentId] = selectorParts.join(' ');

    // 收集所有可能的属性
    let props = [];
    if (node.focusable) props.push('focusable');
    if (node.focused) props.push('focused');
    if (node.expanded !== undefined) props.push(`expanded=${node.expanded}`);
    if (node.selected) props.push('selected');
    if (node.checked !== undefined) props.push(`checked=${node.checked}`);
    if (node.disabled) props.push('disabled');
    if (node.required) props.push('required');
    if (node.pressed !== undefined) props.push(`pressed=${node.pressed}`);

    // 判断元素是否可点击
    const clickableRoles = ['button', 'link', 'menuitem', 'tab', 'checkbox', 'radio', 'switch', 'option'];
    const isClickable = clickableRoles.includes(node.role) || 
                       node.focusable || 
                       node.role === 'generic' && node.name && node.focusable;
    if (isClickable) props.push('clickable');

    const indent = ' '.repeat(depth * 4);
    console.log(`${indent}[${currentId}] ${node.role} '${node.name || ''}'${props.length > 0 ? ' (' + props.join(', ') + ')' : ''}`);

    if (node.children && node.children.length > 0) {
      for (const child of node.children) {
        traverse(child, depth + 1, node);
      }
    }
  }

  // 输出 AXTree 的整体结构
  console.log('## AXTree:');
  // 打印根节点信息（这里用 Root+role 来模拟输出）
  let rootProps = [];
  if (axTree.focusable) rootProps.push('focusable=True');
  if (axTree.focused) rootProps.push('focused');
  console.log(`Root${axTree.role ? axTree.role : 'WebArea'} '${axTree.name || ''}'${rootProps.length > 0 ? ', ' + rootProps.join(', ') : ''}`);

  if (axTree.children && axTree.children.length > 0) {
    for (const child of axTree.children) {
      traverse(child, 1, axTree);
    }
  }

  // 输出编号与伪选择器的映射
  console.log('\n编号与 Selector 映射：');
  console.log(idToSelector);

  // 示例：后续可根据编号获取对应的 selector 进行操作
  // 比如要点击编号为 25 的节点：
  // const selectorForId25 = idToSelector[25];
  // await page.click(selectorForId25);
  //
  // 注意：上面的 selector 为伪生成示例，实际操作中需要根据页面结构生成能唯一定位该元素的 selector。

  await browser.close();
})();
