/**
 * Puppeteer configuration helper for CI/Docker environments
 */

const { createSeededChromeProfile } = require('../shared/chrome_profile');

const isCI = !!process.env.CI;

// Lazy + memoized seeded profile, mirroring BROWSER_CONFIG.userDataDir in
// browser_config.js: create the throwaway dir once and reuse it for every
// launch in this process, so re-invoking getPuppeteerLaunchOptions()
// doesn't strand an extra profile dir until exit.
let seededProfileDir = null;
function getSeededProfileDir() {
    if (!seededProfileDir) {
        seededProfileDir = createSeededChromeProfile();
    }
    return seededProfileDir;
}

/**
 * Take a screenshot only if not in CI mode
 * @param {Page} page - Puppeteer page object
 * @param {string} filepath - Path to save screenshot
 * @param {Object} options - Screenshot options
 * @returns {Promise<void>}
 */
async function takeScreenshot(page, filepath, options = {}) {
    if (isCI) {
        // Skip screenshots in CI to avoid timeouts and save resources
        return;
    }
    try {
        await page.screenshot({ path: filepath, ...options });
        console.log(`📸 Screenshot saved to ${filepath}`);
    } catch (error) {
        console.log(`⚠️  Could not take screenshot: ${error.message}`);
    }
}

function getPuppeteerLaunchOptions(additionalOptions = {}) {
    const defaultOptions = {
        headless: true,
        // Seeded profile that disables Chrome's password leak detection.
        // Without it, logging in with the CI credentials triggers an
        // invisible tab-modal "data breach" dialog that eats all real
        // CDP keyboard/mouse input for the rest of the tab's life — see
        // tests/shared/chrome_profile.js and issue #4430. Only created
        // when the caller doesn't bring their own profile dir.
        ...(additionalOptions.userDataDir
            ? {}
            : { userDataDir: getSeededProfileDir() }),
        // Protocol timeout needs to be long enough for registration flow
        // which creates encrypted DB, derives key, creates tables, and imports 500+ settings
        // This can take 60+ seconds in CI environments
        protocolTimeout: 600000, // 10 minutes - prevents "Runtime.callFunctionOn timed out"
        args: [
            '--no-sandbox',
            '--disable-setuid-sandbox',
            '--disable-dev-shm-usage',
            '--disable-accelerated-2d-canvas',
            '--no-first-run',
            '--no-zygote',
            '--disable-gpu',
            '--disable-features=site-per-process',
            '--disable-background-timer-throttling',
            '--disable-renderer-backgrounding',
            '--disable-backgrounding-occluded-windows'
        ]
    };

    // In Docker/CI environments, explicitly skip Chrome download and use system Chrome/Chromium
    if (process.env.CI || process.env.DOCKER_ENV) {
        console.log('🔍 Detecting Chrome/Chromium in CI/Docker environment...');
        console.log(`📊 Environment Variables:`);
        console.log(`  - CI=${process.env.CI}`);
        console.log(`  - DOCKER_ENV=${process.env.DOCKER_ENV}`);
        console.log(`  - PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=${process.env.PUPPETEER_SKIP_CHROMIUM_DOWNLOAD}`);
        console.log(`  - PUPPETEER_CACHE_DIR=${process.env.PUPPETEER_CACHE_DIR}`);
        console.log(`  - CHROME_BIN=${process.env.CHROME_BIN}`);

        const { execSync } = require('child_process');
        const fs = require('fs');

        // Check if CHROME_BIN is set and valid
        if (process.env.CHROME_BIN && fs.existsSync(process.env.CHROME_BIN)) {
            console.log(`✅ Using CHROME_BIN environment variable: ${process.env.CHROME_BIN}`);
            defaultOptions.executablePath = process.env.CHROME_BIN;
            return { ...defaultOptions, ...additionalOptions };
        }

        // Try to use Playwright's Chromium if available
        const possiblePaths = [
            '/root/.cache/ms-playwright/chromium-*/chrome-linux/chrome',
            '/ms-playwright/chromium-*/chrome-linux/chrome',
            '/usr/lib/chromium/chromium',
            '/usr/bin/chromium-browser',
            '/usr/bin/chromium',
            '/usr/bin/google-chrome',
            '/usr/bin/google-chrome-stable',
            // Add puppeteer cache paths
            '/app/puppeteer-cache/chrome/linux-*/chrome-linux/chrome',
            '/root/.cache/puppeteer/chrome/linux-*/chrome-linux/chrome'
        ];

        console.log('📂 Searching for Chrome/Chromium binaries...');

        // First, check common directories for any chrome/chromium executables
        console.log('🔎 Checking for Chrome/Chromium in common locations:');
        try {
            const findResults = execSync('find /usr/bin /usr/lib /opt -name "*chrom*" -type f -executable 2>/dev/null | head -10', { encoding: 'utf8' }).trim();
            if (findResults) {
                console.log('  Found executables:');
                findResults.split('\n').forEach(path => console.log(`    - ${path}`));
            }
        } catch {
            console.log('  Could not search /usr directories');
        }

        // Check Playwright cache locations
        console.log('🎭 Checking Playwright cache locations:');
        const playwrightDirs = ['/root/.cache/ms-playwright', '/ms-playwright', '/.cache/ms-playwright'];
        for (const dir of playwrightDirs) {
            try {
                if (fs.existsSync(dir)) {
                    console.log(`  📁 Found Playwright cache dir: ${dir}`);
                    const contents = execSync(`ls -la ${dir} 2>/dev/null | head -5`, { encoding: 'utf8' }).trim();
                    if (contents) {
                        console.log(`    Contents: ${contents.split('\n')[0]}`);
                    }

                    // Try to find chrome executable
                    const chromePath = execSync(`find ${dir} -name chrome -type f 2>/dev/null | head -1`, { encoding: 'utf8' }).trim();
                    if (chromePath && fs.existsSync(chromePath)) {
                        console.log(`  ✅ Found Playwright Chrome at: ${chromePath}`);
                        defaultOptions.executablePath = chromePath;
                        break;
                    }
                } else {
                    console.log(`  ❌ Directory not found: ${dir}`);
                }
            } catch (e) {
                console.log(`  ⚠️ Error checking ${dir}: ${e.message}`);
            }
        }

        // Check Puppeteer cache locations
        if (!defaultOptions.executablePath) {
            console.log('🐶 Checking Puppeteer cache locations:');
            const puppeteerDirs = [
                process.env.PUPPETEER_CACHE_DIR || '/app/puppeteer-cache',
                '/root/.cache/puppeteer',
                '/.cache/puppeteer'
            ];

            for (const dir of puppeteerDirs) {
                try {
                    if (fs.existsSync(dir)) {
                        console.log(`  📁 Found Puppeteer cache dir: ${dir}`);
                        const chromePath = execSync(`find ${dir} -name chrome -type f 2>/dev/null | head -1`, { encoding: 'utf8' }).trim();
                        if (chromePath && fs.existsSync(chromePath)) {
                            console.log(`  ✅ Found Puppeteer Chrome at: ${chromePath}`);
                            defaultOptions.executablePath = chromePath;
                            break;
                        }
                    } else {
                        console.log(`  ❌ Directory not found: ${dir}`);
                    }
                } catch (e) {
                    console.log(`  ⚠️ Error checking ${dir}: ${e.message}`);
                }
            }
        }

        // Fall back to checking specific paths
        if (!defaultOptions.executablePath) {
            console.log('🔍 Checking standard Chrome/Chromium paths:');
            for (const pathPattern of possiblePaths) {
                try {
                    const chromiumPath = execSync(`ls ${pathPattern} 2>/dev/null | head -1`, { encoding: 'utf8' }).trim();
                    if (chromiumPath && chromiumPath.length > 0 && fs.existsSync(chromiumPath)) {
                        console.log(`  ✅ Found at: ${chromiumPath}`);
                        // Verify it's executable
                        const stats = fs.statSync(chromiumPath);
                        if (stats.mode & fs.constants.S_IXUSR) {
                            defaultOptions.executablePath = chromiumPath;
                            break;
                        } else {
                            console.log(`    ⚠️ File exists but is not executable`);
                        }
                    }
                } catch {
                    // Silent fail for glob patterns
                }
            }
        }

        if (!defaultOptions.executablePath) {
            console.warn('⚠️ Could not find Chrome/Chromium binary in standard locations');
            console.warn('📋 Debug Information:');
            console.warn(`  - Current working directory: ${process.cwd()}`);
            console.warn(`  - PATH: ${process.env.PATH}`);
            console.warn(`  - Chrome-related env vars:`, Object.keys(process.env).filter(k => k.includes('CHROME') || k.includes('PUPPETEER')));

            // In CI, try to use Puppeteer's bundled Chrome as last resort
            if (process.env.CI) {
                console.log('🚨 CI Mode: Attempting to use Puppeteer\'s bundled Chrome...');
                console.log('  Note: This requires PUPPETEER_SKIP_CHROMIUM_DOWNLOAD to be unset or false');

                // Don't exit, let Puppeteer try to use its own Chrome
                console.log('  Proceeding without explicit executablePath - Puppeteer will use its bundled Chrome');
                // Remove the explicit failure, let Puppeteer handle it
            }
        } else {
            console.log(`🚀 Will launch Puppeteer with executable: ${defaultOptions.executablePath}`);
        }
    }

    return { ...defaultOptions, ...additionalOptions };
}

module.exports = { getPuppeteerLaunchOptions, takeScreenshot, isCI };
