/**
 * Research Submit Test
 * Tests the research form submission workflow
 * CI-compatible: Works in both local and CI environments
 */

const puppeteer = require('puppeteer');
const AuthHelper = require('./auth_helper');
const { CI_TEST_USER } = require('./auth_helper');
const { getPuppeteerLaunchOptions } = require('./puppeteer_config');
const { setupDefaultModel } = require('./model_helper');
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 () => {
    let browser;
    const isCI = !!process.env.CI;

    // Skip in CI: setupDefaultModel() triggers provider-change JS that clears the
    // query field, causing the form to submit empty and redirect to /.  This is a
    // test-infrastructure issue, not a product bug.
    if (isCI) {
        console.log('⏭️  Skipping research submit test in CI (known model-setup race condition)');
        process.exit(0);
    }

    console.log(`🧪 Running research submit test (CI mode: ${isCI})`);
    // Create screenshots directory
    const screenshotsDir = path.join(__dirname, 'screenshots');
    if (!fs.existsSync(screenshotsDir)) {
        fs.mkdirSync(screenshotsDir, { recursive: true });
    }

    try {
        browser = await puppeteer.launch(getPuppeteerLaunchOptions());

        let page = await browser.newPage();

        // Set longer timeout for CI
        const timeout = isCI ? 60000 : 30000;
        page.setDefaultTimeout(timeout);
        page.setDefaultNavigationTimeout(timeout);

        // Log console messages only if verbose
        if (process.env.VERBOSE) {
            page.on('console', msg => {
                console.log(`[${msg.type()}] ${msg.text()}`);
            });
        }

        // Authenticate (tries CI user first, falls back to registration)
        const auth = new AuthHelper(page);
        console.log('🔐 Authenticating...');
        await auth.ensureAuthenticated();
        page = auth.page;

        console.log('\n🏠 Navigating to home page...');
        await page.goto('http://127.0.0.1:5000/', { waitUntil: 'domcontentloaded' });

        // Set up model configuration
        console.log('🔧 Configuring model...');
        const modelConfigured = await setupDefaultModel(page);
        if (!modelConfigured) {
            throw new Error('Failed to configure model');
        }

        // Wait for and fill the query field
        await page.waitForSelector('#query', { timeout: 10000 });
        await page.type('#query', 'What is Node.js?');
        console.log('✅ Query entered');

        // Check if model and search engine are pre-selected
        const formValues = await page.evaluate(() => {
            return {
                query: document.querySelector('#query')?.value,
                model: document.querySelector('#model')?.value || document.querySelector('input[name="model"]')?.value,
                searchEngine: document.querySelector('#search_engine')?.value || document.querySelector('input[name="search_engine"]')?.value
            };
        });
        console.log('📋 Form values:', formValues);

        console.log('\n🚀 Submitting research...');

        // Submit the form with robust retry logic
        const submitButton = await page.$('button[type="submit"]');
        const navigationTimeout = isCI ? 45000 : 15000;

        let navigationSucceeded = false;
        if (submitButton) {
            try {
                // Try Promise.all approach first
                await Promise.all([
                    page.waitForNavigation({ waitUntil: 'domcontentloaded', timeout: navigationTimeout }),
                    submitButton.click()
                ]);
                navigationSucceeded = true;
            } catch (navError) {
                console.log(`  Navigation wait failed: ${navError.message}`);
                // Check if we're already on a different page
                const currentUrl = page.url();
                if (currentUrl.includes('/research/') || currentUrl.includes('/progress/')) {
                    console.log('  Already navigated to research page');
                    navigationSucceeded = true;
                } else {
                    // Wait a bit and check URL again
                    await new Promise(resolve => setTimeout(resolve, 3000));
                    const urlAfterWait = page.url();
                    if (urlAfterWait.includes('/research/') || urlAfterWait.includes('/progress/')) {
                        console.log('  Navigation completed after wait');
                        navigationSucceeded = true;
                    }
                }
            }
        }

        if (!navigationSucceeded) {
            // Try alternative submit method with Enter key
            console.log('  Trying Enter key submission...');
            await page.keyboard.press('Enter');
            await new Promise(resolve => setTimeout(resolve, 5000));
        }

        // Check where we ended up
        const url = page.url();
        console.log('📍 Current URL:', url);

        if (url.includes('/research/') || url.includes('/progress/')) {
            console.log('✅ Research submitted successfully!');
            // URL contains /research/ - that's sufficient proof research started
            // NOTE: Don't use page.evaluate() here - it hangs when the page has
            // active WebSocket/SSE connections for research progress updates.
            // The URL check is enough to verify successful submission.
            console.log('✅ Research is processing');
            console.log('\n🎉 Simple research test passed!');
            process.exit(0);
        } else {
            // Check for error messages
            const errorMessage = await page.evaluate(() => {
                const alert = document.querySelector('.alert-danger, .error-message');
                return alert ? alert.textContent : null;
            });

            if (errorMessage) {
                throw new Error(`Research submission failed: ${errorMessage}`);
            } else {
                throw new Error(`Unexpected redirect to: ${url}`);
            }
        }

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

        // Take screenshot on error
        if (browser) {
            try {
                const pages = await browser.pages();
                const page = pages[0];
                if (page) {
                    // Log current state for debugging
                    try {
                        const currentUrl = page.url();
                        console.log('Current URL at failure:', currentUrl);
                    } catch {
                        console.log('Could not get current URL');
                    }

                    // Skip diagnostic screenshot in CI — error context is in the logs
                    if (!isCI) {
                        try {
                            await page.screenshot({
                                path: path.join(screenshotsDir, `research_submit_error_${Date.now()}.png`),
                                fullPage: true
                            });
                            console.log('📸 Error screenshot saved');
                        } catch (screenshotError) {
                            console.error('Failed to save screenshot:', screenshotError.message);
                        }
                    }
                }
            } catch (browserError) {
                console.error('Error accessing browser pages:', browserError.message);
            }
        }

        process.exit(1);
    } finally {
        if (browser) {
            try {
                await browser.close();
            } catch (closeError) {
                console.error('Error closing browser:', closeError.message);
            }
        }
    }
})();
