/**
 * Research Diagnosis Test
 * Detailed diagnostic test to understand why research doesn't start
 */

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

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

    const page = await browser.newPage();
    const baseUrl = 'http://127.0.0.1:5000';
    const authHelper = new AuthHelper(page, baseUrl);

    console.log('🔬 Research Diagnosis Test');
    console.log('=' .repeat(60) + '\n');

    // Collect all console messages
    const consoleLogs = [];
    page.on('console', msg => {
        const entry = `[${msg.type().toUpperCase()}] ${msg.text()}`;
        consoleLogs.push(entry);
        console.log(`🖥️  ${entry}`);
    });

    // Collect JavaScript errors
    page.on('pageerror', error => {
        console.log(`❌ JS Error: ${error.message}`);
    });

    // Monitor all network requests
    await page.setRequestInterception(true);
    const networkLog = [];

    page.on('request', request => {
        const logEntry = {
            url: request.url(),
            method: request.method(),
            headers: request.headers(),
            postData: request.postData(),
            timestamp: new Date().toISOString()
        };
        networkLog.push(logEntry);

        // Log important requests
        if (request.url().includes('/api/') || request.url().includes('/research/')) {
            console.log(`\n📤 ${request.method()} ${request.url()}`);
            if (request.postData()) {
                console.log('📦 Request Body:', request.postData());
            }
        }

        request.continue();
    });

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

            // Try to get response body for errors
            if (response.status() >= 400) {
                try {
                    const body = await response.text();
                    console.log('📄 Error Response Body:', body);
                } catch {
                    console.log('Could not read response body');
                }
            }
        }
    });

    try {
        // Step 1: Authenticate
        console.log('🔐 Authenticating...');
        await authHelper.ensureAuthenticated();
        console.log('✅ Authenticated\n');

        // Step 2: Go to home page
        await page.goto(baseUrl, {
            waitUntil: 'domcontentloaded',
            timeout: 30000
        });

        // Step 3: Check what's on the page
        console.log('📋 Checking page structure...\n');

        const pageInfo = await page.evaluate(() => {
            const info = {
                forms: [],
                scripts: [],
                apiEndpoints: [],
                formElements: {}
            };

            // Find all forms
            document.querySelectorAll('form').forEach(form => {
                info.forms.push({
                    id: form.id,
                    action: form.action,
                    method: form.method,
                    onsubmit: form.onsubmit ? 'has onsubmit handler' : 'no handler'
                });
            });

            // Find form elements
            const elements = ['#query', '#mode-quick', '#mode-detailed',
                            '#model_provider', '#search_engine', '#iterations',
                            '#questions_per_iteration', 'button[type="submit"]'];

            elements.forEach(selector => {
                const el = document.querySelector(selector);
                info.formElements[selector] = el ? {
                    found: true,
                    type: el.type || el.tagName,
                    value: el.value || '',
                    disabled: el.disabled
                } : { found: false };
            });

            // Find loaded scripts
            document.querySelectorAll('script[src]').forEach(script => {
                if (script.src.includes('research') || script.src.includes('form')) {
                    info.scripts.push(script.src);
                }
            });

            // Check for API endpoints in JavaScript
            const scriptContent = Array.from(document.scripts)
                .map(s => s.textContent)
                .join('\n');

            const apiMatches = scriptContent.match(/['"]\/api\/[^'"]+['"]/g) || [];
            info.apiEndpoints = [...new Set(apiMatches.map(m => m.slice(1, -1)))];

            return info;
        });

        console.log('Forms found:', pageInfo.forms);
        console.log('\nForm elements:');
        Object.entries(pageInfo.formElements).forEach(([selector, info]) => {
            console.log(`  ${selector}: ${info.found ? '✅ Found' : '❌ Not found'}`);
            if (info.found && info.value) {
                console.log(`    Value: ${info.value}`);
            }
        });
        console.log('\nAPI endpoints found in JavaScript:', pageInfo.apiEndpoints);
        console.log('\nResearch-related scripts:', pageInfo.scripts);

        // Step 4: Fill the form
        console.log('\n📝 Filling research form...\n');

        // Clear and type query
        await page.click('#query', { clickCount: 3 }); // Triple click to select all
        await page.type('#query', 'What is artificial intelligence?');
        console.log('✅ Entered query');

        // Select quick mode
        const quickMode = await page.$('#mode-quick');
        if (quickMode) {
            await page.click('#mode-quick');
            console.log('✅ Selected quick mode');
        }

        // Get form data before submission
        const formData = await page.evaluate(() => {
            const data = {};
            const form = document.getElementById('research-form');
            if (form) {
                const fd = new FormData(form);
                for (const [key, value] of fd.entries()) {
                    data[key] = value;
                }
            }

            // Also check hidden inputs and selects
            document.querySelectorAll('input[type="hidden"], select').forEach(el => {
                if (el.name || el.id) {
                    data[el.name || el.id] = el.value;
                }
            });

            return data;
        });

        console.log('\n📊 Form data to be submitted:');
        console.log(JSON.stringify(formData, null, 2));

        // Step 5: Check JavaScript state
        console.log('\n🔧 Checking JavaScript state...\n');

        const jsState = await page.evaluate(() => {
            const state = {
                jQuery: typeof $ !== 'undefined',
                socketIO: typeof io !== 'undefined',
                formHandlers: [],
                globalFunctions: []
            };

            // Check for form submit handlers
            const form = document.getElementById('research-form');
            if (form) {
                // Check jQuery handlers
                if (typeof $ !== 'undefined' && $._data) {
                    const events = $._data(form, 'events');
                    if (events && events.submit) {
                        state.formHandlers.push('jQuery submit handler');
                    }
                }

                // Check native handlers
                if (form.onsubmit) {
                    state.formHandlers.push('Native onsubmit handler');
                }
            }

            // Check for global functions
            const funcs = ['startResearch', 'submitResearch', 'validateForm'];
            funcs.forEach(func => {
                if (typeof window[func] === 'function') {
                    state.globalFunctions.push(func);
                }
            });

            return state;
        });

        console.log('JavaScript environment:');
        console.log(`  jQuery loaded: ${jsState.jQuery}`);
        console.log(`  Socket.IO loaded: ${jsState.socketIO}`);
        console.log(`  Form handlers: ${jsState.formHandlers.join(', ') || 'None'}`);
        console.log(`  Global functions: ${jsState.globalFunctions.join(', ') || 'None'}`);

        // Step 6: Submit the form
        console.log('\n🚀 Attempting to submit research...\n');

        // Take screenshot before submit
        await page.screenshot({ path: './screenshots/diagnosis_before_submit.png' });

        // Find submit button
        const submitButton = await page.$('button[type="submit"]');
        if (!submitButton) {
            throw new Error('Submit button not found!');
        }

        // Click and monitor what happens
        console.log('Clicking submit button...');
        await submitButton.click();

        // Wait a bit to see what happens
        await new Promise(resolve => setTimeout(resolve, 5000));

        // Check current state
        const afterSubmit = await page.evaluate(() => {
            return {
                url: window.location.href,
                alerts: Array.from(document.querySelectorAll('.alert')).map(a => ({
                    class: a.className,
                    text: a.textContent.trim()
                })),
                bodyClasses: document.body.className,
                visibleModals: Array.from(document.querySelectorAll('.modal.show')).length,
                activeRequests: typeof $.active !== 'undefined' ? $.active : 'unknown'
            };
        });

        console.log('\n📍 After submit state:');
        console.log(`  URL: ${afterSubmit.url}`);
        console.log(`  Alerts: ${afterSubmit.alerts.length}`);
        afterSubmit.alerts.forEach(alert => {
            console.log(`    - [${alert.class}] ${alert.text}`);
        });
        console.log(`  Active AJAX requests: ${afterSubmit.activeRequests}`);

        // Take final screenshot
        await page.screenshot({ path: './screenshots/diagnosis_after_submit.png' });

        // Step 7: Summary
        console.log('\n' + '=' .repeat(60));
        console.log('📊 DIAGNOSIS SUMMARY');
        console.log('=' .repeat(60));

        console.log('\n🔍 Key Findings:');

        // Check console logs for errors
        const errors = consoleLogs.filter(log => log.includes('ERROR'));
        if (errors.length > 0) {
            console.log('\n❌ JavaScript Errors:');
            errors.forEach(err => console.log(`  - ${err}`));
        }

        // Check network failures
        const failedRequests = networkLog.filter(req => {
            const response = networkLog.find(r => r.url === req.url && r.status);
            return response && response.status >= 400;
        });

        if (failedRequests.length > 0) {
            console.log('\n❌ Failed API Calls:');
            failedRequests.forEach(req => {
                console.log(`  - ${req.method} ${req.url}`);
            });
        }

        console.log('\n💡 Recommendations:');
        console.log('1. Check server logs for SQLAlchemy errors');
        console.log('2. Verify all required form fields are being sent');
        console.log('3. Check if API endpoints are correctly configured');
        console.log('4. Ensure database migrations are up to date');

    } catch (error) {
        console.error('\n❌ Test error:', error.message);
        console.error(error.stack);
        await page.screenshot({ path: './screenshots/diagnosis_error.png' });
    }

    // Save detailed logs
    const fs = require('fs');
    fs.writeFileSync('./diagnosis_network_log.json', JSON.stringify(networkLog, null, 2));
    fs.writeFileSync('./diagnosis_console_log.json', JSON.stringify(consoleLogs, null, 2));
    console.log('\n📁 Detailed logs saved to:');
    console.log('  - ./diagnosis_network_log.json');
    console.log('  - ./diagnosis_console_log.json');

    console.log('\n⏸️  Keeping browser open for manual inspection...');
    console.log('Press Ctrl+C to close');

    // Keep browser open indefinitely for debugging
    await new Promise(() => {});
}

// Run the test
testResearchDiagnosis().catch(error => {
    console.error('💥 Test runner error:', error);
    process.exit(1);
});
