/**
 * Settings Error Detection UI Test
 *
 * Tests settings page for error messages that appear when changing values.
 * Monitors console errors and checks for error elements on the page after
 * making changes to settings. This helps identify validation errors or
 * save failures.
 *
 * What this tests:
 * - Console error detection during setting changes
 * - Network error monitoring (4xx/5xx responses)
 * - DOM error element detection (.error, .alert-danger, etc.)
 * - Setting input interaction (dropdowns, text fields)
 *
 * Prerequisites: Web server running on http://127.0.0.1:5000
 *
 * Usage: node tests/ui_tests/test_settings_errors.js
 */

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

async function testSettingsChange() {
    const browser = await puppeteer.launch(getPuppeteerLaunchOptions());
    const page = await browser.newPage();
    const baseUrl = 'http://127.0.0.1:5000';
    const authHelper = new AuthHelper(page, baseUrl);

    // Monitor console errors
    page.on('console', msg => {
        if (msg.type() === 'error') {
            console.log('❌ BROWSER ERROR:', msg.text());
        }
    });

    // Monitor network errors
    page.on('response', response => {
        if (response.status() >= 400) {
            console.log('❌ NETWORK ERROR:', response.status(), response.url());
        }
    });

    let failed = false;

    try {
        console.log('🔧 Testing settings change functionality...');
        await authHelper.ensureAuthenticatedWithTimeout();
        await page.goto('http://127.0.0.1:5000/settings/', {
            waitUntil: 'domcontentloaded',
            timeout: 30000
        });

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

        // Try to find and change a simple setting
        console.log('🔍 Looking for a setting to change...');

        // Find a dropdown or input field to change
        const settingInput = await page.$('select[data-key], input[data-key]');

        if (settingInput) {
            console.log('✅ Found setting input, attempting to change...');

            // Get the current value
            const currentValue = await page.evaluate(el => el.value, settingInput);
            console.log('Current value:', currentValue);

            // Try to change it
            await page.evaluate(el => {
                if (el.tagName === 'SELECT') {
                    // For dropdown, select a different option
                    if (el.options.length > 1) {
                        el.selectedIndex = el.selectedIndex === 0 ? 1 : 0;
                        el.dispatchEvent(new Event('change', { bubbles: true }));
                    }
                } else {
                    // For input, change the value
                    el.value = el.value + '_test';
                    el.dispatchEvent(new Event('change', { bubbles: true }));
                }
            }, settingInput);

            console.log('⏳ Waiting for any errors after change...');
            await new Promise(resolve => setTimeout(resolve, 2000));

        } else {
            console.log('❌ No setting inputs found');
        }

        // Check for any error messages on the page
        const errorElements = await page.$$('.error, .alert-danger, .text-danger, [class*="error"]');
        if (errorElements.length > 0) {
            console.log(`❌ Found ${errorElements.length} error elements on page`);
            for (let i = 0; i < errorElements.length; i++) {
                const errorText = await page.evaluate(el => el.textContent, errorElements[i]);
                console.log(`   Error ${i + 1}: ${errorText.trim()}`);
            }
        } else {
            console.log('✅ No error elements found on page');
        }

    } catch (error) {
        console.error('❌ Test error:', error);
        failed = true;
    } finally {
        await browser.close();
        process.exit(failed ? 1 : 0);
    }
}

testSettingsChange().catch(err => { console.error(err); process.exit(1); });
