/**
 * Test for toast notifications when saving settings
 *
 * This test verifies that toast notifications appear when checkbox settings are changed.
 */

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

const TEST_CONFIG = {
    TIMEOUTS: {
        SETTINGS_LOAD: 5000,
        TOAST_APPEAR: 5000,
        AJAX_SAVE: 3000,
        NAVIGATION: 30000
    },
    URLS: {
        BASE: 'http://localhost:5000',
        SETTINGS: 'http://localhost:5000/settings'
    },
    SELECTORS: {
        CHECKBOX: 'input[type="checkbox"].ldr-settings-checkbox',
        TOAST_CONTAINER: '#toast-container',
        TOAST: '.toast, .ldr-toast',
        TOAST_VISIBLE: '.toast.visible, .ldr-toast.visible'
    }
};

(async () => {
    let browser;
    let page;
    const consoleLogs = [];
    const networkRequests = [];
    const networkResponses = [];

    try {
        console.log('=== Testing Toast Notifications ===\n');

        browser = await puppeteer.launch(getPuppeteerLaunchOptions());
        page = await browser.newPage();
        await page.setViewport({ width: 1920, height: 1080 });

        // Capture ONLY toast-related console logs
        page.on('console', msg => {
            const text = msg.text();
            const type = msg.type();

            // Only log toast-related items
            if (text.includes('showMessage') ||
                text.includes('[Notification]') ||
                text.includes('toast') ||
                text.includes('Toast') ||
                text.includes('[DEBUG]') ||
                text.includes('[submitSettingsData]') ||
                text.includes('originalSettings cache')) {
                consoleLogs.push({ type, text, timestamp: Date.now() });
                console.log(`[BROWSER] ${text}`);
            }
        });

        // Capture page errors
        page.on('pageerror', error => {
            console.error(`[PAGE ERROR] ${error.message}`);
            consoleLogs.push({ type: 'pageerror', text: error.message, timestamp: Date.now() });
        });

        // Capture network requests
        page.on('request', req => {
            if (req.url().includes('save_all_settings') || req.url().includes('settings')) {
                networkRequests.push({
                    url: req.url(),
                    method: req.method(),
                    timestamp: Date.now()
                });
            }
        });

        // Capture network responses
        page.on('response', async resp => {
            if (resp.url().includes('save_all_settings')) {
                try {
                    const text = await resp.text();
                    networkResponses.push({
                        url: resp.url(),
                        status: resp.status(),
                        body: text.substring(0, 500),
                        timestamp: Date.now()
                    });
                    console.log(`[NETWORK] Response from save_all_settings: ${resp.status()}`);
                } catch (e) {
                    // Response already consumed
                }
            }
        });

        // Authenticate with a consistent user
        console.log('🔐 Authenticating...');
        const authHelper = new AuthHelper(page);
        const testUser = 'toast_test_user';
        const testPassword = 'T3st!Secure#2024$LDR';

        // Try to register/login this specific user
        try {
            await authHelper.ensureAuthenticated(testUser, testPassword);
        } catch (e) {
            console.log('Initial auth failed, trying direct registration...');
            try {
                await authHelper.register(testUser, testPassword);
            } catch (regErr) {
                console.log('Registration failed (user may exist), trying login...');
                await authHelper.login(testUser, testPassword);
            }
        }
        console.log('✅ Authenticated\n');

        // Navigate to settings
        console.log('📄 Navigating to settings page...');
        await page.goto(TEST_CONFIG.URLS.SETTINGS, {
            waitUntil: 'networkidle2',
            timeout: TEST_CONFIG.TIMEOUTS.NAVIGATION
        });

        // Check current URL
        let currentUrl = page.url();
        console.log(`Current URL: ${currentUrl}`);

        // Check if we got redirected to login - try login with our test user
        if (currentUrl.includes('/auth/login')) {
            console.log('⚠️  Redirected to login, attempting login...');
            await authHelper.login(testUser, testPassword);
            await page.goto(TEST_CONFIG.URLS.SETTINGS, {
                waitUntil: 'networkidle2',
                timeout: TEST_CONFIG.TIMEOUTS.NAVIGATION
            });
            currentUrl = page.url();
            console.log(`After re-login URL: ${currentUrl}`);
        }

        // Wait longer for settings to load (they load dynamically)
        console.log('Waiting for settings page to fully load...');
        await new Promise(resolve => setTimeout(resolve, 5000));

        // Debug: check page content
        const pageDebug = await page.evaluate(() => ({
            title: document.title,
            url: window.location.href,
            allCheckboxes: document.querySelectorAll('input[type="checkbox"]').length,
            ldrCheckboxes: document.querySelectorAll('input[type="checkbox"].ldr-settings-checkbox').length,
            anyInputs: document.querySelectorAll('input').length,
            settingsContent: !!document.getElementById('settings-content'),
            bodyText: document.body.textContent.substring(0, 500)
        }));
        console.log('Page debug info:', JSON.stringify(pageDebug, null, 2));

        // Try different selectors
        let checkboxSelector = TEST_CONFIG.SELECTORS.CHECKBOX;
        let checkboxes = await page.$$(checkboxSelector);

        if (checkboxes.length === 0) {
            console.log('No ldr-settings-checkbox found, trying any checkbox...');
            checkboxSelector = 'input[type="checkbox"]';
            checkboxes = await page.$$(checkboxSelector);
        }

        if (checkboxes.length === 0) {
            // Take screenshot for debugging
            await page.screenshot({ path: '/tmp/settings_no_checkboxes.png', fullPage: true });
            console.log('📸 Screenshot saved to /tmp/settings_no_checkboxes.png');
            throw new Error(`No checkboxes found. Page has ${pageDebug.anyInputs} inputs total.`);
        }

        console.log(`✅ Settings page loaded - found ${checkboxes.length} checkboxes\n`);

        // Check if window.ui is available
        const uiCheck = await page.evaluate(() => {
            return {
                windowUi: !!window.ui,
                showMessage: !!(window.ui && window.ui.showMessage),
                toastContainer: !!document.getElementById('toast-container')
            };
        });
        console.log('UI availability check:', JSON.stringify(uiCheck, null, 2));

        // Get first checkbox info
        const firstCheckbox = checkboxes[0];
        const checkboxInfo = await firstCheckbox.evaluate(el => ({
            name: el.name,
            checked: el.checked,
            id: el.id
        }));
        console.log('Testing checkbox:', JSON.stringify(checkboxInfo, null, 2));

        // Clear console logs before toggling
        consoleLogs.length = 0;
        networkRequests.length = 0;
        networkResponses.length = 0;

        console.log('\n🔄 Toggling checkbox...');
        const initialState = checkboxInfo.checked;
        await firstCheckbox.click();

        // Wait for AJAX save to complete
        console.log('⏳ Waiting for AJAX save...');
        await new Promise(resolve => setTimeout(resolve, TEST_CONFIG.TIMEOUTS.AJAX_SAVE));

        // Check checkbox state changed
        const newState = await firstCheckbox.evaluate(el => el.checked);
        console.log(`Checkbox state: ${initialState} → ${newState}`);

        // Check for toast in DOM
        const toastCheck = await page.evaluate(() => {
            const container = document.getElementById('toast-container');
            const toasts = document.querySelectorAll('.toast, .ldr-toast');
            const visibleToasts = document.querySelectorAll('.toast.visible, .ldr-toast.visible');

            let containerStyles = null;
            if (container) {
                const computed = window.getComputedStyle(container);
                containerStyles = {
                    position: computed.position,
                    top: computed.top,
                    right: computed.right,
                    zIndex: computed.zIndex,
                    display: computed.display,
                    visibility: computed.visibility
                };
            }

            let toastInfo = [];
            toasts.forEach((t, i) => {
                const computed = window.getComputedStyle(t);
                toastInfo.push({
                    index: i,
                    className: t.className,
                    innerHTML: t.innerHTML.substring(0, 100),
                    opacity: computed.opacity,
                    transform: computed.transform,
                    display: computed.display,
                    visibility: computed.visibility
                });
            });

            return {
                containerExists: !!container,
                containerStyles,
                totalToasts: toasts.length,
                visibleToasts: visibleToasts.length,
                toastInfo
            };
        });

        console.log('\n📋 Toast DOM state:');
        console.log(JSON.stringify(toastCheck, null, 2));

        // Wait a bit more for toast animation
        await new Promise(resolve => setTimeout(resolve, 500));

        // Check again for visible toasts
        const finalToastCheck = await page.evaluate(() => {
            const visibleToasts = document.querySelectorAll('.toast.visible, .ldr-toast.visible');
            return {
                visibleToastsCount: visibleToasts.length,
                visibleToastsHTML: Array.from(visibleToasts).map(t => t.innerHTML.substring(0, 100))
            };
        });
        console.log('\n📋 Final toast check:');
        console.log(JSON.stringify(finalToastCheck, null, 2));

        // Print relevant console logs
        console.log('\n📝 Relevant browser console logs:');
        const relevantLogs = consoleLogs.filter(log =>
            log.text.includes('showMessage') ||
            log.text.includes('Notification') ||
            log.text.includes('toast') ||
            log.text.includes('DEBUG') ||
            log.text.includes('submitSettingsData') ||
            log.text.includes('originalSettings') ||
            log.type === 'error'
        );

        if (relevantLogs.length === 0) {
            console.log('  (No relevant logs captured - this is suspicious!)');
        } else {
            relevantLogs.forEach(log => {
                console.log(`  [${log.type}] ${log.text}`);
            });
        }

        // Print network activity
        console.log('\n🌐 Network activity:');
        console.log(`  Requests: ${networkRequests.length}`);
        networkRequests.forEach(req => {
            console.log(`    ${req.method} ${req.url}`);
        });
        console.log(`  Responses: ${networkResponses.length}`);
        networkResponses.forEach(resp => {
            console.log(`    ${resp.status} ${resp.url}`);
            if (resp.body) {
                console.log(`    Body: ${resp.body.substring(0, 200)}`);
            }
        });

        // Take screenshot
        const screenshotPath = '/tmp/toast_test_screenshot.png';
        await page.screenshot({ path: screenshotPath, fullPage: false });
        console.log(`\n📸 Screenshot saved to: ${screenshotPath}`);

        // Toggle back to original state
        console.log('\n🔄 Restoring original checkbox state...');
        await firstCheckbox.click();
        await new Promise(resolve => setTimeout(resolve, 1000));

        // Final verdict
        console.log('\n' + '='.repeat(60));
        if (finalToastCheck.visibleToastsCount > 0) {
            console.log('✅ SUCCESS: Toast notification appeared!');
        } else if (toastCheck.totalToasts > 0) {
            console.log('⚠️  PARTIAL: Toast created but not visible (CSS issue)');
        } else if (networkResponses.length > 0 && networkResponses[0].status === 200) {
            console.log('❌ ISSUE: Save succeeded but no toast was created');
            console.log('   Check if notification code is being reached');
        } else {
            console.log('❌ ISSUE: No save request or toast notification detected');
        }
        console.log('='.repeat(60));

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

        // Print all console logs on failure
        console.log('\n📝 All browser console logs:');
        consoleLogs.forEach(log => {
            console.log(`  [${log.type}] ${log.text}`);
        });

        process.exit(1);
    } finally {
        if (browser) {
            await browser.close();
        }
    }
})();
