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

async function startResearch(page, query) {
    // Make sure we're on the home page first
    const currentUrl = page.url();
    if (!currentUrl.endsWith('/') || currentUrl.includes('/auth/')) {
        console.log('Not on home page, navigating back...');
        await page.goto('http://127.0.0.1:5000/', { waitUntil: 'networkidle2' });
        await new Promise(resolve => setTimeout(resolve, 1000));
    }

    // Wait for and fill the research form
    try {
        await page.waitForSelector('#query', { timeout: 5000 });
    } catch (e) {
        console.log('Could not find #query input.');
        console.log('Current URL:', page.url());

        // Debug: check what's on the page
        const pageContent = await page.evaluate(() => {
            return {
                title: document.title,
                forms: document.querySelectorAll('form').length,
                inputs: Array.from(document.querySelectorAll('input')).map(i => ({id: i.id, name: i.name, type: i.type})),
                body: document.body.innerHTML.substring(0, 500)
            };
        });
        console.log('Page content:', pageContent);

        throw new Error('Research form not found');
    }

    // Clear existing value and type new query
    await page.evaluate(() => {
        const queryInput = document.getElementById('query');
        if (queryInput) {
            queryInput.value = '';
        }
    });

    await page.type('#query', query);

    // Setup the default model
    await setupDefaultModel(page);

    // Debug: check research form specifically
    const submissionInfo = await page.evaluate(() => {
        // Look for the research form specifically
        const researchForm = document.querySelector('#research-form') ||
                           document.querySelector('form:has(#query)') ||
                           Array.from(document.querySelectorAll('form')).find(f =>
                               f.querySelector('#query') !== null
                           );

        if (!researchForm) {
            // List all forms found
            const allForms = Array.from(document.querySelectorAll('form')).map(f => ({
                id: f.id,
                action: f.action,
                hasQueryInput: !!f.querySelector('#query')
            }));
            return { error: 'Research form not found', forms: allForms };
        }

        return {
            formFound: true,
            formId: researchForm.id || 'no-id',
            action: researchForm.action,
            method: researchForm.method,
            queryValue: document.querySelector('#query')?.value || 'not found'
        };
    });
    console.log('Research form info:', submissionInfo);

    // Submit research
    let responseData = null;

    try {
        // Set up response interception BEFORE clicking submit
        const responsePromise = new Promise((resolve) => {
            page.on('response', async (response) => {
                if (response.url().includes('/api/start_research') && response.status() === 200) {
                    try {
                        const data = await response.json();
                        resolve(data);
                    } catch (e) {
                        console.log('Could not parse API response:', e.message);
                        resolve(null);
                    }
                }
            });
        });

        // Also set a timeout
        const timeoutPromise = new Promise((resolve) => {
            setTimeout(() => resolve({ timeout: true }), 10000);
        });

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

        // Wait for either response or timeout
        const result = await Promise.race([responsePromise, timeoutPromise]);

        if (result && result.timeout) {
            console.log('Timeout waiting for research response');
        } else if (result) {
            responseData = result;
            console.log('Got research response:', responseData);
        }
    } catch (e) {
        console.log('Error during research submission:', e.message);
    }

    if (responseData) {
        if (responseData.status === 'queued') {
            console.log(`🕔 Research "${query}" queued with ID: ${responseData.research_id}, position: ${responseData.queue_position}`);

            // Navigate back to home page for next submission
            await page.goto('http://127.0.0.1:5000/', { waitUntil: 'networkidle2' });
            await new Promise(resolve => setTimeout(resolve, 1000));

            return { id: responseData.research_id, queued: true, position: responseData.queue_position };
        } else if (responseData.research_id) {
            console.log(`✓ Started research "${query}" with ID: ${responseData.research_id}`);

            // Wait a bit to ensure page navigation completes
            await new Promise(resolve => setTimeout(resolve, 2000));

            // Navigate back to home page to ensure we're ready for next research
            await page.goto('http://127.0.0.1:5000/', { waitUntil: 'networkidle2' });
            await new Promise(resolve => setTimeout(resolve, 1000));

            return { id: responseData.research_id, queued: false };
        }
    }

    console.log(`✗ Failed to start research "${query}": ${responseData?.message || 'Unknown error'}`);

    // Try to navigate back to home page anyway
    await page.goto('http://127.0.0.1:5000/', { waitUntil: 'networkidle2' });

    return null;
}

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

    const page = await browser.newPage();

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

    try {
        // First, ensure we're logged out
        const auth = new AuthHelper(page);

        // Check if we're logged in and log out if necessary
        await page.goto('http://127.0.0.1:5000/', { waitUntil: 'networkidle2' });
        const isCurrentlyLoggedIn = await auth.isLoggedIn();
        if (isCurrentlyLoggedIn) {
            console.log('Found existing session, logging out first...');
            await auth.logout();
            await new Promise(resolve => setTimeout(resolve, 1000));
        }

        // Create a fresh user
        const username = 'multitest_' + Date.now();
        const password = 'T3st!Secure#2024$LDR';

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

        // Check if already logged in after registration
        const isLoggedIn = await auth.isLoggedIn();
        if (!isLoggedIn) {
            console.log('Not logged in after registration, logging in...');
            await auth.login(username, password);
        } else {
            console.log('Already logged in after registration');
        }

        // We should be logged in after registration, but let's make sure we're on the home page
        console.log('Ensuring we are on the home page...');
        const currentUrl = page.url();
        console.log('Current URL after registration:', currentUrl);

        // If not on home page, navigate there using the same domain
        if (!currentUrl.endsWith('/') || currentUrl.includes('/auth/')) {
            await page.goto('http://127.0.0.1:5000/', { waitUntil: 'networkidle2' });
            await new Promise(resolve => setTimeout(resolve, 1000));
        }

        // Wait for the research form to be visible
        try {
            await page.waitForSelector('#query', { timeout: 5000 });
            console.log('✅ Research form is visible, ready to start tests');
        } catch (e) {
            console.error('Could not find research form');
            throw new Error('Unable to access research form after login');
        }

        console.log('\n2. Testing multiple concurrent researches...\n');

        // Navigate to home page using consistent domain
        console.log('Navigating to home page...');
        await page.goto('http://127.0.0.1:5000/', { waitUntil: 'networkidle2' });
        await new Promise(resolve => setTimeout(resolve, 1000));

        // Check current URL
        console.log('Current URL:', page.url());

        // Start first research
        console.log('Starting research 1...');
        await page.waitForSelector('#query', { timeout: 10000 });
        const research1 = await startResearch(page, 'First research about AI');

        if (!research1) {
            throw new Error('Failed to start first research');
        }

        // Wait a bit before starting next research to ensure transaction commits
        await new Promise(resolve => setTimeout(resolve, 3000));

        // Start second research (should work now!)
        console.log('\nStarting research 2...');
        const research2 = await startResearch(page, 'Second research about Python');

        if (!research2) {
            throw new Error('Failed to start second research');
        }

        // Wait to ensure transaction commits
        await new Promise(resolve => setTimeout(resolve, 3000));

        // Start third research
        console.log('\nStarting research 3...');
        const research3 = await startResearch(page, 'Third research about databases');

        if (!research3) {
            throw new Error('Failed to start third research');
        }

        // Wait to ensure transaction commits
        await new Promise(resolve => setTimeout(resolve, 3000));

        // Try to start fourth research (should fail due to limit)
        console.log('\nTrying to start research 4 (should hit limit)...');
        const research4 = await startResearch(page, 'Fourth research should fail');

        if (research4) {
            if (research4.queued) {
                console.log(`✓ Fourth research correctly queued at position ${research4.position}`);
            } else {
                console.log('WARNING: Fourth research started when it should have been queued!');
            }
        } else {
            console.log('✗ Fourth research failed to submit');
        }

        // Check active researches
        console.log('\n3. Summary:');
        console.log('Research submission results:');
        console.log(`  - Research 1: ${research1?.id} (queued: ${research1?.queued || false})`);
        console.log(`  - Research 2: ${research2?.id} (queued: ${research2?.queued || false})`);
        console.log(`  - Research 3: ${research3?.id} (queued: ${research3?.queued || false})`);
        console.log(`  - Research 4: ${research4?.id} (queued: ${research4?.queued || false})`);

        // Count how many were started vs queued
        const results = [research1, research2, research3, research4].filter(r => r);
        const started = results.filter(r => !r.queued).length;
        const queued = results.filter(r => r.queued).length;

        console.log(`\nStarted: ${started}, Queued: ${queued}`);
        console.log('\n✓ Multi-research and queueing functionality is working correctly!');

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