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

// Create screenshots directory
async function ensureScreenshotsDir() {
    const dir = path.join(__dirname, 'screenshots');
    try {
        await fs.mkdir(dir, { recursive: true });
    } catch (e) {
        // Directory exists
    }
    return dir;
}

async function takeScreenshot(page, name) {
    const dir = await ensureScreenshotsDir();
    const filepath = path.join(dir, `${name}.png`);
    await page.screenshot({ path: filepath, fullPage: true });
    console.log(`📸 Screenshot saved: ${filepath}`);
}

async function testResearchSubmitDebug() {
    let browser;
    let success = true;

    try {
        console.log('🚀 Starting research submit debug test...\n');

    const browser = await puppeteer.launch(getPuppeteerLaunchOptions());

        const page = await browser.newPage();
        const auth = new AuthHelper(page);

        // Set viewport
        await page.setViewport({ width: 1280, height: 800 });

        // Enable console logging
        page.on('console', msg => {
            const type = msg.type();
            if (type === 'error') {
                console.log('❌ PAGE ERROR:', msg.text());
            } else if (type === 'warning') {
                console.log('⚠️  PAGE WARNING:', msg.text());
            } else {
                console.log('📝 PAGE LOG:', msg.text());
            }
        });

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

        // Step 1: Login
        console.log('STEP 1: Login\n');
        console.log('Navigating to home page...');
        await page.goto('http://127.0.0.1:5000', { waitUntil: 'networkidle2' });
        await takeScreenshot(page, '01-initial-page');

        // Check if we need to login
        const needsLogin = page.url().includes('/auth/login');
        if (needsLogin) {
            console.log('Login required, authenticating...');
            await auth.login('testuser', 'T3st!Secure#2024$LDR');
            await takeScreenshot(page, '02-after-login');
        } else {
            console.log('Already logged in');
        }

        // Make sure we're on the home page
        if (!page.url().endsWith('/')) {
            console.log('Navigating to home page...');
            await page.goto('http://127.0.0.1:5000/', { waitUntil: 'networkidle2' });
        }

        await takeScreenshot(page, '03-home-page');

        // Step 2: Wait for form to load
        console.log('\nSTEP 2: Wait for research form to load\n');

        await page.waitForSelector('#research-form', { timeout: 10000 });
        console.log('✅ Research form found');

        await page.waitForSelector('#query', { timeout: 10000 });

        // Check what type of element the query field is
        const queryElementInfo = await page.evaluate(() => {
            const el = document.getElementById('query');
            return {
                tagName: el.tagName,
                type: el.type,
                id: el.id,
                placeholder: el.placeholder
            };
        });
        console.log('✅ Query element found:', queryElementInfo);

        await page.waitForSelector('#start-research-btn', { timeout: 10000 });
        console.log('✅ Submit button found');

        await takeScreenshot(page, '04-form-loaded');

        // Step 3: Fill the form
        console.log('\nSTEP 3: Fill research form\n');

        // Enter research query - handle textarea
        console.log('Entering research query...');

        // First clear the field completely
        await page.evaluate(() => {
            const textarea = document.getElementById('query');
            textarea.value = '';
            textarea.focus();
            // Trigger events to ensure React/Vue updates
            textarea.dispatchEvent(new Event('input', { bubbles: true }));
            textarea.dispatchEvent(new Event('change', { bubbles: true }));
        });

        // Click to focus
        await page.click('#query');

        // Wait a moment
        await new Promise(resolve => setTimeout(resolve, 500));

        // Now type the text
        await page.keyboard.type('Test research about AI safety', { delay: 100 });

        // Verify the text was entered
        const queryValue = await page.$eval('#query', el => el.value);
        console.log(`Entered research query: "${queryValue}"`);

        if (!queryValue || queryValue.trim() === '') {
            console.log('❌ Query was not entered, trying alternative method...');

            // Alternative method - set value directly
            await page.evaluate(() => {
                const textarea = document.getElementById('query');
                textarea.value = 'Test research about AI safety';
                textarea.dispatchEvent(new Event('input', { bubbles: true }));
                textarea.dispatchEvent(new Event('change', { bubbles: true }));
                textarea.dispatchEvent(new KeyboardEvent('keyup', { key: 'a' }));
            });

            const queryValue2 = await page.$eval('#query', el => el.value);
            console.log(`Alternative method result: "${queryValue2}"`);
        }

        // Wait a bit for any dynamic form updates
        await new Promise(resolve => setTimeout(resolve, 1000));

        await takeScreenshot(page, '05-form-filled');

        // Step 4: Check form values
        console.log('\nSTEP 4: Check form values\n');

        const formData = await page.evaluate(() => {
            const form = document.getElementById('research-form');
            const data = {
                query: document.getElementById('query')?.value,
                mode: document.querySelector('input[name="research_mode"]:checked')?.value,
                provider: document.getElementById('model_provider')?.value,
                model: document.getElementById('model_hidden')?.value || document.getElementById('model')?.value,
                searchEngine: document.getElementById('search_engine_hidden')?.value || document.getElementById('search_engine')?.value,
                submitButton: document.getElementById('start-research-btn')?.outerHTML
            };
            return data;
        });

        console.log('Form data:', JSON.stringify(formData, null, 2));

        // Step 5: Submit the form
        console.log('\nSTEP 5: Submit research form\n');

        // Set up request interception to monitor API calls
        await page.setRequestInterception(true);

        let apiCalled = false;
        let apiResponse = null;

        page.on('request', request => {
            if (request.url().includes('/api/start_research')) {
                apiCalled = true;
                console.log('🔍 API Request intercepted:');
                console.log('  URL:', request.url());
                console.log('  Method:', request.method());
                console.log('  Headers:', JSON.stringify(request.headers(), null, 2));
                if (request.postData()) {
                    console.log('  Body:', request.postData());
                }
            }
            request.continue();
        });

        page.on('response', async response => {
            if (response.url().includes('/api/start_research')) {
                apiResponse = response;
                console.log('📦 API Response received:');
                console.log('  Status:', response.status());
                console.log('  Status Text:', response.statusText());
                try {
                    const text = await response.text();
                    console.log('  Body:', text);
                } catch (e) {
                    console.log('  Body: <unable to read>');
                }
            }
        });

        // Check form submission handler
        const formInfo = await page.evaluate(() => {
            const form = document.getElementById('research-form');
            const submitBtn = document.getElementById('start-research-btn');
            return {
                formAction: form?.action,
                formMethod: form?.method,
                formOnSubmit: !!form?.onsubmit,
                buttonOnClick: !!submitBtn?.onclick,
                formEventListeners: form?._events || 'unknown'
            };
        });
        console.log('Form submission info:', formInfo);

        // Click submit button
        console.log('\nClicking submit button...');

        // Add console logging for form submission
        await page.evaluate(() => {
            const form = document.getElementById('research-form');
            const btn = document.getElementById('start-research-btn');

            // Log any form submit events
            if (form) {
                form.addEventListener('submit', (e) => {
                    console.log('FORM SUBMIT EVENT TRIGGERED!');
                    console.log('Form action:', e.target.action);
                    console.log('Form method:', e.target.method);
                    console.log('Event default prevented:', e.defaultPrevented);
                });
            }

            // Log button click
            if (btn) {
                btn.addEventListener('click', (e) => {
                    console.log('BUTTON CLICK EVENT TRIGGERED!');
                    console.log('Button type:', e.target.type);
                });
            }
        });

        // Use Promise.race to handle both navigation and potential error
        const submitPromise = Promise.race([
            page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 10000 }),
            new Promise(resolve => setTimeout(resolve, 5000)) // Fallback timeout
        ]);

        await page.click('#start-research-btn');

        // Wait for either navigation or timeout
        await submitPromise;

        await takeScreenshot(page, '06-after-submit');

        // Check results
        console.log('\nSTEP 6: Check results\n');

        const currentUrl = page.url();
        console.log('Current URL:', currentUrl);

        if (apiCalled) {
            console.log('✅ API was called');
            if (apiResponse) {
                console.log(`API Response status: ${apiResponse.status()}`);
                if (apiResponse.status() === 200) {
                    console.log('✅ API returned success');
                } else {
                    console.log('❌ API returned error');
                    success = false;
                }
            }
        } else {
            console.log('❌ API was not called');
            success = false;
        }

        // Check if we navigated to progress page
        if (currentUrl.includes('/progress/')) {
            console.log('✅ Successfully navigated to progress page');
        } else {
            console.log('❌ Did not navigate to progress page');

            // Check for any alerts (errors or otherwise)
            const allAlerts = await page.$$('.alert');
            if (allAlerts.length > 0) {
                console.log('\nFound alerts on page:');
                for (const alert of allAlerts) {
                    const text = await page.evaluate(el => el.textContent, alert);
                    const classes = await page.evaluate(el => el.className, alert);
                    console.log(`  - [${classes}]: ${text.trim()}`);
                }
            }

            // Check if form validation prevented submission
            const formValidation = await page.evaluate(() => {
                const form = document.getElementById('research-form');
                const query = document.getElementById('query');
                return {
                    formValid: form ? form.checkValidity() : null,
                    queryValid: query ? query.checkValidity() : null,
                    queryRequired: query ? query.hasAttribute('required') : null,
                    queryValue: query ? query.value : null
                };
            });
            console.log('\nForm validation state:', formValidation);

            success = false;
        }

        await takeScreenshot(page, '07-final-state');

    } catch (error) {
        console.error('\n💥 Test error:', error);
        success = false;

        // Try to take error screenshot
        if (browser) {
            try {
                const pages = await browser.pages();
                if (pages.length > 0) {
                    await takeScreenshot(pages[0], 'error-screenshot');
                }
            } catch (e) {
                console.error('Could not take error screenshot:', e.message);
            }
        }
    } finally {
        if (browser) {
            console.log('\n⏸️  Keeping browser open for 10 seconds for inspection...');
            await new Promise(resolve => setTimeout(resolve, 10000));
            await browser.close();
        }
    }

    console.log('\n' + '='.repeat(60));
    console.log(success ? '✅ Test completed successfully' : '❌ Test failed');
    console.log('='.repeat(60));

    return success;
}

// Run the test
testResearchSubmitDebug().then(success => {
    process.exit(success ? 0 : 1);
}).catch(error => {
    console.error('Fatal error:', error);
    process.exit(1);
});
