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

// Test configuration
const BASE_URL = 'http://127.0.0.1:5000';
const PREDEFINED_QUESTION = 'What are the latest developments in renewable energy technology in 2024?';
const SEARCH_TIMEOUT = 5000; // 5 seconds timeout for search
const POLL_INTERVAL = 500; // Check every 0.5 seconds

async function analyzeSearchFunctionality() {
    console.log('🔍 Starting Research Search Analysis Test...\n');

    let browser;
    try {
        // Launch browser
    const browser = await puppeteer.launch(getPuppeteerLaunchOptions());

        const page = await browser.newPage();
        const authHelper = new AuthHelper(page, BASE_URL);

        // Set up console logging
        page.on('console', msg => {
            console.log(`📝 [BROWSER ${msg.type().toUpperCase()}] ${msg.text()}`);
        });

        // Set up request logging
        page.on('request', request => {
            if (request.url().includes('/api/') || request.url().includes('/research')) {
                console.log(`→ REQUEST: ${request.method()} ${request.url()}`);
            }
        });

        page.on('response', response => {
            if (response.url().includes('/api/') || response.url().includes('/research')) {
                console.log(`← RESPONSE: ${response.status()} ${response.url()}`);
            }
        });

        // Step 1: Authentication
        console.log('🔐 Step 1: Authenticating...');
        await authHelper.ensureAuthenticated();
        console.log('✅ Authentication successful\n');

        // Step 2: Navigate to research page
        console.log('📄 Step 2: Navigating to research page...');
        await page.goto(`${BASE_URL}/`, { waitUntil: 'networkidle2' });

        // Check if research form exists
        const researchForm = await page.$('#research-form');
        if (!researchForm) {
            throw new Error('Research form not found on page');
        }
        console.log('✅ Research form found\n');

        // Step 3: Fill in research question
        console.log('📝 Step 3: Filling research form...');
        console.log(`   Question: "${PREDEFINED_QUESTION}"`);

        // Type the question
        await page.type('#query', PREDEFINED_QUESTION);

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

        // The custom dropdown uses an input field and stores the value in a hidden input
        console.log('   Looking for model dropdown elements...');

        // Check current model value
        const currentModel = await page.$eval('#model_hidden', el => el.value).catch(() => 'not found');
        console.log(`   Current model value in hidden input: ${currentModel}`);

        // Click the model input to open dropdown
        const modelInput = await page.$('#model');
        if (modelInput) {
            console.log('   Clicking model input to open dropdown...');
            await modelInput.click();
            await new Promise(resolve => setTimeout(resolve, 200));

            // Look for dropdown options in the list
            const modelOptions = await page.$$('#model-dropdown-list li');
            console.log(`   Found ${modelOptions.length} model options`);

            if (modelOptions.length > 0) {
                // Get the text and value of first option
                const firstOption = await page.evaluate(el => ({
                    text: el.textContent.trim(),
                    value: el.getAttribute('data-value') || el.textContent.trim()
                }), modelOptions[0]);

                console.log(`   Clicking first model option: ${firstOption.text} (${firstOption.value})`);
                await modelOptions[0].click();
                await new Promise(resolve => setTimeout(resolve, 300));

                // Verify selection
                const selectedModel = await page.$eval('#model_hidden', el => el.value).catch(() => 'error');
                console.log(`   Selected model: ${selectedModel}`);
            } else {
                console.log('   No model options found in dropdown list');
            }
        } else {
            // Fallback to regular select if custom dropdown not found
            const modelOptions = await page.$$eval('#model option', options =>
                options.map(opt => ({ value: opt.value, text: opt.textContent }))
            );
            console.log(`   Available models: ${modelOptions.length}`);
            modelOptions.forEach(model => {
                console.log(`     - ${model.value}: ${model.text}`);
            });

            if (modelOptions.length > 0) {
                await page.select('#model', modelOptions[0].value);
                console.log(`   Selected model: ${modelOptions[0].value}`);
            }
        }

        // Handle search engine selection
        console.log('   Checking search engine options...');

        // Check current search engine value
        const currentEngine = await page.$eval('#search_engine_hidden', el => el.value).catch(() => 'not found');
        console.log(`   Current search engine value in hidden input: ${currentEngine}`);

        // Click the search engine input to open dropdown
        const searchInput = await page.$('#search_engine');
        if (searchInput) {
            console.log('   Clicking search engine input to open dropdown...');
            await searchInput.click();
            await new Promise(resolve => setTimeout(resolve, 200));

            // Look for dropdown options in the list
            const searchOptions = await page.$$('#search-engine-dropdown-list li');
            console.log(`   Found ${searchOptions.length} search engine options`);

            if (searchOptions.length > 0) {
                // Get the text and value of first option
                const firstOption = await page.evaluate(el => ({
                    text: el.textContent.trim(),
                    value: el.getAttribute('data-value') || el.textContent.trim()
                }), searchOptions[0]);

                console.log(`   Clicking first search engine option: ${firstOption.text} (${firstOption.value})`);
                await searchOptions[0].click();
                await new Promise(resolve => setTimeout(resolve, 300));

                // Verify selection
                const selectedEngine = await page.$eval('#search_engine_hidden', el => el.value).catch(() => 'error');
                console.log(`   Selected search engine: ${selectedEngine}`);
            } else {
                console.log('   No search engine options found in dropdown list');
            }
        } else {
            // Fallback to checkboxes
            const searchEngines = await page.$$eval('[name="search_engines"]:checked', engines =>
                engines.map(e => e.value)
            );
            console.log(`   Selected search engines: ${searchEngines.join(', ') || 'None'}`);

            if (searchEngines.length === 0) {
                const availableEngines = await page.$$('[name="search_engines"]');
                if (availableEngines.length > 0) {
                    await availableEngines[0].click();
                    console.log('   Selected first available search engine');
                }
            }
        }

        console.log('✅ Form filled successfully\n');

        // Step 4: Submit research
        console.log('🚀 Step 4: Submitting research...');

        // Click submit button - specifically the research submit button
        const submitButton = await page.$('#start-research-btn');
        if (!submitButton) {
            // Fallback to form submit button
            const fallbackButton = await page.$('#research-form button[type="submit"]');
            if (!fallbackButton) {
                throw new Error('Submit button not found');
            }
        }

        // Set up response interceptor for research submission
        const submissionPromise = page.waitForResponse(
            response => response.url().includes('/research') && response.request().method() === 'POST',
            { timeout: 30000 }
        );

        await submitButton.click();

        try {
            const response = await submissionPromise;
            console.log(`✅ Research submitted - Response: ${response.status()}`);

            if (response.status() !== 200) {
                const responseText = await response.text();
                console.log(`⚠️  Non-200 response: ${responseText}`);
            }
        } catch (error) {
            console.log('❌ No response received for research submission');
        }

        // Wait a bit for any redirects
        await new Promise(resolve => setTimeout(resolve, 500));

        // Step 5: Analyze current state
        console.log('\n📊 Step 5: Analyzing search state...');

        const currentUrl = page.url();
        console.log(`   Current URL: ${currentUrl}`);

        // Check if we're on a results page
        if (currentUrl.includes('/research/') || currentUrl.includes('/results')) {
            console.log('✅ Redirected to results page');

            // Monitor search progress
            console.log('\n⏳ Step 6: Monitoring search progress...');

            let searchComplete = false;
            let errorFound = false;
            let resultsFound = false;
            const startTime = Date.now();

            while (!searchComplete && (Date.now() - startTime) < SEARCH_TIMEOUT) {
                // Check for various indicators
                const indicators = await page.evaluate(() => {
                    const result = {
                        // Check for progress indicators
                        progressBar: !!document.querySelector('.progress-bar'),
                        spinner: !!document.querySelector('.spinner-border'),
                        loadingText: !!document.querySelector('[class*="loading"]'),

                        // Check for completion indicators
                        results: !!document.querySelector('.research-results'),
                        summary: !!document.querySelector('.research-summary'),
                        sources: document.querySelectorAll('.source-item').length,

                        // Check for error indicators
                        errorAlert: !!document.querySelector('.alert-danger'),
                        errorMessage: document.querySelector('.alert-danger')?.textContent || '',

                        // Check for status messages
                        statusText: document.querySelector('.status-message')?.textContent || '',

                        // Check page content
                        bodyText: document.body.innerText.substring(0, 500)
                    };

                    return result;
                });

                // Log current state
                console.log(`\n   [${Math.floor((Date.now() - startTime) / 1000)}s] Search state:`);
                console.log(`     Progress indicators: ${indicators.progressBar || indicators.spinner || indicators.loadingText ? 'Active' : 'None'}`);
                console.log(`     Results found: ${indicators.results || indicators.summary ? 'Yes' : 'No'}`);
                console.log(`     Sources found: ${indicators.sources}`);

                if (indicators.errorAlert) {
                    console.log(`     ❌ ERROR: ${indicators.errorMessage}`);
                    errorFound = true;
                    searchComplete = true;
                }

                if (indicators.results || indicators.summary || indicators.sources > 0) {
                    console.log('     ✅ Search results detected!');
                    resultsFound = true;
                    searchComplete = true;
                }

                if (indicators.statusText) {
                    console.log(`     Status: ${indicators.statusText}`);
                }

                // Check if search is still in progress
                if (!searchComplete) {
                    await new Promise(resolve => setTimeout(resolve, POLL_INTERVAL));
                }
            }

            // Final analysis
            console.log('\n📋 Step 7: Final Analysis:');
            console.log(`   Search duration: ${Math.floor((Date.now() - startTime) / 1000)} seconds`);
            console.log(`   Search completed: ${searchComplete}`);
            console.log(`   Results found: ${resultsFound}`);
            console.log(`   Errors encountered: ${errorFound}`);

            // Take screenshot
            await page.screenshot({ path: 'research_search_analysis.png', fullPage: true });
            console.log('   📸 Screenshot saved as research_search_analysis.png');

            // Get final page content for debugging
            const finalContent = await page.evaluate(() => {
                return {
                    title: document.title,
                    hasResults: !!document.querySelector('.research-results'),
                    resultCount: document.querySelectorAll('.result-item').length,
                    sourceCount: document.querySelectorAll('.source-item').length,
                    errorCount: document.querySelectorAll('.alert-danger').length,
                    warningCount: document.querySelectorAll('.alert-warning').length
                };
            });

            console.log('\n   Final page analysis:');
            console.log(`     Title: ${finalContent.title}`);
            console.log(`     Has results section: ${finalContent.hasResults}`);
            console.log(`     Result items: ${finalContent.resultCount}`);
            console.log(`     Source items: ${finalContent.sourceCount}`);
            console.log(`     Errors: ${finalContent.errorCount}`);
            console.log(`     Warnings: ${finalContent.warningCount}`);

            // Overall test result
            console.log('\n🏁 TEST SUMMARY:');
            if (resultsFound && !errorFound) {
                console.log('✅ Search functionality is WORKING - Results were generated');
            } else if (errorFound) {
                console.log('❌ Search functionality FAILED - Errors were encountered');
            } else {
                console.log('⚠️  Search functionality UNCLEAR - No results or errors detected within timeout');
            }

        } else {
            console.log('❌ Did not redirect to results page');
            console.log('   Search functionality appears to be broken');

            // Don't wait for full timeout if we didn't redirect
            await new Promise(resolve => setTimeout(resolve, 200));

            // Check for any error messages on current page
            const pageErrors = await page.$$eval('.alert-danger', alerts =>
                alerts.map(alert => alert.textContent.trim())
            );

            if (pageErrors.length > 0) {
                console.log('\n   Errors found on page:');
                pageErrors.forEach(error => console.log(`     - ${error}`));
            }
        }

    } catch (error) {
        console.error('\n❌ Test failed with error:', error.message);
        throw error;
    } finally {
        if (browser) {
            await browser.close();
        }
    }
}

// Run the test
analyzeSearchFunctionality()
    .then(() => {
        console.log('\n✅ Research search analysis test completed');
        process.exit(0);
    })
    .catch(error => {
        console.error('\n❌ Research search analysis test failed:', error);
        process.exit(1);
    });
