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

(async () => {
    const browser = await puppeteer.launch(getPuppeteerLaunchOptions());

    const page = await browser.newPage();

    // Log console errors
    page.on('console', msg => {
        if (msg.type() === 'error') {
            console.log(`  Browser error: ${msg.text()}`);
        }
    });

    try {
        // Register and login
        const auth = new AuthHelper(page);
        const username = 'metrics_' + Date.now();
        const password = 'T3st!Secure#2024$LDR';

        console.log('Creating user:', username);
        await auth.register(username, password);

        console.log('\n=== TESTING LLM DIRECTLY FIRST ===\n');

        // First make a direct LLM API call to generate some early metrics
        await page.evaluate(async () => {
            try {
                const response = await fetch('/api/v1/quick_summary', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        query: 'What is JavaScript? Give a very brief answer.',
                        iterations: 1,
                        search_tool: 'wikipedia'
                    })
                });

                console.log('API Response status:', response.status);
                console.log('API Response headers:', response.headers);

                let data;
                const contentType = response.headers.get('content-type');
                if (contentType && contentType.includes('application/json')) {
                    data = await response.json();
                } else {
                    data = await response.text();
                }

                console.log('LLM API Response:', data);

                if (response.ok && typeof data === 'object' && data.summary) {
                    console.log('✅ LLM query successful, tokens should be tracked');
                    console.log('Summary preview:', data.summary.substring(0, 100) + '...');
                } else {
                    console.log('❌ LLM query failed with status:', response.status);
                    console.log('Error details:', data);
                }
            } catch (error) {
                console.log('Error calling LLM API:', error.toString());
            }
        });

        // Wait for metrics to be processed
        await new Promise(resolve => setTimeout(resolve, 2000));

        console.log('\n=== CHECKING INITIAL METRICS ===\n');

        // Navigate to metrics page to check if the LLM call was tracked
        await page.goto('http://127.0.0.1:5000/metrics', { waitUntil: 'domcontentloaded' });

        const initialMetrics = await page.evaluate(() => {
            const content = {
                title: document.title,
                totalTokens: document.querySelector('[data-metric="total-tokens"]')?.textContent ||
                            document.querySelector('.metric-value')?.textContent || 'not found',
                metrics: Array.from(document.querySelectorAll('.metric-item, [class*="metric"]')).slice(0, 5).map(el => el.textContent.trim())
            };
            return content;
        });
        console.log('Initial metrics page:', JSON.stringify(initialMetrics, null, 2));

        console.log('\n=== CONFIGURING SETTINGS FOR FASTER TEST ===\n');

        // Navigate to settings page to configure iterations and questions
        await page.goto('http://127.0.0.1:5000/settings', { waitUntil: 'domcontentloaded' });

        // Set iterations to 1
        await page.evaluate(() => {
            const iterationsInput = document.querySelector('input[name="search.iterations"]') ||
                                  document.querySelector('#search\\.iterations');
            if (iterationsInput) {
                iterationsInput.value = '1';
                iterationsInput.dispatchEvent(new Event('change', { bubbles: true }));
                console.log('Set iterations to 1');
            }
        });

        // Set questions per iteration to 1
        await page.evaluate(() => {
            const questionsInput = document.querySelector('input[name="search.questions_per_iteration"]') ||
                                  document.querySelector('#search\\.questions_per_iteration');
            if (questionsInput) {
                questionsInput.value = '1';
                questionsInput.dispatchEvent(new Event('change', { bubbles: true }));
                console.log('Set questions to 1');
            }
        });

        // Save settings
        const saveButton = await page.$('button[type="submit"]');
        if (saveButton) {
            await saveButton.click();
            console.log('Settings saved');
            await new Promise(resolve => setTimeout(resolve, 1000));
        }

        console.log('\n=== STARTING RESEARCH ===\n');

        // Navigate to home
        await page.goto('http://127.0.0.1:5000/', { waitUntil: 'domcontentloaded' });

        // Fill form with a simple query
        await page.type('#query', 'What is Node.js?');

        // Setup the default model
        await setupDefaultModel(page);

        // Set search engine
        await page.evaluate(() => {
            const searchInput = document.querySelector('#search_engine');
            if (searchInput) {
                searchInput.value = 'searxng';
                const inputEvent = new Event('input', { bubbles: true });
                searchInput.dispatchEvent(inputEvent);
                console.log('Set search engine to:', searchInput.value);
            }
        });

        // Wait a bit for UI to update
        await new Promise(resolve => setTimeout(resolve, 500));

        // Submit
        await page.click('button[type="submit"]');

        // Wait for navigation
        await page.waitForNavigation({ waitUntil: 'domcontentloaded' });

        // Check where we ended up
        const url = page.url();
        console.log('After submission URL:', url);

        if (url.includes('/progress/')) {
            console.log('✅ Research submitted successfully!');
            const researchId = url.split('/progress/')[1];
            console.log('Research ID:', researchId);

            // Monitor progress for up to 90 seconds
            const startTime = Date.now();
            const maxWaitTime = 90000; // 90 seconds for faster test
            let isComplete = false;

            while (!isComplete && (Date.now() - startTime) < maxWaitTime) {
                // Get progress page content
                const progressContent = await page.evaluate(() => {
                    const content = {
                        status: document.querySelector('.status')?.textContent.trim() ||
                               document.querySelector('[class*="status"]')?.textContent.trim() || 'not found',
                        progressBar: document.querySelector('.progress-bar')?.style.width ||
                                    document.querySelector('[class*="progress-bar"]')?.style.width || 'not found',
                        currentTask: document.querySelector('.current-task')?.textContent.trim() ||
                                    document.querySelector('[class*="current-task"]')?.textContent.trim() || 'not found'
                    };
                    return content;
                });

                console.log(`Progress: ${progressContent.progressBar} - ${progressContent.currentTask}`);

                // Check if complete
                if (progressContent.status.toLowerCase().includes('complete') ||
                    progressContent.status.toLowerCase().includes('finished') ||
                    progressContent.progressBar === '100%') {
                    isComplete = true;
                    console.log('\n✅ Research completed!');
                }

                // Wait 3 seconds before checking again
                await new Promise(resolve => setTimeout(resolve, 3000));
            }

            console.log('\n=== CHECKING METRICS AFTER RESEARCH ===\n');

            // Navigate to metrics page
            await page.goto('http://127.0.0.1:5000/metrics', { waitUntil: 'domcontentloaded' });

            // Wait for metrics to load
            await new Promise(resolve => setTimeout(resolve, 2000));

            // Get detailed metrics
            const finalMetrics = await page.evaluate(() => {
                const getTextContent = (selector) => {
                    const el = document.querySelector(selector);
                    return el ? el.textContent.trim() : 'not found';
                };

                const content = {
                    title: document.title,
                    // Try different selectors for metrics
                    totalTokens: getTextContent('[data-metric="total-tokens"]') ||
                                getTextContent('.total-tokens') ||
                                getTextContent('#total-tokens'),
                    totalCalls: getTextContent('[data-metric="total-calls"]') ||
                               getTextContent('.total-calls') ||
                               getTextContent('#total-calls'),
                    totalCost: getTextContent('[data-metric="total-cost"]') ||
                              getTextContent('.total-cost') ||
                              getTextContent('#total-cost'),
                    // Get all metric cards
                    metricCards: Array.from(document.querySelectorAll('.metric-card, .ldr-card')).map(card => {
                        return {
                            title: card.querySelector('.card-title, h5, h6')?.textContent.trim() || '',
                            value: card.querySelector('.metric-value, .display-4, .h2')?.textContent.trim() || '',
                            text: card.textContent.trim()
                        };
                    }).filter(card => card.title || card.value),
                    // Get any tables
                    tables: Array.from(document.querySelectorAll('table')).map(table => {
                        const headers = Array.from(table.querySelectorAll('th')).map(th => th.textContent.trim());
                        const firstRow = table.querySelector('tbody tr');
                        const firstRowData = firstRow ? Array.from(firstRow.querySelectorAll('td')).map(td => td.textContent.trim()) : [];
                        return {
                            headers,
                            firstRow: firstRowData,
                            rowCount: table.querySelectorAll('tbody tr').length
                        };
                    })
                };
                return content;
            });

            console.log('Final metrics page:', JSON.stringify(finalMetrics, null, 2));

            // Check if metrics were recorded
            if (finalMetrics.metricCards.length > 0 || finalMetrics.tables.some(t => t.rowCount > 0)) {
                console.log('\n✅ Metrics are being tracked!');

                // Try to get specific token counts
                const hasTokenData = finalMetrics.metricCards.some(card =>
                    card.text.toLowerCase().includes('token') &&
                    card.value && card.value !== '0' && card.value !== 'not found'
                );

                if (hasTokenData) {
                    console.log('✅ Token usage data found in metrics!');
                } else {
                    console.log('⚠️  No token usage data found in metrics cards');
                }
            } else {
                console.log('\n❌ No metrics data found on page');
            }

            // Also check the cost analytics page
            console.log('\n=== CHECKING COST ANALYTICS ===\n');

            await page.goto('http://127.0.0.1:5000/metrics/costs', { waitUntil: 'domcontentloaded' });

            const costMetrics = await page.evaluate(() => {
                const content = {
                    title: document.title,
                    hasData: document.querySelectorAll('table tbody tr').length > 0,
                    tableRows: document.querySelectorAll('table tbody tr').length,
                    firstRowData: (() => {
                        const firstRow = document.querySelector('table tbody tr');
                        if (!firstRow) return null;
                        return Array.from(firstRow.querySelectorAll('td')).map(td => td.textContent.trim());
                    })()
                };
                return content;
            });

            console.log('Cost analytics page:', JSON.stringify(costMetrics, null, 2));

            if (costMetrics.hasData) {
                console.log('✅ Cost data is being tracked!');
            } else {
                console.log('⚠️  No cost data found');
            }

        } else {
            console.log('❌ Failed to submit research');

            // Check for errors
            const errors = await page.evaluate(() => {
                return Array.from(document.querySelectorAll('.error, .alert')).map(el => el.textContent);
            });

            console.log('Errors found:', errors);
        }

    } catch (error) {
        console.error('Test failed:', error);
        process.exitCode = 1;
    } finally {
        console.log('\n=== TEST COMPLETE ===\n');
        await browser.close();
    }
})().catch(err => {
    console.error('Unhandled error:', err);
    process.exitCode = 1;
});
