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

// 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 submitResearch(page, query, index) {
    console.log(`\nSubmitting: "${query}"`);

    // Navigate to home
    await page.goto('http://127.0.0.1:5000/', { waitUntil: 'domcontentloaded' });

    // Capture page state before submission
    const pageInfo = await page.evaluate(() => {
        return {
            title: document.title,
            url: window.location.href,
            forms: document.querySelectorAll('form').length,
            queryInput: document.querySelector('#query') ? 'found' : 'not found',
            modelSelect: document.querySelector('#model') || document.querySelector('[name="model"]') ? 'found' : 'not found',
            submitButton: document.querySelector('button[type="submit"]') ? 'found' : 'not found',
            errorMessages: Array.from(document.querySelectorAll('.error, .alert-danger')).map(el => el.textContent),
            bodyText: document.body.innerText.substring(0, 500)
        };
    });
    console.log('Page state:', pageInfo);

    // Take screenshot before filling form
    await page.screenshot({ path: `/tmp/before_submit_${index}.png` });

    // Fill form
    try {
        await page.waitForSelector('#query', { timeout: 5000 });
        await page.evaluate(() => document.querySelector('#query').value = '');
        await page.type('#query', query);

        // Select model
        const modelSelected = await page.evaluate(() => {
            const modelSelect = document.querySelector('#model') ||
                               document.querySelector('[name="model"]') ||
                               document.querySelector('#model-select');
            if (modelSelect) {
                modelSelect.value = 'llama3.1:8b';
                modelSelect.dispatchEvent(new Event('change'));
                return true;
            }
            return false;
        });
        console.log('Model selected:', modelSelected);
    } catch (e) {
        console.log('Error filling form:', e.message);
        // Log page content
        const pageContent = await page.evaluate(() => document.body.innerHTML);
        console.log('Page HTML (first 1000 chars):', pageContent.substring(0, 1000));

        return null;
    }

    // Set up response listener before submitting
    const responsePromise = page.waitForResponse(
        response => response.url().includes('/api/start_research'),
        { timeout: 10000 }
    );

    // Submit
    await page.click('button[type="submit"]');

    try {
        const response = await responsePromise;
        const data = await response.json();
        console.log(`Response:`, data);

        return data;
    } catch (e) {
        console.log(`Failed to get response: ${e.message}`);

        // Log current page state
        const errorPageInfo = await page.evaluate(() => {
            return {
                url: window.location.href,
                title: document.title,
                errors: Array.from(document.querySelectorAll('.error, .alert, [class*="error"]')).map(el => ({
                    class: el.className,
                    text: el.textContent
                })),
                bodyText: document.body.innerText.substring(0, 1000)
            };
        });
        console.log('Error page state:', errorPageInfo);

        return null;
    }
}

(async () => {
    const browser = await puppeteer.launch(getPuppeteerLaunchOptions());

    const page = await browser.newPage();

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

    page.on('pageerror', error => {
        console.log('PAGE CRASH:', error.message);
    });

    try {
        // Register and login
        const auth = new AuthHelper(page);
        const username = 'qtest_' + Date.now();
        const password = 'T3st!Secure#2024$LDR';

        console.log('Creating user:', username);
        await auth.register(username, password);

        if (!await auth.isLoggedIn()) {
            await auth.login(username, password);
        }

        console.log('\nSubmitting 5 researches to test queueing...\n');

        const results = [];

        // Submit researches one by one
        for (let i = 1; i <= 5; i++) {
            const result = await submitResearch(page, `Research ${i} about topic ${i}`, i);
            if (result) {
                results.push(result);

                if (result.status === 'queued') {
                    console.log(`✓ Research ${i} QUEUED at position ${result.queue_position}`);
                } else if (result.status === 'success') {
                    console.log(`✓ Research ${i} STARTED`);
                }
            }

            // Small delay between submissions
            await new Promise(resolve => setTimeout(resolve, 500));
        }

        // Summary
        console.log('\n=== SUMMARY ===');
        const started = results.filter(r => r && r.status === 'success').length;
        const queued = results.filter(r => r && r.status === 'queued').length;
        const failed = results.filter(r => !r).length;

        console.log(`Started: ${started}`);
        console.log(`Queued: ${queued}`);
        console.log(`Failed: ${failed}`);

        // The test should pass if we have a reasonable distribution
        // In CI, network issues might cause some to fail
        if (started >= 1 && (started + queued) >= 3) {
            console.log('\n✅ SUCCESS: Queue system working correctly!');
        } else if (started >= 2) {
            console.log('\n✅ SUCCESS: Multiple researches started successfully');
        } else {
            console.log(`\n❌ FAILED: Only ${started} started, ${queued} queued, ${failed} failed`);
        }

        // Keep browser open for 5 seconds to see results
        await new Promise(resolve => setTimeout(resolve, 5000));

    } catch (error) {
        console.error('Test failed:', error);
    } finally {
        await browser.close();
    }
})();
