/**
 * Research Workflow Comprehensive Test
 * Tests the complete research lifecycle from submission to results
 * CI-compatible: Works in both local and CI environments
 */

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

const BASE_URL = 'http://127.0.0.1:5000';

async function testResearchWorkflow() {
    const isCI = !!process.env.CI;
    console.log(`🧪 Running research workflow test (CI mode: ${isCI})`);

    // Create screenshots directory
    const screenshotsDir = path.join(__dirname, 'screenshots');
    if (!fs.existsSync(screenshotsDir)) {
        fs.mkdirSync(screenshotsDir, { recursive: true });
    }

    const browser = await puppeteer.launch(getPuppeteerLaunchOptions());
    const page = await browser.newPage();
    const auth = new AuthHelper(page, BASE_URL);

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

    let testsPassed = 0;
    let testsFailed = 0;
    let testsSkipped = 0;

    try {
        // Setup: Authenticate
        console.log('🔐 Authenticating...');
        await auth.ensureAuthenticatedWithTimeout();
        console.log('✅ Authentication successful\n');

        // Test 1: Home page loads with research form
        console.log('📝 Test 1: Research form loads correctly');
        try {
            await page.goto(`${BASE_URL}/`, { waitUntil: 'domcontentloaded' });

            // Check for query input
            const queryInput = await page.$('#query, input[name="query"]');
            if (queryInput) {
                console.log('✅ Research form with query input found');
                testsPassed++;
            } else {
                console.log('❌ Query input not found');
                testsFailed++;
            }
        } catch (error) {
            console.log(`❌ Test 1 failed: ${error.message}`);
            testsFailed++;
        }

        // Test 2: Model configuration
        console.log('\n📝 Test 2: Model can be configured');
        try {
            const modelConfigured = await setupDefaultModel(page);
            if (modelConfigured) {
                console.log('✅ Model configuration successful');
                testsPassed++;
            } else {
                console.log('⚠️  Model configuration may have issues (continuing)');
                testsSkipped++;
            }
        } catch (error) {
            console.log(`⚠️  Model configuration error: ${error.message}`);
            testsSkipped++;
        }

        // Test 3: Form fields are accessible
        console.log('\n📝 Test 3: Form fields are accessible');
        try {
            const formElements = await page.evaluate(() => {
                return {
                    hasQueryInput: !!document.querySelector('#query, input[name="query"]'),
                    hasSubmitButton: !!document.querySelector('button[type="submit"]'),
                    hasModelSelect: !!document.querySelector('#model, select[name="model"]'),
                    hasSearchEngineSelect: !!document.querySelector('#search_engine, select[name="search_engine"]')
                };
            });

            const missingElements = [];
            if (!formElements.hasQueryInput) missingElements.push('query input');
            if (!formElements.hasSubmitButton) missingElements.push('submit button');

            if (missingElements.length === 0) {
                console.log('✅ All essential form elements found');
                testsPassed++;
            } else {
                console.log(`⚠️  Missing elements: ${missingElements.join(', ')}`);
                testsFailed++;
            }
        } catch (error) {
            console.log(`❌ Test 3 failed: ${error.message}`);
            testsFailed++;
        }

        // Test 4: Query can be entered
        console.log('\n📝 Test 4: Query input accepts text');
        try {
            await page.goto(`${BASE_URL}/`, { waitUntil: 'domcontentloaded' });

            const queryInput = await page.$('#query, input[name="query"]');
            if (queryInput) {
                // Set value atomically to avoid race with page JS event handlers
                await page.$eval('#query', (el) => {
                    el.value = 'Test research query for workflow test';
                    el.dispatchEvent(new Event('input', { bubbles: true }));
                });

                const value = await page.$eval('#query, input[name="query"]', el => el.value);
                if (value.includes('Test research query')) {
                    console.log('✅ Query input accepts text correctly');
                    testsPassed++;
                } else {
                    console.log(`❌ Query value mismatch: ${value}`);
                    testsFailed++;
                }
            } else {
                console.log('❌ Query input not found');
                testsFailed++;
            }
        } catch (error) {
            console.log(`❌ Test 4 failed: ${error.message}`);
            testsFailed++;
        }

        // Test 5: Research submission workflow
        console.log('\n📝 Test 5: Research submission workflow');
        try {
            await page.goto(`${BASE_URL}/`, { waitUntil: 'domcontentloaded' });

            // Configure model
            await setupDefaultModel(page);

            // Enter query
            await page.waitForSelector('#query', { timeout: 10000 });
            await page.type('#query', 'What is machine learning?');

            // Take screenshot before submission
            await page.screenshot({
                path: path.join(screenshotsDir, 'research_workflow_before_submit.png')
            });

            // Try to submit
            const submitButton = await page.$('button[type="submit"]');
            if (submitButton) {
                // Click and wait for response
                try {
                    await Promise.race([
                        Promise.all([
                            page.waitForNavigation({ waitUntil: 'domcontentloaded', timeout: 30000 }),
                            submitButton.click()
                        ]),
                        new Promise((_, reject) => setTimeout(() => reject(new Error('Navigation timeout')), 30000))
                    ]);
                } catch (navError) {
                    // Check if we're on a research page anyway
                    await new Promise(resolve => setTimeout(resolve, 3000));
                }

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

                // Take screenshot after submission attempt
                await page.screenshot({
                    path: path.join(screenshotsDir, 'research_workflow_after_submit.png')
                });

                if (url.includes('/research/') || url.includes('/progress/')) {
                    console.log('✅ Research submission navigated to research page');
                    testsPassed++;
                } else if (url === `${BASE_URL}/` || url.endsWith('/')) {
                    // Still on home page - might be validation error or config issue
                    const errorMsg = await page.evaluate(() => {
                        const alert = document.querySelector('.alert-danger, .error-message');
                        return alert ? alert.textContent : null;
                    });
                    if (errorMsg) {
                        console.log(`⚠️  Submission blocked: ${errorMsg.trim()}`);
                    } else {
                        console.log('⚠️  Stayed on home page (may need model configuration)');
                    }
                    testsSkipped++;
                } else {
                    console.log(`⚠️  Unexpected URL after submission: ${url}`);
                    testsSkipped++;
                }
            } else {
                console.log('❌ Submit button not found');
                testsFailed++;
            }
        } catch (error) {
            console.log(`⚠️  Test 5 had issues: ${error.message}`);
            testsSkipped++;
        }

        // Test 6: History page shows research history
        console.log('\n📝 Test 6: History page is accessible');
        try {
            await page.goto(`${BASE_URL}/history/`, { waitUntil: 'domcontentloaded' });

            const hasHistoryContent = await page.evaluate(() => {
                const body = document.body;
                return body && (
                    body.innerText.includes('History') ||
                    body.innerText.includes('history') ||
                    body.innerText.includes('Research') ||
                    body.innerText.includes('No research')
                );
            });

            if (hasHistoryContent) {
                console.log('✅ History page loads correctly');
                testsPassed++;
            } else {
                console.log('⚠️  History page content unclear');
                testsPassed++;
            }
        } catch (error) {
            console.log(`❌ Test 6 failed: ${error.message}`);
            testsFailed++;
        }

        // Test 7: Navigation between pages works
        console.log('\n📝 Test 7: Navigation between workflow pages');
        try {
            const pages = [
                { path: '/', name: 'Home' },
                { path: '/settings/', name: 'Settings' },
                { path: '/history/', name: 'History' },
                { path: '/metrics/', name: 'Metrics' }
            ];

            let navSuccess = 0;
            for (const pageInfo of pages) {
                try {
                    await page.goto(`${BASE_URL}${pageInfo.path}`, {
                        waitUntil: 'domcontentloaded',
                        timeout: 15000
                    });

                    // Check we didn't get redirected to login
                    if (!page.url().includes('/auth/login')) {
                        navSuccess++;
                    }
                } catch (e) {
                    console.log(`  ⚠️  Navigation to ${pageInfo.name} failed`);
                }
            }

            if (navSuccess >= 3) {
                console.log(`✅ Navigation works (${navSuccess}/${pages.length} pages accessible)`);
                testsPassed++;
            } else {
                console.log(`⚠️  Navigation issues (${navSuccess}/${pages.length} pages)`);
                testsFailed++;
            }
        } catch (error) {
            console.log(`❌ Test 7 failed: ${error.message}`);
            testsFailed++;
        }

        // Summary
        console.log('\n' + '='.repeat(50));
        console.log('📊 RESEARCH WORKFLOW TEST SUMMARY');
        console.log('='.repeat(50));
        console.log(`✅ Passed: ${testsPassed}`);
        console.log(`⏭️  Skipped: ${testsSkipped}`);
        console.log(`❌ Failed: ${testsFailed}`);
        console.log(`📊 Success Rate: ${Math.round((testsPassed / (testsPassed + testsFailed + testsSkipped)) * 100)}%`);

        // Take final screenshot
        await page.screenshot({
            path: path.join(screenshotsDir, 'research_workflow_final.png'),
            fullPage: true
        });

        if (testsFailed > 0) {
            console.log('\n⚠️  Too many workflow tests failed');
            process.exit(1);
        }

        console.log('\n🎉 Research workflow tests completed!');
        process.exit(0);

    } catch (error) {
        console.error('\n❌ Test suite failed:', error.message);

        try {
            await page.screenshot({
                path: path.join(screenshotsDir, `research_workflow_error_${Date.now()}.png`),
                fullPage: true
            });
            console.log('📸 Error screenshot saved');
        } catch (screenshotError) {
            console.log('Could not save screenshot:', screenshotError.message);
        }

        process.exit(1);
    } finally {
        await browser.close();
    }
}

// Run the test
testResearchWorkflow().catch(error => {
    console.error('Fatal error:', error);
    process.exit(1);
});
