/**
 * Settings Form Validation Test
 * Tests that settings form inputs validate correctly
 * CI-compatible: Works in both local and CI environments
 */

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

// NAVIGATION NOTE: Using 'domcontentloaded' instead of 'networkidle2' for page.goto()
// because networkidle2 waits for no network activity for 500ms, but WebSocket
// connections and background polling keep the network active, causing infinite hangs.
// See: test_login_validation.js and auth_helper.js for detailed explanation.
async function testSettingsValidation() {
    const isCI = !!process.env.CI;
    const testTimer = new Timer('test_settings_validation');
    console.log(`🧪 Running settings validation test (CI mode: ${isCI})`);
    // Create screenshots directory if it doesn't exist
    const screenshotsDir = path.join(__dirname, 'screenshots');
    if (!fs.existsSync(screenshotsDir)) {
        fs.mkdirSync(screenshotsDir, { recursive: true });
    }

    const browser = await puppeteer.launch(getPuppeteerLaunchOptions());
    const page = await browser.newPage();
    const baseUrl = 'http://127.0.0.1:5000';

    // Increase default timeout in CI
    if (isCI) {
        page.setDefaultTimeout(60000);
        page.setDefaultNavigationTimeout(60000);
    }

    let testsPassed = 0;
    let testsFailed = 0;

    console.log('🧪 Starting settings validation tests...\n');

    try {
        // Authenticate (CI uses pre-created user for speed)
        console.log('📋 Setup: Authenticating...');
        const authHelper = new AuthHelper(page, baseUrl);

        try {
            // Use ensureAuthenticated which tries CI user first, then falls back to registration
            await authHelper.ensureAuthenticatedWithTimeout();
            console.log('✅ Authenticated\n');
        } catch (authError) {
            console.log(`⚠️  Could not authenticate: ${authError.message}`);
            console.log('❌ Cannot authenticate - skipping settings tests');
            await browser.close();
            testTimer.summary();
            process.exit(1);
        }

        // Navigate to settings page
        console.log('📄 Navigating to settings page...');
        await page.goto(`${baseUrl}/settings/`, {
            waitUntil: 'domcontentloaded',
            timeout: 30000
        });

        const currentUrl = page.url();
        if (!currentUrl.includes('/settings')) {
            console.log(`❌ Could not access settings page, redirected to: ${currentUrl}`);
            throw new Error('Cannot access settings page');
        }
        console.log('✅ Settings page loaded\n');

        // Test 1: Page loads without JavaScript errors
        console.log('📋 Test 1: Settings page loads without JS errors');

        // Check for console errors
        const consoleErrors = [];
        page.on('console', msg => {
            if (msg.type() === 'error') {
                consoleErrors.push(msg.text());
            }
        });

        // Wait a moment for any delayed JS to run
        await new Promise(resolve => setTimeout(resolve, 2000));

        if (consoleErrors.length === 0) {
            console.log('✅ No JavaScript console errors detected');
            testsPassed++;
        } else {
            console.log(`⚠️  ${consoleErrors.length} console error(s) detected:`);
            consoleErrors.slice(0, 3).forEach(err => console.log(`   - ${err.substring(0, 80)}`));
            // Don't fail - some console errors might be acceptable
        }

        // Test 2: Check for number inputs with validation
        console.log('\n📋 Test 2: Number inputs have min/max attributes');

        const numberInputs = await page.$$('input[type="number"]');
        console.log(`   Found ${numberInputs.length} number inputs`);

        let inputsWithValidation = 0;
        for (const input of numberInputs.slice(0, 5)) { // Check first 5
            const attrs = await page.evaluate(el => ({
                name: el.name || el.id,
                min: el.min,
                max: el.max,
                step: el.step
            }), input);

            if (attrs.min || attrs.max) {
                inputsWithValidation++;
                console.log(`   ✓ "${attrs.name}" has min=${attrs.min} max=${attrs.max}`);
            }
        }

        if (inputsWithValidation > 0 || numberInputs.length === 0) {
            console.log('✅ Number inputs have validation attributes');
            testsPassed++;
        } else {
            console.log('⚠️  Number inputs may lack validation attributes');
        }

        // Test 3: Settings form exists and has inputs
        console.log('\n📋 Test 3: Settings form structure');

        const formInputs = await page.$$('input, select, textarea');
        console.log(`   Found ${formInputs.length} form inputs`);

        if (formInputs.length > 0) {
            console.log('✅ Settings page has form inputs');
            testsPassed++;
        } else {
            console.log('❌ Settings page has no form inputs');
            testsFailed++;
        }

        // Test 4: Check for checkboxes and toggles
        console.log('\n📋 Test 4: Checkbox/toggle inputs');

        const checkboxInputs = await page.$$('input[type="checkbox"]');
        console.log(`   Found ${checkboxInputs.length} checkbox inputs`);

        if (checkboxInputs.length > 0) {
            // Try to toggle a checkbox
            try {
                const firstCheckbox = checkboxInputs[0];
                const initialState = await page.evaluate(el => el.checked, firstCheckbox);
                await firstCheckbox.click();
                await new Promise(resolve => setTimeout(resolve, 500));
                const newState = await page.evaluate(el => el.checked, firstCheckbox);

                if (initialState !== newState) {
                    console.log('✅ Checkboxes are interactive');
                    testsPassed++;
                } else {
                    console.log('⚠️  Checkbox click did not change state');
                }

                // Toggle back
                await firstCheckbox.click();
            } catch (e) {
                console.log(`⚠️  Could not test checkbox interaction: ${e.message}`);
            }
        } else {
            console.log('⚠️  No checkboxes found');
        }

        // Test 5: No error alerts on page load
        console.log('\n📋 Test 5: No error alerts on page load');

        const errorAlerts = await page.$$('.alert-danger, .error-message, .alert-error');
        if (errorAlerts.length === 0) {
            console.log('✅ No error alerts on settings page');
            testsPassed++;
        } else {
            console.log(`⚠️  Found ${errorAlerts.length} error alert(s) on page`);
            for (const alert of errorAlerts.slice(0, 2)) {
                const text = await page.evaluate(el => el.textContent, alert);
                console.log(`   - ${text.trim().substring(0, 60)}`);
            }
        }

        // Take a screenshot of the settings page (skip in CI)
        if (!isCI) {
            await page.screenshot({
                path: path.join(screenshotsDir, 'settings_validation_test.png'),
                fullPage: true
            });
            console.log('\n📸 Screenshot saved to screenshots/settings_validation_test.png');
        }

        // Summary
        console.log('\n' + '='.repeat(50));
        console.log(`📊 Test Summary: ${testsPassed} passed, ${testsFailed} failed`);
        console.log('='.repeat(50));

        if (testsFailed > 0) {
            throw new Error(`${testsFailed} test(s) failed`);
        }

        console.log('\n🎉 All settings validation tests passed!');

    } catch (error) {
        console.error('\n❌ Test failed:', error.message);

        // Take error screenshot (skip in CI)
        if (!isCI) {
            try {
                await page.screenshot({
                    path: path.join(screenshotsDir, 'settings_validation_error.png'),
                    fullPage: true
                });
                console.log('📸 Error screenshot saved');
            } catch (screenshotError) {
                console.log('⚠️  Could not take error screenshot:', screenshotError.message);
            }
        }

        await browser.close();
        testTimer.summary();
        process.exit(1);
    }

    await browser.close();
    testTimer.summary();
    console.log('\n✅ Test completed successfully');
}

// Run the test
testSettingsValidation().catch(console.error);
