#!/usr/bin/env node

/**
 * Standalone test for Context Overflow Dashboard
 * Run with: node test_context_overflow_standalone.js
 */

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

const BASE_URL = process.env.BASE_URL || 'http://127.0.0.1:5000';
const HEADLESS = process.env.HEADLESS !== 'false';
const SLOW_MO = parseInt(process.env.SLOW_MO || '100');

async function testContextOverflow() {
    console.log('🚀 Starting Context Overflow Dashboard Test');
    console.log(`   Base URL: ${BASE_URL}`);
    console.log(`   Headless: ${HEADLESS}`);
    console.log('');

    let browser;
    let page;

    try {
        // Launch browser
        browser = await puppeteer.launch({
            headless: HEADLESS,
            slowMo: SLOW_MO,
            args: ['--no-sandbox', '--disable-setuid-sandbox']
        });

        page = await browser.newPage();
        await page.setViewport({ width: 1280, height: 800 });

        // Enable console logging
        page.on('console', msg => {
            const type = msg.type();
            const text = msg.text();
            if (type === 'error') {
                console.log('  ❌ Browser console error:', text);
            } else if (type === 'warning') {
                console.log('  ⚠️  Browser console warning:', text);
            } else if (text.includes('loadContextData') || text.includes('displayContextData') || text.includes('Response')) {
                console.log('  📝 Browser console:', text);
            }
        });

        // Enable request/response logging
        page.on('response', response => {
            const url = response.url();
            if (url.includes('context-overflow')) {
                console.log(`  📡 Response: ${url} - Status: ${response.status()}`);
            }
        });

        const authHelper = new AuthHelper(page, BASE_URL);

        // Set longer timeout
        page.setDefaultTimeout(30000);

        // Login
        console.log('📝 Logging in...');
        await authHelper.ensureAuthenticated();
        console.log('✅ Logged in successfully');
        console.log('');

        // Navigate to context overflow page
        console.log('📊 Navigating to context overflow page...');
        await page.goto(`${BASE_URL}/metrics/context-overflow`, {
            waitUntil: 'networkidle2',
            timeout: 30000
        });
        console.log('✅ Page loaded');

        // Wait for main container
        await page.waitForSelector('#context-overflow', { timeout: 10000 });
        console.log('✅ Found context overflow container');

        // Check loading state
        console.log('⏳ Waiting for data to load...');
        const loadingResult = await page.waitForFunction(
            () => {
                const loading = document.getElementById('loading');
                const content = document.getElementById('content');

                // Log current state
                console.log('loadContextData check - loading display:', loading ? loading.style.display : 'no loading element');
                console.log('loadContextData check - content display:', content ? content.style.display : 'no content element');

                return loading && loading.style.display === 'none' &&
                       content && content.style.display !== 'none';
            },
            { timeout: 15000 }
        ).catch(err => {
            console.log('❌ Timeout waiting for data to load');
            return null;
        });

        if (loadingResult) {
            console.log('✅ Data loaded successfully');
        }

        // Get page data
        console.log('');
        console.log('📊 Analyzing page content...');
        const pageData = await page.evaluate(() => {
            const results = {
                sections: {},
                metrics: {},
                errors: []
            };

            // Check for error messages
            const alerts = document.querySelectorAll('.alert-danger');
            alerts.forEach(alert => {
                results.errors.push(alert.textContent.trim());
            });

            // Check sections
            results.sections.hasOverviewCards = !!document.querySelector('.overflow-grid');
            results.sections.hasContextChart = !!document.getElementById('context-chart');
            results.sections.hasModelStats = !!document.getElementById('model-stats');
            results.sections.hasTruncatedList = !!document.getElementById('truncated-list');
            results.sections.hasDistributionChart = !!document.getElementById('distribution-chart');

            // Get metrics
            const truncationRate = document.getElementById('truncation-rate');
            results.metrics.truncationRate = truncationRate ? truncationRate.textContent.trim() : null;

            const avgTokensLost = document.getElementById('avg-tokens-lost');
            results.metrics.avgTokensLost = avgTokensLost ? avgTokensLost.textContent.trim() : null;

            const modelsTracked = document.getElementById('models-tracked');
            results.metrics.modelsTracked = modelsTracked ? modelsTracked.textContent.trim() : null;

            const dataCoverage = document.getElementById('data-coverage');
            results.metrics.dataCoverage = dataCoverage ? dataCoverage.textContent.trim() : null;

            // Check for no data message
            const noDataMessages = document.querySelectorAll('.no-data-message');
            results.hasNoDataMessage = noDataMessages.length > 0;
            if (noDataMessages.length > 0) {
                results.noDataText = Array.from(noDataMessages).map(el => el.textContent.trim());
            }

            return results;
        });

        // Display results
        console.log('');
        console.log('📋 Page Sections:');
        console.log(`  Overview cards: ${pageData.sections.hasOverviewCards ? '✅' : '❌'}`);
        console.log(`  Context chart: ${pageData.sections.hasContextChart ? '✅' : '❌'}`);
        console.log(`  Model stats: ${pageData.sections.hasModelStats ? '✅' : '❌'}`);
        console.log(`  Truncated list: ${pageData.sections.hasTruncatedList ? '✅' : '❌'}`);
        console.log(`  Distribution chart: ${pageData.sections.hasDistributionChart ? '✅' : '❌'}`);

        console.log('');
        console.log('📈 Metrics:');
        console.log(`  Truncation rate: ${pageData.metrics.truncationRate || 'N/A'}`);
        console.log(`  Avg tokens lost: ${pageData.metrics.avgTokensLost || 'N/A'}`);
        console.log(`  Models tracked: ${pageData.metrics.modelsTracked || 'N/A'}`);
        console.log(`  Data coverage: ${pageData.metrics.dataCoverage || 'N/A'}`);

        if (pageData.errors.length > 0) {
            console.log('');
            console.log('❌ Errors found:');
            pageData.errors.forEach(err => console.log(`  - ${err}`));
        }

        if (pageData.hasNoDataMessage) {
            console.log('');
            console.log('ℹ️  No data messages:');
            pageData.noDataText.forEach(msg => console.log(`  - ${msg}`));
        }

        // Test API directly
        console.log('');
        console.log('🔌 Testing API endpoint...');
        const apiResponse = await page.evaluate(async (baseUrl) => {
            try {
                const res = await fetch(`${baseUrl}/metrics/api/context-overflow?period=30d`, {
                    method: 'GET',
                    credentials: 'include',
                    headers: {
                        'Accept': 'application/json'
                    }
                });

                const text = await res.text();
                let data;
                try {
                    data = JSON.parse(text);
                } catch (e) {
                    data = { parseError: true, rawText: text.substring(0, 200) };
                }

                return {
                    status: res.status,
                    ok: res.ok,
                    headers: Object.fromEntries(res.headers.entries()),
                    data: data
                };
            } catch (error) {
                return {
                    error: error.message
                };
            }
        }, BASE_URL);

        console.log(`  Status: ${apiResponse.status}`);
        console.log(`  OK: ${apiResponse.ok}`);

        if (apiResponse.data) {
            if (apiResponse.data.parseError) {
                console.log('  ❌ Failed to parse JSON response');
                console.log(`  Raw response: ${apiResponse.data.rawText}`);
            } else {
                console.log(`  Response status: ${apiResponse.data.status}`);

                if (apiResponse.data.overview) {
                    console.log('');
                    console.log('  📊 API Data Overview:');
                    console.log(`    Total requests: ${apiResponse.data.overview.total_requests}`);
                    console.log(`    Requests with context: ${apiResponse.data.overview.requests_with_context_data}`);
                    console.log(`    Truncated requests: ${apiResponse.data.overview.truncated_requests}`);
                    console.log(`    Truncation rate: ${apiResponse.data.overview.truncation_rate}%`);
                    console.log(`    Avg tokens truncated: ${apiResponse.data.overview.avg_tokens_truncated}`);
                }

                if (apiResponse.data.model_stats) {
                    console.log(`    Model stats count: ${apiResponse.data.model_stats.length}`);
                }

                if (apiResponse.data.context_limits) {
                    console.log(`    Context limits count: ${apiResponse.data.context_limits.length}`);
                }

                if (apiResponse.data.chart_data) {
                    console.log(`    Chart data points: ${apiResponse.data.chart_data.length}`);
                }
            }
        } else if (apiResponse.error) {
            console.log(`  ❌ Error: ${apiResponse.error}`);
        }

        // Test time range selector
        console.log('');
        console.log('🕐 Testing time range selector...');
        const timeRangeButtons = await page.$$('.time-range-btn');
        console.log(`  Found ${timeRangeButtons.length} time range buttons`);

        if (timeRangeButtons.length > 0) {
            // Click 7d button
            await page.click('[data-period="7d"]');
            await new Promise(resolve => setTimeout(resolve, 1000));

            const is7dActive = await page.evaluate(() => {
                const btn = document.querySelector('[data-period="7d"]');
                return btn && btn.classList.contains('active');
            });
            console.log(`  7d button active: ${is7dActive ? '✅' : '❌'}`);
        }

        console.log('');
        console.log('✅ Test completed successfully!');

    } catch (error) {
        console.error('');
        console.error('❌ Test failed with error:', error.message);
        console.error(error.stack);
    } finally {
        if (browser) {
            await browser.close();
        }
    }
}

// Run the test
testContextOverflow().catch(console.error);
