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

(async () => {
    // 启动浏览器
    const browser = await chromium.launch({
        headless: true // 设置为有头模式，方便观察
    });
    const context = await browser.newContext();
    const page = await context.newPage();

    try {
        page.setViewportSize({ width: 2560, height: 1440 });

        // url = "https://play.grafana.org/a/grafana-app-observability-app"
        url = "https://play.grafana.org/dashboards"
        // url = "https://play.grafana.org/a/grafana-synthetic-monitoring-app/probes"

        // 访问目标网站，增加超时时间并添加重试逻辑
        console.log(`正在访问 ${url}...`);
        
        // 增加超时时间到 120 秒
        await page.goto(url, { 
            timeout: 120000,  // 增加到 120 秒
            waitUntil: 'domcontentloaded'  // 改为只等待 DOM 加载完成，不等待所有资源
        });
        
        console.log('页面加载完成');

        // 等待页面稳定
        try {
            await page.waitForLoadState('networkidle', { timeout: 30000 });
        } catch (e) {
            console.log('网络未完全空闲，但继续执行：', e.message);
        }

        
        // 展开所有折叠的部分
        console.log('\n开始展开导航项...');
        
        // 用 Set 来记录已经点击过的按钮
        const clickedButtons = new Set();
        
        const expandButtons = async () => {
            console.log('开始寻找可展开按钮...');
            // 查找所有折叠按钮
            const buttons = await page.$$('button[aria-label*="Expand"], button[aria-label*="Open"], button[aria-expanded="false"]');
            console.log(`找到 ${buttons.length} 个折叠按钮`);
            
            let newButtonsFound = false;
            
            for (const button of buttons) {
                try {
                    const ariaLabel = await button.getAttribute('aria-label');
                    // 检查按钮是否已经点击过
                    if (!clickedButtons.has(ariaLabel)) {
                        console.log(`点击新按钮: ${ariaLabel}`);
                        await button.click();
                        clickedButtons.add(ariaLabel);
                        newButtonsFound = true;
                        await page.waitForTimeout(200);
                    }
                } catch (e) {
                    console.log(`点击失败: ${e.message}`);
                }
            }
            
            return newButtonsFound;
        };
        
        // 持续查找和点击，直到没有新按钮
        let iteration = 1;
        while (true) {
            console.log(`\n第 ${iteration} 次查找...`);
            const foundNewButtons = await expandButtons();
            
            if (!foundNewButtons) {
                console.log('没有发现新的可展开按钮，结束查找');
                break;
            }
            
            console.log(`已点击按钮数量: ${clickedButtons.size}`);
            await page.waitForTimeout(500);
            iteration++;
        }

        // 确保截图目录存在
        const screenshotDir = path.join(__dirname, 'temp_screenshot');
        
        fs.rmSync(screenshotDir, { recursive: true, force: true });
        fs.mkdirSync(screenshotDir, { recursive: true });
        console.log(`创建截图目录: ${screenshotDir}`);

        const anchorHandles = await page.$$('a');
        console.log(`找到 ${anchorHandles.length} 个链接`);
        
        for (let i = 0; i < anchorHandles.length; i++) {
            try {
                const anchorHandle = anchorHandles[i];
                
                // 先获取 <a> 标签的 href 与文本内容
                const anchorData = await page.evaluate(el => {
                    return {
                        url: el.href,
                        text: el.innerText.trim()
                    };
                }, anchorHandle);
                
                // 生成文件名 (使用索引和文本内容的组合)
                let filename = `link_${i+1}_${anchorData.text}`;
                // 替换不合法的文件名字符
                filename = filename.replace(/[\\/:*?"<>|]/g, '_');
                // 限制文件名长度
                if (filename.length > 100) filename = filename.substring(0, 100);
                
                try {
                    // 使用更可靠的滚动方法
                    await page.evaluate(element => {
                        // 使用JavaScript的scrollIntoView，更直接且兼容性更好
                        element.scrollIntoView({behavior: 'smooth', block: 'center'});
                    }, anchorHandle);
                    
                    await page.waitForTimeout(500); // 给滚动和渲染更多时间

                    const rect = await anchorHandle.boundingBox();

                    filename = `${filename}_${rect.x}_${rect.y}_${rect.width}_${rect.height}.png`;
                    
                    // 截图并保存
                    const screenshotPath = path.join(screenshotDir, filename);
                    await page.screenshot({ path: screenshotPath });
                    
                    console.log(`处理链接 ${i+1}/${anchorHandles.length}: ${anchorData.text} - 已截图保存至 ${filename}`);
                } catch (scrollError) {
                    console.log(`处理链接 ${i+1}/${anchorHandles.length}: ${anchorData.text} - 滚动失败但尝试截图`);
                    // 即使滚动失败也尝试截图
                    try {
                        const screenshotPath = path.join(screenshotDir, filename);
                        await page.screenshot({ path: screenshotPath });
                    } catch (e) {
                        console.error(`截图失败: ${e.message}`);
                    }
                }
            } catch (error) {
                console.error(`处理第 ${i+1} 个链接时出错:`, error.message);
            }
        }
        
        console.log(`链接总数: ${anchorHandles.length}, 截图已保存到 ${screenshotDir}`);

        console.log('\n等待1000秒...');
        await page.waitForTimeout(1000 * 1000);

    } catch (error) {
        console.error('发生错误:', error);
    } finally {
        // 关闭浏览器
        await browser.close();
    }
})();