/**
 * Research Form Validation Test
 * Tests that the research form correctly validates input
 * CI-compatible: Works in both local and CI environments
 */

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

// NAVIGATION NOTE: Using 'domcontentloaded' instead of 'networkidle2' for page.goto()
// because networkidle2 waits for no network activity for 500ms, but WebSocket
// connections and background polling keep the network active, causing infinite hangs.
// See: test_login_validation.js and auth_helper.js for detailed explanation.
async function testResearchFormValidation() {
    const isCI = !!process.env.CI;
    console.log(`🧪 Running research form validation test (CI mode: ${isCI})`);
    // Create screenshots directory if it doesn't exist
    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 baseUrl = 'http://127.0.0.1:5000';

    // Increase default timeout in CI
    if (isCI) {
        page.setDefaultTimeout(60000);
        page.setDefaultNavigationTimeout(60000);
    }

    let testsPassed = 0;
    let testsFailed = 0;

    console.log('🧪 Starting research form validation tests...\n');

    try {
        // Authenticate (CI uses pre-created user for speed)
        console.log('📋 Setup: Authenticating...');
        const authHelper = new AuthHelper(page, baseUrl);

        try {
            // Use ensureAuthenticated which tries CI user first, then falls back to registration
            await authHelper.ensureAuthenticatedWithTimeout();
            console.log('✅ Authenticated\n');
        } catch (authError) {
            console.log(`⚠️  Could not authenticate: ${authError.message}`);
            console.log('❌ Cannot authenticate - skipping research form tests');
            await browser.close();
            process.exit(1);
        }

        // Navigate to home page (research form)
        console.log('📄 Navigating to research page...');
        await page.goto(`${baseUrl}/`, {
            waitUntil: 'domcontentloaded',
            timeout: 30000
        });

        const currentUrl = page.url();
        if (currentUrl.includes('/auth/login')) {
            console.log(`❌ Redirected to login - not authenticated`);
            throw new Error('Not authenticated');
        }
        console.log('✅ Research page loaded\n');

        // Test 1: Research form exists
        console.log('📋 Test 1: Research form exists');

        const researchForm = await page.$('#research-form, form[action*="research"], form');
        if (researchForm) {
            console.log('✅ Research form found');
            testsPassed++;
        } else {
            console.log('❌ Research form not found');
            testsFailed++;
        }

        // Test 2: Query input exists and is required
        console.log('\n📋 Test 2: Query input validation');

        // Look for query textarea or input
        const queryInput = await page.$('textarea[name="query"], input[name="query"], #query, textarea#research-query');

        if (queryInput) {
            const tagName = await page.evaluate(el => el.tagName.toLowerCase(), queryInput);
            const isRequired = await page.evaluate(el => el.required || el.hasAttribute('required'), queryInput);
            const placeholder = await page.evaluate(el => el.placeholder, queryInput);

            console.log(`   Query input type: ${tagName}, required: ${isRequired}`);
            console.log(`   Placeholder: "${placeholder?.substring(0, 40)}..."`);

            console.log('✅ Query input found');
            testsPassed++;

            // Test 3: Empty query validation
            console.log('\n📋 Test 3: Empty query handling');

            // Clear the query input
            await page.evaluate(el => { el.value = ''; }, queryInput);

            // Check if submit button is disabled or if form prevents submission
            const submitBtn = await page.$('button[type="submit"], #start-research, .ldr-btn-research');

            if (submitBtn) {
                const isDisabled = await page.evaluate(el => el.disabled, submitBtn);
                console.log(`   Submit button disabled: ${isDisabled}`);

                if (isDisabled) {
                    console.log('✅ Submit button disabled for empty query');
                    testsPassed++;
                } else {
                    // Check if there's client-side validation
                    console.log('⚠️  Submit button enabled - empty query handled server-side');
                    // This is still acceptable
                }
            }
        } else {
            console.log('⚠️  Query input not found with expected selectors');
        }

        // Test 4: Check for number inputs (iterations, questions)
        console.log('\n📋 Test 4: Numeric inputs have constraints');

        const numberInputs = await page.$$('input[type="number"]');
        console.log(`   Found ${numberInputs.length} number inputs`);

        for (const input of numberInputs.slice(0, 3)) {
            const attrs = await page.evaluate(el => ({
                name: el.name || el.id,
                min: el.min,
                max: el.max,
                value: el.value
            }), input);

            if (attrs.name) {
                console.log(`   ✓ "${attrs.name}": min=${attrs.min || 'none'}, max=${attrs.max || 'none'}, value=${attrs.value}`);
            }
        }

        if (numberInputs.length > 0) {
            // Check that at least one has min attribute
            let hasMinConstraint = false;
            for (const input of numberInputs) {
                const min = await page.evaluate(el => el.min, input);
                if (min) {
                    hasMinConstraint = true;
                    break;
                }
            }

            if (hasMinConstraint) {
                console.log('✅ Number inputs have min constraints');
                testsPassed++;
            } else {
                console.log('⚠️  Number inputs may lack min constraints');
            }
        }

        // Test 5: No JavaScript errors on page
        console.log('\n📋 Test 5: No critical JavaScript errors');

        const jsErrors = [];
        page.on('pageerror', err => jsErrors.push(err.message));

        // Interact with the form to trigger any lazy-loaded JS
        if (queryInput) {
            await queryInput.click();
            await page.keyboard.type('test query', { delay: 30 });
            await new Promise(resolve => setTimeout(resolve, 500));
        }

        if (jsErrors.length === 0) {
            console.log('✅ No JavaScript page errors');
            testsPassed++;
        } else {
            console.log(`❌ ${jsErrors.length} JavaScript error(s):`);
            jsErrors.slice(0, 2).forEach(err => console.log(`   - ${err.substring(0, 80)}`));
            testsFailed++;
        }

        // Test 6: Form structure check
        console.log('\n📋 Test 6: Form has expected structure');

        const formElements = await page.$$('select, input[type="radio"], .ldr-dropdown, .custom-dropdown');
        console.log(`   Found ${formElements.length} selection elements (dropdowns, radios)`);

        if (formElements.length > 0) {
            console.log('✅ Form has selection elements for configuration');
            testsPassed++;
        } else {
            console.log('⚠️  Form may be missing configuration options');
        }

        // Take a screenshot (skip in CI)
        if (!isCI) {
            await page.screenshot({
                path: path.join(screenshotsDir, 'research_form_validation_test.png'),
                fullPage: true
            });
            console.log('\n📸 Screenshot saved to screenshots/research_form_validation_test.png');
        }

        // Summary
        console.log('\n' + '='.repeat(50));
        console.log(`📊 Test Summary: ${testsPassed} passed, ${testsFailed} failed`);
        console.log('='.repeat(50));

        if (testsFailed > 0) {
            throw new Error(`${testsFailed} test(s) failed`);
        }

        console.log('\n🎉 All research form validation tests passed!');

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

        // Take error screenshot (skip in CI)
        if (!isCI) {
            try {
                await page.screenshot({
                    path: path.join(screenshotsDir, 'research_form_validation_error.png'),
                    fullPage: true
                });
                console.log('📸 Error screenshot saved');
            } catch (screenshotError) {
                console.log('⚠️  Could not take error screenshot:', screenshotError.message);
            }
        }

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

    await browser.close();
    console.log('\n✅ Test completed successfully');
    process.exit(0);
}

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