#!/usr/bin/env node
/**
 * Comprehensive Mobile Test - All Pages
 * Tests ALL pages in the LDR application across multiple mobile viewports
 *
 * Features:
 * - Tests 3 mobile viewports: 360px (small Android), 375px (iPhone SE), 430px (iPhone 14)
 * - Tests ALL pages including auth, settings subpages, metrics subpages
 * - Checks for horizontal overflow, mobile nav, sidebar, touch targets, text readability
 * - Takes screenshots of each page at each viewport
 * - Generates comprehensive summary report
 */

const puppeteer = require('puppeteer');
const AuthHelper = require('../auth_helper');
const { getPuppeteerLaunchOptions } = require('../puppeteer_config');
const path = require('path');
const fs = require('fs').promises;

// Test configuration
const CONFIG = {
    baseUrl: process.env.TEST_BASE_URL || 'http://127.0.0.1:5000',
    timeout: 30000,
    screenshotDir: path.join(__dirname, 'screenshots'),
};

// Mobile viewports to test
const VIEWPORTS = {
    'Android_360': { width: 360, height: 640, isMobile: true, hasTouch: true, label: 'Small Android (360px)' },
    'iPhone_SE': { width: 375, height: 667, isMobile: true, hasTouch: true, label: 'iPhone SE (375px)' },
    'iPhone_14': { width: 430, height: 932, isMobile: true, hasTouch: true, label: 'iPhone 14 (430px)' },
};

// ALL pages to test
const PAGES = [
    // Main pages
    { path: '/', name: 'Research', requiresAuth: true, category: 'Main' },
    { path: '/history/', name: 'History', requiresAuth: true, category: 'Main' },
    { path: '/news/', name: 'News', requiresAuth: true, category: 'Main' },
    { path: '/news/subscriptions', name: 'News-Subscriptions', requiresAuth: true, category: 'News' },

    // Settings pages
    { path: '/settings/', name: 'Settings', requiresAuth: true, category: 'Settings' },
    { path: '/settings/collections', name: 'Settings-Collections', requiresAuth: true, category: 'Settings' },
    { path: '/settings/embeddings', name: 'Settings-Embeddings', requiresAuth: true, category: 'Settings' },

    // Metrics pages
    { path: '/metrics/', name: 'Metrics', requiresAuth: true, category: 'Metrics' },
    { path: '/metrics/costs', name: 'Metrics-Costs', requiresAuth: true, category: 'Metrics' },
    { path: '/metrics/context-overflow', name: 'Metrics-ContextOverflow', requiresAuth: true, category: 'Metrics' },
    { path: '/metrics/star-reviews', name: 'Metrics-StarReviews', requiresAuth: true, category: 'Metrics' },

    // Other pages
    { path: '/benchmark/', name: 'Benchmark', requiresAuth: true, category: 'Other' },
    { path: '/library/', name: 'Library', requiresAuth: true, category: 'Other' },
    { path: '/library/download-manager', name: 'Library-DownloadManager', requiresAuth: true, category: 'Other' },

    // Auth pages
    { path: '/auth/login', name: 'Login', requiresAuth: false, category: 'Auth' },
    { path: '/auth/register', name: 'Register', requiresAuth: false, category: 'Auth' },
];

class ComprehensiveMobileTest {
    constructor() {
        this.results = {
            startTime: new Date(),
            viewportResults: {},
            pageResults: {},
            issues: [],
            screenshots: [],
            summary: {
                total: 0,
                passed: 0,
                failed: 0,
                warnings: 0,
                pagesTestedPerViewport: {},
                criticalIssues: [],
                viewportStats: {}
            }
        };
    }

