/**
 * Test for autocomplete selection behavior
 * Tests that clicking on autocomplete suggestions properly selects the item
 * for both LLM model and search engine dropdowns
 */

const puppeteer = require('puppeteer');
const AuthHelper = require('./auth_helper');

// Default timeout for tests
const TEST_TIMEOUT = 30000;

// Test configuration
const config = {
    baseUrl: process.env.BASE_URL || 'http://127.0.0.1:5000',
    headless: process.env.HEADLESS !== 'false',
    slowMo: parseInt(process.env.SLOW_MO || '0', 10),
    devtools: process.env.DEVTOOLS === 'true'
};

// Function to run tests when file is executed directly
async function runTests() {
    let browser;
    let allTestsPassed = true;

    try {
        console.log('\n📋 Autocomplete Selection Tests\n');
        console.log(`Configuration: headless=${config.headless}, baseUrl=${config.baseUrl}\n`);

        browser = await puppeteer.launch({
            headless: config.headless,
            slowMo: config.slowMo,
            devtools: config.devtools,
            args: [
                '--no-sandbox',
                '--disable-setuid-sandbox',
                '--disable-dev-shm-usage',
                '--disable-web-security',
                '--disable-features=IsolateOrigins,site-per-process'
            ]
        });

        // Test 1: LLM model autocomplete selection
        console.log('🧪 Test 1: Should select LLM model from autocomplete when clicked');
        try {
            const page = await browser.newPage();
            await page.setViewport({ width: 1280, height: 800 });
            const authHelper = new AuthHelper(page, config.baseUrl);
            page.setDefaultTimeout(TEST_TIMEOUT);

            await authHelper.ensureAuthenticated();
            await page.goto(`${config.baseUrl}/`, { waitUntil: 'domcontentloaded' });

            // Wait for and click the model input
            await page.waitForSelector('#model', { visible: true });
            await page.click('#model');

            // Wait for dropdown to appear
            await page.waitForSelector('#model-dropdown-list', { visible: true });
            await page.waitForSelector('.ldr-custom-dropdown-item', { visible: true });

            const dropdownItems = await page.$$('.ldr-custom-dropdown-item');
            console.log(`  Found ${dropdownItems.length} model options`);

            if (dropdownItems.length > 0) {
                // Get the first item's text
                const firstItemText = await page.evaluate(el => el.textContent, dropdownItems[0]);

                // Clear input and type part of the model name
                await page.evaluate(() => { document.getElementById('model').value = ''; });
                const searchText = firstItemText.substring(0, Math.min(3, firstItemText.length));
                await page.type('#model', searchText);
                console.log(`  Typed "${searchText}" to filter models`);

                await new Promise(resolve => setTimeout(resolve, 500));

                // Check if dropdown is still visible
                const dropdownVisible = await page.evaluate(() => {
                    const dropdown = document.getElementById('model-dropdown-list');
                    return dropdown && window.getComputedStyle(dropdown).display !== 'none';
                });

                if (!dropdownVisible) {
                    console.log('  Dropdown closed, reopening...');
                    await page.click('#model');
                    await page.waitForSelector('#model-dropdown-list', { visible: true });
                }

                // Click the first filtered item
                const filteredItems = await page.$$('.ldr-custom-dropdown-item');
                if (filteredItems.length > 0) {
                    const itemToClick = await page.evaluate(el => el.textContent, filteredItems[0]);
                    console.log(`  Clicking on: "${itemToClick}"`);
                    await filteredItems[0].click();
                    await new Promise(resolve => setTimeout(resolve, 500));

                    // Check the selected value
                    const selectedModel = await page.evaluate(() => document.getElementById('model').value);
                    const hiddenValue = await page.evaluate(() => {
                        const hidden = document.getElementById('model_hidden');
                        return hidden ? hidden.value : null;
                    });

                    console.log(`  Display value: "${selectedModel}"`);
                    console.log(`  Hidden value: "${hiddenValue}"`);

                    if (selectedModel && selectedModel !== searchText) {
                        console.log('  ✅ Model autocomplete selection works correctly');
                    } else {
                        console.log('  ❌ Model was not properly selected from autocomplete');
                        console.log('     Issue confirmed: Clicking autocomplete does not select the item');
                        allTestsPassed = false;
                    }
                } else {
                    console.log('  ⚠️ No filtered items found');
                }
            } else {
                console.log('  ⚠️ No model options available');
            }

            await page.close();
        } catch (error) {
            console.error(`  ❌ Test failed: ${error.message}`);
            allTestsPassed = false;
        }

        // Test 2: Search engine autocomplete selection
        console.log('\n🧪 Test 2: Should select search engine from autocomplete when clicked');
        try {
            const page = await browser.newPage();
            await page.setViewport({ width: 1280, height: 800 });
            const authHelper = new AuthHelper(page, config.baseUrl);
            page.setDefaultTimeout(TEST_TIMEOUT);

            await authHelper.ensureAuthenticated();
            await page.goto(`${config.baseUrl}/`, { waitUntil: 'domcontentloaded' });

            // Wait for and click the search engine input
            await page.waitForSelector('#search_engine', { visible: true });
            await page.click('#search_engine');

            // Wait for dropdown to appear
            await page.waitForSelector('#search-engine-dropdown-list', { visible: true });

            await page.waitForFunction(() => {
                const items = document.querySelectorAll('#search-engine-dropdown-list .ldr-custom-dropdown-item');
                return items.length > 0;
            });

            const dropdownItems = await page.$$('#search-engine-dropdown-list .ldr-custom-dropdown-item');
            console.log(`  Found ${dropdownItems.length} search engine options`);

            if (dropdownItems.length > 0) {
                // Get the first item's text
                const firstItemText = await page.evaluate(el => el.textContent, dropdownItems[0]);

                // Clear input and type part of the search engine name
                await page.evaluate(() => { document.getElementById('search_engine').value = ''; });
                const searchText = firstItemText.substring(0, Math.min(3, firstItemText.length));
                await page.type('#search_engine', searchText);
                console.log(`  Typed "${searchText}" to filter search engines`);

                await new Promise(resolve => setTimeout(resolve, 500));

                // Click the first filtered item
                const filteredItems = await page.$$('#search-engine-dropdown-list .ldr-custom-dropdown-item');
                if (filteredItems.length > 0) {
                    const itemToClick = await page.evaluate(el => el.textContent, filteredItems[0]);
                    console.log(`  Clicking on: "${itemToClick}"`);
                    await filteredItems[0].click();
                    await new Promise(resolve => setTimeout(resolve, 500));

                    // Check the selected value
                    const selectedEngine = await page.evaluate(() => document.getElementById('search_engine').value);
                    const hiddenValue = await page.evaluate(() => {
                        const hidden = document.getElementById('search_engine_hidden');
                        return hidden ? hidden.value : null;
                    });

                    console.log(`  Display value: "${selectedEngine}"`);
                    console.log(`  Hidden value: "${hiddenValue}"`);

                    if (selectedEngine && selectedEngine !== searchText) {
                        console.log('  ✅ Search engine autocomplete selection works correctly');
                    } else {
                        console.log('  ❌ Search engine was not properly selected from autocomplete');
                        console.log('     Issue confirmed: Clicking autocomplete does not select the item');
                        allTestsPassed = false;
                    }
                } else {
                    console.log('  ⚠️ No filtered items found');
                }
            } else {
                console.log('  ⚠️ No search engine options available');
            }

            await page.close();
        } catch (error) {
            console.error(`  ❌ Test failed: ${error.message}`);
            allTestsPassed = false;
        }

        // Test 3: Keyboard navigation
        console.log('\n🧪 Test 3: Should verify keyboard navigation works for selection');
        try {
            const page = await browser.newPage();
            await page.setViewport({ width: 1280, height: 800 });
            const authHelper = new AuthHelper(page, config.baseUrl);
            page.setDefaultTimeout(TEST_TIMEOUT);

            await authHelper.ensureAuthenticated();
            await page.goto(`${config.baseUrl}/`, { waitUntil: 'domcontentloaded' });

            // Test with model dropdown
            await page.waitForSelector('#model', { visible: true });
            await page.click('#model');
            await page.waitForSelector('#model-dropdown-list .ldr-custom-dropdown-item', { visible: true });

            const itemCount = await page.evaluate(() => {
                return document.querySelectorAll('#model-dropdown-list .ldr-custom-dropdown-item').length;
            });
            console.log(`  Found ${itemCount} items in dropdown`);

            if (itemCount > 0) {
                // Use arrow key to navigate
                await page.keyboard.press('ArrowDown');

                // Check if first item is highlighted
                const firstItemActive = await page.evaluate(() => {
                    const items = document.querySelectorAll('#model-dropdown-list .ldr-custom-dropdown-item');
                    return items[0] && items[0].classList.contains('active');
                });
                console.log(`  First item highlighted: ${firstItemActive}`);

                // Press Enter to select
                await page.keyboard.press('Enter');
                await new Promise(resolve => setTimeout(resolve, 500));

                // Check the selected value
                const selectedModel = await page.evaluate(() => document.getElementById('model').value);

                if (selectedModel) {
                    console.log(`  ✅ Keyboard navigation selected: "${selectedModel}"`);
                } else {
                    console.log('  ❌ Keyboard navigation failed to select');
                    allTestsPassed = false;
                }
            }

            await page.close();
        } catch (error) {
            console.error(`  ❌ Test failed: ${error.message}`);
            allTestsPassed = false;
        }

        // Test 4: Type and Enter behavior (reveals the issue)
        console.log('\n🧪 Test 4: Type and immediate Enter (reveals the issue)');
        try {
            const page = await browser.newPage();
            await page.setViewport({ width: 1280, height: 800 });
            const authHelper = new AuthHelper(page, config.baseUrl);
            page.setDefaultTimeout(TEST_TIMEOUT);

            await authHelper.ensureAuthenticated();
            await page.goto(`${config.baseUrl}/`, { waitUntil: 'domcontentloaded' });

            // Open model dropdown
            await page.waitForSelector('#model', { visible: true });
            await page.click('#model');
            await page.waitForSelector('#model-dropdown-list .ldr-custom-dropdown-item', { visible: true });

            // Get a model name to type
            const firstModelText = await page.evaluate(() => {
                const firstItem = document.querySelector('#model-dropdown-list .ldr-custom-dropdown-item');
                return firstItem ? firstItem.textContent : null;
            });

            if (firstModelText) {
                // Clear and type part of the model name
                await page.evaluate(() => { document.getElementById('model').value = ''; });
                const searchText = firstModelText.substring(0, Math.min(5, firstModelText.length));
                await page.type('#model', searchText);
                console.log(`  Typed "${searchText}"`);

                await new Promise(resolve => setTimeout(resolve, 300));

                // Press Enter without using arrow keys
                await page.keyboard.press('Enter');
                await new Promise(resolve => setTimeout(resolve, 500));

                // Check what was selected
                const selectedValue = await page.evaluate(() => document.getElementById('model').value);

                if (selectedValue === searchText) {
                    console.log(`  ⚠️ Enter key only kept typed text: "${selectedValue}"`);
                    console.log('  📝 Issue confirmed: User must either:');
                    console.log('     - Click on the autocomplete suggestion');
                    console.log('     - Use arrow keys then Enter');
                    console.log('     - Typing and pressing Enter alone does NOT select from autocomplete');
                } else {
                    console.log(`  ✅ Enter key selected from autocomplete: "${selectedValue}"`);
                }
            }

            await page.close();
        } catch (error) {
            console.error(`  ❌ Test failed: ${error.message}`);
            allTestsPassed = false;
        }

    } catch (error) {
        console.error(`\n❌ Test suite failed: ${error.message}`);
        allTestsPassed = false;
    } finally {
        if (browser) {
            await browser.close();
        }

        console.log('\n' + '='.repeat(60));
        console.log('📊 Test Summary:');
        console.log('  - Model autocomplete: Tests if clicking selects the item');
        console.log('  - Search engine autocomplete: Tests if clicking selects the item');
        console.log('  - Keyboard navigation: Tests arrow key + Enter selection');
        console.log('  - Type and Enter: Reveals if typing + Enter selects first match');
        console.log('='.repeat(60));

        if (allTestsPassed) {
            console.log('✅ All tests completed successfully\n');
            process.exit(0);
        } else {
            console.log('❌ Some tests revealed issues with autocomplete selection\n');
            console.log('The tests confirm that when typing in the autocomplete fields:');
            console.log('1. The dropdown appears and filters correctly');
            console.log('2. However, pressing Enter does not select the first match');
            console.log('3. Users must either click or use arrow keys to select\n');
            process.exit(1);
        }
    }
}

// Run tests if this file is executed directly
if (require.main === module) {
    runTests().catch(error => {
        console.error('Fatal error:', error);
        process.exit(1);
    });
}

module.exports = { runTests };
