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

// Color codes for terminal output
const colors = {
    reset: '\x1b[0m',
    bright: '\x1b[1m',
    red: '\x1b[31m',
    green: '\x1b[32m',
    yellow: '\x1b[33m',
    blue: '\x1b[34m'
};

function log(message, type = 'info') {
    const timestamp = new Date().toISOString();
    const prefix = {
        info: `${colors.blue}ℹ`,
        success: `${colors.green}✓`,
        error: `${colors.red}ERROR:`,
        warn: `${colors.yellow}⚠`
    }[type] || '';

    console.log(`${prefix}[${timestamp}] ${message}${colors.reset}`);
}

(async () => {
    let browser;
    let authHelper;

    try {
        // Test configuration
        const TEST_API_KEY_1 = 'enter-save-test-key-12345';
        const TEST_API_KEY_2 = 'enter-save-changed-67890';
        const BASE_URL = 'http://localhost:5000';

        log(`${colors.bright}=== Testing API Key Save with Enter Key ===${colors.reset}`, 'info');

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

        log('Browser launched in visible mode', 'success');

        const page = await browser.newPage();
        await page.setViewport({ width: 1920, height: 1080 });

        // Set up console logging
        page.on('console', msg => {
            const text = msg.text();
            if (!text.includes('Failed to load resource')) {
                log(`Browser console: ${text}`, 'info');
            }
        });

        // Listen for page dialogs (alerts, confirms)
        page.on('dialog', async dialog => {
            log(`Dialog appeared: ${dialog.message()}`, 'warn');
            await dialog.accept();
        });

        // Initialize auth helper
        authHelper = new AuthHelper(page);

        // Create test user
        const timestamp = Date.now();
        const testUsername = `enter_test_${timestamp}`;
        const testPassword = 'testpass123';

        log(`Creating user: ${testUsername}`, 'info');

        // Register and login
        await authHelper.register(testUsername, testPassword);
        const isAuthenticated = await authHelper.isLoggedIn();
        if (!isAuthenticated) {
            throw new Error('Failed to authenticate after registration');
        }
        log('User authenticated successfully', 'success');

        // Navigate to settings page
        log('Navigating to settings page...', 'info');
        await page.goto(`${BASE_URL}/settings`, { waitUntil: 'networkidle2' });

        // Wait a bit for page to fully load
        await new Promise(resolve => setTimeout(resolve, 2000));

        // Take initial screenshot
        await page.screenshot({
            path: `/tmp/enter_key_test_initial_${timestamp}.png`,
            fullPage: false
        });
        log('Screenshot saved: Initial settings page', 'info');

        // Find the API key input field
        log('Looking for OpenAI Endpoint API key field...', 'info');

        const apiKeySelectors = [
            'input[name="llm.openai_endpoint.api_key"]',
            'input[id="llm.openai_endpoint.api_key"]',
            'input[data-setting="llm.openai_endpoint.api_key"]',
            '#llm\\.openai_endpoint\\.api_key'
        ];

        let apiKeyInput = null;
        for (const selector of apiKeySelectors) {
            try {
                apiKeyInput = await page.$(selector);
                if (apiKeyInput) {
                    log(`Found API key input with selector: ${selector}`, 'success');
                    break;
                }
            } catch (e) {
                // Continue with next selector
            }
        }

        if (!apiKeyInput) {
            throw new Error('Could not find OpenAI Endpoint API key input field');
        }

        // Scroll the input into view
        await apiKeyInput.evaluate(el => el.scrollIntoView({ behavior: 'smooth', block: 'center' }));
        await new Promise(resolve => setTimeout(resolve, 500));

        // Clear any existing value and type the first API key
        log(`Clearing field and typing API key: ${TEST_API_KEY_1}`, 'info');
        await apiKeyInput.click({ clickCount: 3 });
        await page.keyboard.press('Backspace');
        await apiKeyInput.type(TEST_API_KEY_1);

        // Take screenshot before pressing Enter
        await page.screenshot({
            path: `/tmp/enter_key_test_before_enter_${timestamp}.png`,
            fullPage: false
        });
        log('Screenshot saved: Before pressing Enter', 'info');

        // Press Enter to save
        log('Pressing Enter to save...', 'info');
        await page.keyboard.press('Enter');

        // Wait for any save operation to complete
        await new Promise(resolve => setTimeout(resolve, 2000));

        // Take screenshot after Enter
        await page.screenshot({
            path: `/tmp/enter_key_test_after_enter_${timestamp}.png`,
            fullPage: false
        });
        log('Screenshot saved: After pressing Enter', 'info');

        // Check for any success messages or indicators
        const successIndicators = [
            '.alert-success',
            '.success-message',
            '[class*="success"]',
            '.saved-indicator',
            '.toast-success'
        ];

        let successFound = false;
        for (const selector of successIndicators) {
            const element = await page.$(selector);
            if (element) {
                const text = await element.evaluate(el => el.textContent);
                log(`Success indicator found: ${text}`, 'success');
                successFound = true;
                break;
            }
        }

        // Check if the value persisted by reloading
        log('Reloading page to check persistence...', 'info');
        await page.reload({ waitUntil: 'networkidle2' });
        await new Promise(resolve => setTimeout(resolve, 2000));

        // Find the input again
        apiKeyInput = null;
        for (const selector of apiKeySelectors) {
            apiKeyInput = await page.$(selector);
            if (apiKeyInput) break;
        }

        if (apiKeyInput) {
            const currentValue = await apiKeyInput.evaluate(el => el.value);
            log(`Value after reload: ${currentValue ? '***' + currentValue.slice(-5) : 'empty'}`, 'info');

            // Now try the second API key
            log(`Trying second API key: ${TEST_API_KEY_2}`, 'info');
            await apiKeyInput.click({ clickCount: 3 });
            await page.keyboard.press('Backspace');
            await apiKeyInput.type(TEST_API_KEY_2);

            // Try different save methods
            log('Testing different save triggers...', 'info');

            // Method 1: Press Enter
            log('Method 1: Pressing Enter', 'info');
            await page.keyboard.press('Enter');
            await new Promise(resolve => setTimeout(resolve, 1000));

            // Method 2: Tab away (blur event)
            log('Method 2: Tabbing away from field', 'info');
            await page.keyboard.press('Tab');
            await new Promise(resolve => setTimeout(resolve, 1000));

            // Method 3: Click elsewhere
            log('Method 3: Clicking elsewhere on page', 'info');
            await page.click('body');
            await new Promise(resolve => setTimeout(resolve, 1000));
        }

        // Check if there's a form around the input
        const formInfo = await page.evaluate(() => {
            const input = document.querySelector('input[name="llm.openai_endpoint.api_key"]');
            if (!input) return null;

            const form = input.closest('form');
            return {
                hasForm: !!form,
                formAction: form?.action,
                formMethod: form?.method,
                inputType: input.type,
                hasOnChange: !!input.onchange,
                hasOnKeyPress: !!input.onkeypress,
                dataAttributes: Object.keys(input.dataset || {})
            };
        });

        log(`Form analysis: ${JSON.stringify(formInfo, null, 2)}`, 'info');

        // Final screenshot
        await page.screenshot({
            path: `/tmp/enter_key_test_final_${timestamp}.png`,
            fullPage: false
        });
        log('Screenshot saved: Final state', 'info');

        log('Test completed - check screenshots to see results', 'success');
        log('Note: Browser is left open for manual inspection', 'info');

        // Keep browser open for manual inspection
        log('Browser will remain open for 30 seconds...', 'info');
        await new Promise(resolve => setTimeout(resolve, 30000));

    } catch (error) {
        log(`Test failed: ${error.message}`, 'error');
        console.error(error);

        // Take error screenshot
        if (browser) {
            const page = (await browser.pages())[0];
            if (page) {
                await page.screenshot({
                    path: `/tmp/enter_key_test_error_${Date.now()}.png`,
                    fullPage: false
                });
                log('Error screenshot saved', 'info');
            }
        }

        process.exit(1);
    } finally {
        if (browser) {
            await browser.close();
            log('Browser closed', 'success');
        }
    }
})();