    async run() {
        console.log('🚀 Comprehensive Mobile Test - All Pages');
        console.log('='.repeat(70));
        console.log(`Testing ${Object.keys(VIEWPORTS).length} viewports × ${PAGES.length} pages = ${Object.keys(VIEWPORTS).length * PAGES.length} tests`);
        console.log('='.repeat(70));

        let browser;
        try {
            // Ensure screenshot directory exists
            await fs.mkdir(CONFIG.screenshotDir, { recursive: true });

            browser = await puppeteer.launch(getPuppeteerLaunchOptions());

            for (const [deviceName, viewport] of Object.entries(VIEWPORTS)) {
                await this.testDevice(browser, deviceName, viewport);
            }

            await this.generateReport();

            // Exit with error code if there are failed tests
            process.exit(this.results.summary.failed > 0 ? 1 : 0);

        } catch (error) {
            console.error('❌ Test suite failed:', error);
            process.exit(1);
        } finally {
            if (browser) await browser.close();
        }
    }

    async testDevice(browser, deviceName, viewport) {
        console.log(`\n${'='.repeat(70)}`);
        console.log(`📱 Testing ${viewport.label}`);
        console.log(`${'='.repeat(70)}`);

        this.results.viewportResults[deviceName] = {
            viewport: viewport.label,
            tests: [],
            passed: 0,
            failed: 0,
            warnings: 0
        };

        const page = await browser.newPage();
        await page.setViewport(viewport);

        // Authenticate for auth-required pages
        const authHelper = new AuthHelper(page, CONFIG.baseUrl);
        let authenticated = false;
        try {
            await authHelper.ensureAuthenticated();
            authenticated = true;
            console.log('✅ Authentication successful\n');
        } catch (error) {
            console.log('⚠️  Authentication failed, testing unauthenticated pages only\n');
        }

        // Test each page
        for (const pageInfo of PAGES) {
            if (pageInfo.requiresAuth && !authenticated) {
                console.log(`  ⏭️  Skipping ${pageInfo.name} (requires auth)`);
                continue;
            }
            await this.testPage(page, deviceName, viewport, pageInfo);
        }

        await page.close();

        // Display viewport summary
        const vpResult = this.results.viewportResults[deviceName];
        console.log(`\n${'─'.repeat(70)}`);
        console.log(`${viewport.label} Summary: ${vpResult.passed}/${vpResult.tests.length} passed, ${vpResult.failed} failed, ${vpResult.warnings} warnings`);
        console.log(`${'─'.repeat(70)}`);
    }

