#!/usr/bin/env node

/**
 * Screenshot Generator for Infinite Agents Dashboard
 *
 * Automatically captures screenshots of all demos for preview thumbnails.
 * Uses Playwright to render each demo and save a screenshot.
 *
 * Installation:
 *   npm install -D playwright
 *   npx playwright install chromium
 *
 * Usage:
 *   node generate_screenshots.js
 *   node generate_screenshots.js --category threejs
 *   node generate_screenshots.js --single threejs_viz/threejs_viz_1.html
 */

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

// Demo categories and their file patterns
const DEMO_CATEGORIES = {
    threejs: {
        pattern: 'threejs_viz/threejs_viz_*.html',
        delay: 3000, // Extra time for WebGL to render
    },
    sdg: {
        pattern: 'sdg_viz/sdg_viz_*.html',
        delay: 2000,
    },
    d3: {
        pattern: 'd3_test/d3_viz_*.html',
        delay: 1500,
    },
    mapbox: {
        pattern: 'mapbox_test/mapbox_globe_*/index.html',
        delay: 3000, // Mapbox needs time to load tiles
    },
    claudeDevTools: {
        pattern: 'claude_code_devtools/claude_devtool_*.html',
        delay: 1000,
    },
    uiSingle: {
        pattern: 'src/ui_hybrid_*.html',
        delay: 800,
    },
    uiInfinite: {
        pattern: 'src_infinite/ui_hybrid_*.html',
        delay: 800,
    },
    uiModular: {
        pattern: 'src_group/ui_hybrid_*/index.html',
        delay: 800,
    },
    infiniteVariants: {
        pattern: 'infinite_variants/infinite_variant_*/test_output/*.html',
        delay: 1500, // Mixed content, some may have animations
    },
};

// Parse command line arguments
const args = process.argv.slice(2);
const categoryFilter = args.find(arg => arg.startsWith('--category='))?.split('=')[1];
const singleFile = args.find(arg => arg.startsWith('--single='))?.split('=')[1];
const PORT = args.find(arg => arg.startsWith('--port='))?.split('=')[1] || 8889;

// Create screenshots directory
const SCREENSHOTS_DIR = path.join(__dirname, 'screenshots');
if (!fs.existsSync(SCREENSHOTS_DIR)) {
    fs.mkdirSync(SCREENSHOTS_DIR, { recursive: true });
    console.log(`✅ Created screenshots directory: ${SCREENSHOTS_DIR}`);
}

// Scan directory for demo files
function scanDirectory(pattern) {
    const glob = require('glob');
    return glob.sync(pattern);
}

// Get all demo files
function getAllDemos() {
    const demos = [];

    for (const [category, config] of Object.entries(DEMO_CATEGORIES)) {
        if (categoryFilter && category !== categoryFilter) continue;

        const files = scanDirectory(config.pattern);
        files.forEach(file => {
            demos.push({
                path: file,
                category,
                delay: config.delay,
            });
        });
    }

    return demos;
}

// Capture screenshot for a single demo
async function captureScreenshot(browser, demo, index, total) {
    const page = await browser.newPage();

    try {
        // Set viewport size (desktop resolution)
        await page.setViewportSize({ width: 1920, height: 1080 });

        const url = `http://localhost:${PORT}/${demo.path}`;
        console.log(`\n📸 [${index + 1}/${total}] ${demo.path}`);

        // Navigate to demo
        await page.goto(url, {
            waitUntil: 'networkidle',
            timeout: 30000,
        });

        // Wait for demo to render
        await page.waitForTimeout(demo.delay);

        // Generate screenshot filename
        const screenshotFilename = demo.path.replace(/\//g, '_').replace('.html', '.png');
        const screenshotPath = path.join(SCREENSHOTS_DIR, screenshotFilename);

        // Capture screenshot
        await page.screenshot({
            path: screenshotPath,
            fullPage: false, // Just viewport, not entire scrollable page
        });

        console.log(`   ✅ Saved: ${screenshotFilename}`);

    } catch (error) {
        console.error(`   ❌ Failed: ${error.message}`);
    } finally {
        await page.close();
    }
}

// Main execution
async function main() {
    console.log('🚀 Infinite Agents Screenshot Generator\n');

    // Get demo files
    let demos;
    if (singleFile) {
        demos = [{
            path: singleFile,
            category: 'custom',
            delay: 2000,
        }];
    } else {
        demos = getAllDemos();
    }

    if (demos.length === 0) {
        console.error('❌ No demo files found!');
        console.log('\nMake sure:');
        console.log('  1. You are in the project root directory');
        console.log('  2. Demo files exist in their respective directories');
        console.log('  3. Category filter is correct (if using --category)');
        process.exit(1);
    }

    console.log(`📊 Found ${demos.length} demos to screenshot\n`);

    // Check if server is running
    console.log(`🔍 Checking if server is running on http://localhost:${PORT}...`);
    try {
        const http = require('http');
        await new Promise((resolve, reject) => {
            const req = http.get(`http://localhost:${PORT}`, (res) => {
                resolve();
            });
            req.on('error', reject);
            req.setTimeout(3000, () => reject(new Error('Timeout')));
        });
        console.log('   ✅ Server is running\n');
    } catch (error) {
        console.error('   ❌ Server is not running!');
        console.log(`\n🔧 Start the server first:`);
        console.log(`   python3 -m http.server ${PORT}\n`);
        process.exit(1);
    }

    // Launch browser
    console.log('🌐 Launching browser...');
    const browser = await chromium.launch({
        headless: true,
    });
    console.log('   ✅ Browser ready\n');

    // Capture screenshots
    console.log('📸 Capturing screenshots...');
    console.log('━'.repeat(50));

    for (let i = 0; i < demos.length; i++) {
        await captureScreenshot(browser, demos[i], i, demos.length);
    }

    // Cleanup
    await browser.close();

    console.log('\n' + '━'.repeat(50));
    console.log(`\n✨ Done! Captured ${demos.length} screenshots`);
    console.log(`📁 Screenshots saved to: ${SCREENSHOTS_DIR}\n`);
}

// Run
main().catch(error => {
    console.error('\n❌ Fatal error:', error);
    process.exit(1);
});
