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

async function testCostAnalytics() {
    let browser;
    const results = {
        success: false,
        errors: [],
        networkErrors: [],
        consoleErrors: [],
        apiResponses: {},
    };

    try {
        console.log('🚀 Starting Cost Analytics test...');

    browser = await puppeteer.launch(getPuppeteerLaunchOptions());

        const page = await browser.newPage();
    const baseUrl = 'http://127.0.0.1:5000';
    const authHelper = new AuthHelper(page, baseUrl);

        // Intercept network requests to debug API calls
        await page.setRequestInterception(true);
        page.on('request', (request) => {
            console.log(`📡 Network Request: ${request.method()} ${request.url()}`);
            request.continue();
        });

        // Monitor network responses
        page.on('response', async (response) => {
            const url = response.url();
            const status = response.status();
            console.log(`📨 Network Response: ${status} ${url}`);

            if (url.includes('/metrics/api/')) {
                try {
                    const responseText = await response.text();
                    results.apiResponses[url] = {
                        status,
                        response: responseText.substring(0, 500) // First 500 chars
                    };
                    console.log(`📊 API Response for ${url}:`, responseText.substring(0, 200));
                } catch (e) {
                    console.log(`❌ Failed to read response for ${url}:`, e.message);
                }
            }
        });

        // Monitor console messages
        page.on('console', msg => {
            const text = msg.text();
            console.log(`🖥️  Console ${msg.type()}: ${text}`);
            if (msg.type() === 'error') {
                results.consoleErrors.push(text);
            }
        });

        // Monitor network failures
        page.on('requestfailed', request => {
            const error = `Network failed: ${request.url()} - ${request.failure().errorText}`;
            console.log(`❌ ${error}`);
            results.networkErrors.push(error);
        });

        // Ensure authenticated before accessing cost analytics
        await authHelper.ensureAuthenticated();

        // Wait a bit to ensure session is established
        await new Promise(resolve => setTimeout(resolve, 1000));

        console.log('📄 Navigating to cost analytics page...');
        const response = await page.goto('http://127.0.0.1:5000/metrics/costs', {
            waitUntil: 'domcontentloaded',
            timeout: 30000
        });

        if (!response.ok()) {
            throw new Error(`Page failed to load: ${response.status()} ${response.statusText()}`);
        }


        // Wait for page elements
        console.log('⏳ Waiting for page elements...');
        await page.waitForSelector('.cost-analytics-container', { timeout: 10000 });

        // Check if loading state is present
        const loadingElement = await page.$('#loading');
        const isLoading = await page.evaluate(el => el && el.style.display !== 'none', loadingElement);
        console.log(`📊 Loading state visible: ${isLoading}`);

        // Wait a bit and check state again
        await new Promise(resolve => setTimeout(resolve, 1000));

        // Check for error state
        const errorElement = await page.$('#error');
        const hasError = await page.evaluate(el => el && el.style.display !== 'none', errorElement);
        console.log(`❌ Error state visible: ${hasError}`);

        // Check for content state
        const contentElement = await page.$('#cost-content');
        const hasContent = await page.evaluate(el => el && el.style.display !== 'none', contentElement);
        console.log(`✅ Content state visible: ${hasContent}`);

        // Check for no-data state
        const noDataElement = await page.$('#no-data');
        const hasNoData = await page.evaluate(el => el && el.style.display !== 'none', noDataElement);
        console.log(`📭 No-data state visible: ${hasNoData}`);

        // Try to manually trigger the API call to debug
        console.log('🔧 Manually testing API call...');
        const apiResponse = await page.evaluate(async () => {
            try {
                const resp = await fetch('/metrics/api/cost-analytics?period=7d');
                const data = await resp.json();
                return { success: true, status: resp.status, data };
            } catch (error) {
                return { success: false, error: error.message };
            }
        });
        console.log('🔍 Manual API test result:', JSON.stringify(apiResponse, null, 2));


        // Check for specific cost data elements
        const totalCostElement = await page.$('#total-cost');
        const totalCostText = totalCostElement ? await page.evaluate(el => el.textContent, totalCostElement) : 'Not found';
        console.log(`💰 Total cost display: "${totalCostText}"`);

        const localSavingsElement = await page.$('#local-savings');
        const localSavingsText = localSavingsElement ? await page.evaluate(el => el.textContent, localSavingsElement) : 'Not found';
        console.log(`🏠 Local savings display: "${localSavingsText}"`);

        // Test time period buttons
        console.log('🕒 Testing time period buttons...');
        const timePeriodButtons = await page.$$('.time-range-btn');
        console.log(`📊 Found ${timePeriodButtons.length} time period buttons`);

        if (timePeriodButtons.length > 1) {
            // Click on 30d button to test functionality
            await timePeriodButtons[1].click();
            await new Promise(resolve => setTimeout(resolve, 1000));

        }

        results.success = true;
        console.log('✅ Cost Analytics test completed successfully!');

    } catch (error) {
        console.error('❌ Test failed:', error.message);
        results.errors.push(error.message);

    } finally {
        if (browser) {
            await browser.close();
        }
    }

    // Write detailed results
    const resultsPath = './results/cost-analytics-test-results.json';
    fs.mkdirSync('./results', { recursive: true });
    fs.writeFileSync(resultsPath, JSON.stringify(results, null, 2));
    console.log(`📄 Detailed results saved: ${resultsPath}`);

    return results;
}

// Create results directory
const resultsDir = './results';
fs.mkdirSync(resultsDir, { recursive: true });

// Run the test
testCostAnalytics().then(results => {
    console.log('\n📋 Test Summary:');
    console.log(`✅ Success: ${results.success}`);
    console.log(`❌ Errors: ${results.errors.length}`);
    console.log(`🌐 Network Errors: ${results.networkErrors.length}`);
    console.log(`🖥️  Console Errors: ${results.consoleErrors.length}`);
    console.log(`📡 API Responses: ${Object.keys(results.apiResponses).length}`);

    if (results.errors.length > 0) {
        console.log('\n❌ Errors encountered:');
        results.errors.forEach(error => console.log(`  - ${error}`));
    }

    if (results.networkErrors.length > 0) {
        console.log('\n🌐 Network Errors:');
        results.networkErrors.forEach(error => console.log(`  - ${error}`));
    }

    if (results.consoleErrors.length > 0) {
        console.log('\n🖥️  Console Errors:');
        results.consoleErrors.forEach(error => console.log(`  - ${error}`));
    }

    process.exit(results.success ? 0 : 1);
}).catch(error => {
    console.error('💥 Test runner failed:', error);
    process.exit(1);
});