    async testPage(page, deviceName, viewport, pageInfo) {
        const testName = `${deviceName}/${pageInfo.name}`;
        const startTime = Date.now();

        try {
            // Navigate to page
            await page.goto(CONFIG.baseUrl + pageInfo.path, {
                waitUntil: 'networkidle2',
                timeout: CONFIG.timeout
            });

            // Wait for page to settle
            await new Promise(resolve => setTimeout(resolve, 1500));

            // Take screenshot
            const screenshotName = `${deviceName}_${pageInfo.name}.png`;
            const screenshotPath = path.join(CONFIG.screenshotDir, screenshotName);
            await page.screenshot({
                path: screenshotPath,
                fullPage: true
            });
            this.results.screenshots.push({
                viewport: deviceName,
                page: pageInfo.name,
                path: screenshotPath
            });

            // Run comprehensive checks
            const checks = await page.evaluate(() => {
                const results = {
                    horizontalOverflow: false,
                    overflowAmount: 0,
                    mobileNavExists: false,
                    mobileNavVisible: false,
                    sidebarHidden: true,
                    smallTouchTargets: 0,
                    touchTargetDetails: [],
                    textReadability: {
                        tooSmall: 0,
                        elements: []
                    },
                    viewportWidth: window.innerWidth,
                    scrollWidth: document.body.scrollWidth,
                    errors: [],
                    warnings: []
                };

                // 1. Check horizontal overflow (CRITICAL)
                const threshold = 5; // Allow 5px tolerance
                if (document.body.scrollWidth > window.innerWidth + threshold) {
                    results.horizontalOverflow = true;
                    results.overflowAmount = document.body.scrollWidth - window.innerWidth;
                    results.errors.push(`Horizontal overflow: ${results.overflowAmount}px beyond viewport`);
                }

                // 2. Check mobile navigation visibility
                const mobileNav = document.querySelector('.ldr-mobile-bottom-nav');
                results.mobileNavExists = !!mobileNav;
                if (mobileNav) {
                    const style = window.getComputedStyle(mobileNav);
                    results.mobileNavVisible = style.display !== 'none' &&
                        mobileNav.classList.contains('visible');
                }

                // 3. Check sidebar hidden on mobile
                const sidebar = document.querySelector('.ldr-sidebar');
                if (sidebar) {
                    const style = window.getComputedStyle(sidebar);
                    results.sidebarHidden = style.display === 'none' ||
                        style.visibility === 'hidden' ||
                        parseFloat(style.opacity) === 0;

                    if (!results.sidebarHidden && window.innerWidth <= 768) {
                        results.errors.push('Desktop sidebar visible on mobile viewport');
                    }
                }

                // 4. Check touch target sizes (minimum 44x44px recommended)
                const interactiveSelectors = [
                    'button:not([disabled])',
                    'a:not([disabled])',
                    'input[type="button"]:not([disabled])',
                    'input[type="submit"]:not([disabled])',
                    '.ldr-mobile-nav-tab',
                    '[role="button"]'
                ];

                document.querySelectorAll(interactiveSelectors.join(', ')).forEach(el => {
                    const rect = el.getBoundingClientRect();
                    // Only check visible elements
                    if (rect.width > 0 && rect.height > 0) {
                        const minDimension = Math.min(rect.width, rect.height);
                        if (minDimension < 44) {
                            results.smallTouchTargets++;
                            if (results.touchTargetDetails.length < 5) { // Limit details to first 5
                                const identifier = el.id || el.className || el.tagName;
                                results.touchTargetDetails.push({
                                    element: identifier.substring(0, 50),
                                    size: `${Math.round(rect.width)}×${Math.round(rect.height)}px`
                                });
                            }
                        }
                    }
                });

                // 5. Check text readability (minimum 16px for body text)
                const textElements = document.querySelectorAll('p, li, span, div, td, th, label');
                textElements.forEach(el => {
                    const style = window.getComputedStyle(el);
                    const fontSize = parseFloat(style.fontSize);
                    const hasText = el.textContent.trim().length > 20; // Only check substantial text

                    if (hasText && fontSize < 14) {
                        results.textReadability.tooSmall++;
                        if (results.textReadability.elements.length < 3) {
                            results.textReadability.elements.push({
                                size: `${fontSize}px`,
                                text: el.textContent.substring(0, 30) + '...'
                            });
                        }
                    }
                });

                // Add warnings
                if (results.smallTouchTargets > 5) {
                    results.warnings.push(`${results.smallTouchTargets} touch targets < 44px`);
                }
                if (results.textReadability.tooSmall > 0) {
                    results.warnings.push(`${results.textReadability.tooSmall} text elements < 14px`);
                }

                return results;
            });

            // Analyze results
            const testResult = {
                name: testName,
                page: pageInfo.name,
                path: pageInfo.path,
                viewport: deviceName,
                status: 'passed',
                issues: [],
                warnings: [],
                checks: checks,
                duration: (Date.now() - startTime) / 1000,
                screenshot: screenshotName
            };

            // Critical issues (fail test)
            if (checks.horizontalOverflow) {
                testResult.status = 'failed';
                testResult.issues.push(`❌ CRITICAL: Horizontal overflow (${checks.overflowAmount}px)`);
                this.results.issues.push({
                    severity: 'critical',
                    page: pageInfo.name,
                    viewport: deviceName,
                    issue: `Horizontal overflow: ${checks.overflowAmount}px`
                });
            }

            // Check mobile nav visibility (only for authenticated pages, not auth pages)
            if (pageInfo.requiresAuth && !pageInfo.path.includes('/auth/')) {
                const currentUrl = page.url();
                // Only require mobile nav if we're actually on the page (not redirected to login)
                if (!currentUrl.includes('/auth/') && !checks.mobileNavVisible) {
                    testResult.status = 'failed';
                    testResult.issues.push('❌ CRITICAL: Mobile navigation not visible');
                    this.results.issues.push({
                        severity: 'critical',
                        page: pageInfo.name,
                        viewport: deviceName,
                        issue: 'Mobile navigation not visible'
                    });
                }
            }

            if (!checks.sidebarHidden) {
                testResult.status = 'failed';
                testResult.issues.push('❌ CRITICAL: Desktop sidebar visible on mobile');
                this.results.issues.push({
                    severity: 'critical',
                    page: pageInfo.name,
                    viewport: deviceName,
                    issue: 'Desktop sidebar visible'
                });
            }

            // Warnings (don't fail test)
            if (checks.smallTouchTargets > 10) {
                testResult.warnings.push(`⚠️  ${checks.smallTouchTargets} small touch targets (< 44px)`);
                if (checks.touchTargetDetails.length > 0) {
                    testResult.warnings.push(`   Examples: ${checks.touchTargetDetails.map(t => `${t.element} ${t.size}`).join(', ')}`);
                }
            }

            if (checks.textReadability.tooSmall > 5) {
                testResult.warnings.push(`⚠️  ${checks.textReadability.tooSmall} text elements too small (< 14px)`);
            }

            // Update counters
            this.results.summary.total++;
            if (testResult.status === 'passed') {
                this.results.summary.passed++;
                this.results.viewportResults[deviceName].passed++;
            } else {
                this.results.summary.failed++;
                this.results.viewportResults[deviceName].failed++;
            }

            if (testResult.warnings.length > 0) {
                this.results.summary.warnings++;
                this.results.viewportResults[deviceName].warnings++;
            }

            // Store result
            this.results.viewportResults[deviceName].tests.push(testResult);

            if (!this.results.pageResults[pageInfo.name]) {
                this.results.pageResults[pageInfo.name] = [];
            }
            this.results.pageResults[pageInfo.name].push(testResult);

            // Display result
            const status = testResult.status === 'passed' ? '✅' : '❌';
            const category = pageInfo.category ? `[${pageInfo.category}]` : '';
            console.log(`  ${status} ${category} ${pageInfo.name.padEnd(30)} | ${checks.viewportWidth}×${checks.scrollWidth}px`);

            if (testResult.issues.length > 0) {
                testResult.issues.forEach(issue => console.log(`      ${issue}`));
            }
            if (testResult.warnings.length > 0) {
                testResult.warnings.forEach(warning => console.log(`      ${warning}`));
            }

        } catch (error) {
            this.results.summary.total++;
            this.results.summary.failed++;
            this.results.viewportResults[deviceName].failed++;

            const errorResult = {
                name: testName,
                page: pageInfo.name,
                path: pageInfo.path,
                viewport: deviceName,
                status: 'failed',
                issues: [`❌ ERROR: ${error.message}`],
                warnings: [],
                duration: (Date.now() - startTime) / 1000
            };

            this.results.viewportResults[deviceName].tests.push(errorResult);
            console.log(`  ❌ ${pageInfo.name} - ERROR: ${error.message}`);
        }
    }

    async generateReport() {
        this.results.endTime = new Date();
        this.results.duration = (this.results.endTime - this.results.startTime) / 1000;

        console.log('\n' + '='.repeat(70));
        console.log('📊 COMPREHENSIVE TEST REPORT');
        console.log('='.repeat(70));

        // Overall summary
        console.log('\n📈 Overall Summary:');
        console.log(`   Total Tests: ${this.results.summary.total}`);
        console.log(`   ✅ Passed: ${this.results.summary.passed}`);
        console.log(`   ❌ Failed: ${this.results.summary.failed}`);
        console.log(`   ⚠️  Warnings: ${this.results.summary.warnings}`);
        console.log(`   ⏱️  Duration: ${this.results.duration.toFixed(2)}s`);
        console.log(`   📸 Screenshots: ${this.results.screenshots.length}`);

        // Viewport breakdown
        console.log('\n📱 Viewport Breakdown:');
        for (const [deviceName, vpResult] of Object.entries(this.results.viewportResults)) {
            const passRate = vpResult.tests.length > 0
                ? ((vpResult.passed / vpResult.tests.length) * 100).toFixed(1)
                : 0;
            console.log(`   ${VIEWPORTS[deviceName].label}:`);
            console.log(`      ${vpResult.passed}/${vpResult.tests.length} passed (${passRate}%) | ${vpResult.failed} failed | ${vpResult.warnings} warnings`);
        }

        // Critical issues
        if (this.results.summary.failed > 0) {
            console.log('\n❌ CRITICAL ISSUES:');
            const criticalIssues = this.results.issues.filter(i => i.severity === 'critical');

            // Group by issue type
            const issuesByType = {};
            criticalIssues.forEach(issue => {
                const type = issue.issue.split(':')[0];
                if (!issuesByType[type]) {
                    issuesByType[type] = [];
                }
                issuesByType[type].push(issue);
            });

            for (const [type, issues] of Object.entries(issuesByType)) {
                console.log(`\n   ${type}:`);
                issues.forEach(issue => {
                    console.log(`      - ${issue.page} @ ${issue.viewport}: ${issue.issue}`);
                });
            }
        }

        // Failed pages
        if (this.results.summary.failed > 0) {
            console.log('\n🚨 Failed Pages:');
            for (const [pageName, results] of Object.entries(this.results.pageResults)) {
                const failed = results.filter(r => r.status === 'failed');
                if (failed.length > 0) {
                    console.log(`   ${pageName}:`);
                    failed.forEach(r => {
                        console.log(`      - ${VIEWPORTS[r.viewport].label}: ${r.issues.join(', ')}`);
                    });
                }
            }
        }

        // Page category summary
        console.log('\n📑 Page Category Summary:');
        const categorySummary = {};
        for (const page of PAGES) {
            if (!categorySummary[page.category]) {
                categorySummary[page.category] = { total: 0, passed: 0, failed: 0 };
            }
            const pageResults = this.results.pageResults[page.name] || [];
            pageResults.forEach(r => {
                categorySummary[page.category].total++;
                if (r.status === 'passed') {
                    categorySummary[page.category].passed++;
                } else {
                    categorySummary[page.category].failed++;
                }
            });
        }

        for (const [category, stats] of Object.entries(categorySummary)) {
            const passRate = stats.total > 0 ? ((stats.passed / stats.total) * 100).toFixed(1) : 0;
            console.log(`   ${category}: ${stats.passed}/${stats.total} passed (${passRate}%)`);
        }

        // Screenshot info
        console.log(`\n📸 Screenshots saved to: ${CONFIG.screenshotDir}/`);
        console.log(`   Total screenshots: ${this.results.screenshots.length}`);

        // Save detailed JSON report
        const reportPath = path.join(__dirname, 'mobile-test-report.json');
        await fs.writeFile(reportPath, JSON.stringify(this.results, null, 2));
        console.log(`\n💾 Detailed report saved to: ${reportPath}`);

        // Generate HTML report
        await this.generateHtmlReport();

        console.log('\n' + '='.repeat(70));
        if (this.results.summary.failed === 0) {
            console.log('🎉 ALL TESTS PASSED!');
        } else {
            console.log(`⚠️  ${this.results.summary.failed} TEST(S) FAILED`);
        }
        console.log('='.repeat(70) + '\n');
    }

    async generateHtmlReport() {
        const html = `<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mobile Test Report - ${new Date().toLocaleDateString()}</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; padding: 20px; background: #f5f5f5; }
        .container { max-width: 1400px; margin: 0 auto; background: white; padding: 30px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
        h1 { color: #333; margin-bottom: 20px; }
        h2 { color: #555; margin: 30px 0 15px; padding-bottom: 10px; border-bottom: 2px solid #eee; }
        h3 { color: #666; margin: 20px 0 10px; }
        .summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin: 20px 0; }
        .stat-card { padding: 20px; border-radius: 6px; background: #f8f9fa; }
        .stat-card.passed { border-left: 4px solid #28a745; }
        .stat-card.failed { border-left: 4px solid #dc3545; }
        .stat-card.warning { border-left: 4px solid #ffc107; }
        .stat-label { font-size: 14px; color: #666; margin-bottom: 5px; }
        .stat-value { font-size: 32px; font-weight: bold; color: #333; }
        .viewport-results { margin: 20px 0; }
        .viewport { margin-bottom: 30px; padding: 20px; background: #f8f9fa; border-radius: 6px; }
        .test-grid { display: grid; gap: 15px; margin-top: 15px; }
        .test-item { padding: 15px; background: white; border-radius: 4px; border-left: 4px solid #28a745; }
        .test-item.failed { border-left-color: #dc3545; }
        .test-item.warning { border-left-color: #ffc107; }
        .test-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
        .test-name { font-weight: 600; color: #333; }
        .test-status { padding: 4px 12px; border-radius: 4px; font-size: 12px; font-weight: 600; }
        .test-status.passed { background: #d4edda; color: #155724; }
        .test-status.failed { background: #f8d7da; color: #721c24; }
        .test-details { font-size: 14px; color: #666; margin-top: 8px; }
        .issue { color: #dc3545; margin-top: 5px; }
        .warning { color: #ffc107; margin-top: 5px; }
        .screenshot-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; margin: 20px 0; }
        .screenshot { border: 1px solid #ddd; border-radius: 4px; padding: 10px; background: white; }
        .screenshot img { width: 100%; border-radius: 4px; }
        .screenshot-label { text-align: center; margin-top: 8px; font-size: 12px; color: #666; }
        .category-summary { display: grid; gap: 10px; }
        .category-item { padding: 12px; background: #f8f9fa; border-radius: 4px; display: flex; justify-content: space-between; align-items: center; }
        .progress-bar { width: 200px; height: 20px; background: #e9ecef; border-radius: 10px; overflow: hidden; }
        .progress-fill { height: 100%; background: #28a745; transition: width 0.3s; }
    </style>
</head>
<body>
    <div class="container">
        <h1>📱 Mobile Test Report</h1>
        <p style="color: #666; margin-bottom: 20px;">Generated on ${new Date().toLocaleString()}</p>

        <h2>📈 Overall Summary</h2>
        <div class="summary">
            <div class="stat-card">
                <div class="stat-label">Total Tests</div>
                <div class="stat-value">${this.results.summary.total}</div>
            </div>
            <div class="stat-card passed">
                <div class="stat-label">Passed</div>
                <div class="stat-value">${this.results.summary.passed}</div>
            </div>
            <div class="stat-card failed">
                <div class="stat-label">Failed</div>
                <div class="stat-value">${this.results.summary.failed}</div>
            </div>
            <div class="stat-card warning">
                <div class="stat-label">Warnings</div>
                <div class="stat-value">${this.results.summary.warnings}</div>
            </div>
            <div class="stat-card">
                <div class="stat-label">Duration</div>
                <div class="stat-value">${this.results.duration.toFixed(1)}s</div>
            </div>
            <div class="stat-card">
                <div class="stat-label">Screenshots</div>
                <div class="stat-value">${this.results.screenshots.length}</div>
            </div>
        </div>

        <h2>📱 Viewport Results</h2>
        <div class="viewport-results">
            ${Object.entries(this.results.viewportResults).map(([deviceName, vpResult]) => `
                <div class="viewport">
                    <h3>${VIEWPORTS[deviceName].label} (${VIEWPORTS[deviceName].width}px)</h3>
                    <p style="margin: 10px 0;">
                        <strong>${vpResult.passed}/${vpResult.tests.length}</strong> tests passed
                        (${vpResult.tests.length > 0 ? ((vpResult.passed / vpResult.tests.length) * 100).toFixed(1) : 0}%)
                    </p>
                    <div class="test-grid">
                        ${vpResult.tests.map(test => `
                            <div class="test-item ${test.status} ${test.warnings.length > 0 ? 'warning' : ''}">
                                <div class="test-header">
                                    <span class="test-name">${test.page}</span>
                                    <span class="test-status ${test.status}">${test.status.toUpperCase()}</span>
                                </div>
                                <div class="test-details">
                                    <div>Path: ${test.path}</div>
                                    <div>Duration: ${test.duration.toFixed(2)}s</div>
                                    ${test.screenshot ? `<div>Screenshot: ${test.screenshot}</div>` : ''}
                                    ${test.issues.length > 0 ? test.issues.map(issue => `<div class="issue">${issue}</div>`).join('') : ''}
                                    ${test.warnings.length > 0 ? test.warnings.map(warning => `<div class="warning">${warning}</div>`).join('') : ''}
                                </div>
                            </div>
                        `).join('')}
                    </div>
                </div>
            `).join('')}
        </div>

        <h2>📑 Page Category Summary</h2>
        <div class="category-summary">
            ${(() => {
                const categorySummary = {};
                for (const page of PAGES) {
                    if (!categorySummary[page.category]) {
                        categorySummary[page.category] = { total: 0, passed: 0, failed: 0 };
                    }
                    const pageResults = this.results.pageResults[page.name] || [];
                    pageResults.forEach(r => {
                        categorySummary[page.category].total++;
                        if (r.status === 'passed') {
                            categorySummary[page.category].passed++;
                        } else {
                            categorySummary[page.category].failed++;
                        }
                    });
                }
                return Object.entries(categorySummary).map(([category, stats]) => {
                    const passRate = stats.total > 0 ? ((stats.passed / stats.total) * 100) : 0;
                    return `
                        <div class="category-item">
                            <div>
                                <strong>${category}</strong>
                                <div style="font-size: 14px; color: #666;">${stats.passed}/${stats.total} passed</div>
                            </div>
                            <div class="progress-bar">
                                <div class="progress-fill" style="width: ${passRate}%"></div>
                            </div>
                        </div>
                    `;
                }).join('');
            })()}
        </div>

        ${this.results.summary.failed > 0 ? `
            <h2>❌ Critical Issues</h2>
            <div style="background: #f8d7da; padding: 15px; border-radius: 6px; border-left: 4px solid #dc3545;">
                ${this.results.issues.map(issue => `
                    <div style="margin: 8px 0;">
                        <strong>${issue.page}</strong> @ ${issue.viewport}: ${issue.issue}
                    </div>
                `).join('')}
            </div>
        ` : ''}

        <h2>📸 Screenshots</h2>
        <p style="color: #666; margin-bottom: 15px;">All screenshots saved to: ${CONFIG.screenshotDir}/</p>
        <p style="color: #666;">Total screenshots: ${this.results.screenshots.length}</p>
    </div>
</body>
</html>`;

        const htmlPath = path.join(__dirname, 'mobile-test-report.html');
        await fs.writeFile(htmlPath, html);
        console.log(`📄 HTML report saved to: ${htmlPath}`);
    }
}

// Run
const test = new ComprehensiveMobileTest();
test.run();
