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

// Test configuration
const BASE_URL = 'http://127.0.0.1:5000';
const TEST_USER = `details_test_${Date.now()}`;
const TEST_PASSWORD = 'TestPass123!';

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

function log(message, type = 'info') {
    const timestamp = new Date().toISOString().split('T')[1].split('.')[0];
    const typeColors = {
        'info': colors.cyan,
        'success': colors.green,
        'error': colors.red,
        'warning': colors.yellow,
        'section': colors.blue
    };
    const color = typeColors[type] || colors.reset;
    console.log(`${color}[${timestamp}] ${message}${colors.reset}`);
}

async function delay(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function registerAndLogin(page) {
    log('📝 Registering new user...', 'info');

    await page.goto(`${BASE_URL}/register`);
    await page.waitForSelector('#username');

    await page.type('#username', TEST_USER);
    await page.type('#password', TEST_PASSWORD);
    await page.type('#password_confirm', TEST_PASSWORD);

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

    log('✅ Registration successful', 'success');
}

async function createAndWaitForResearch(page) {
    log('🔬 Creating research for details test...', 'info');

    await page.goto(`${BASE_URL}/research`);
    await page.waitForSelector('#query');

    // Set a specific query
    const testQuery = 'Benefits of green tea for health';
    await page.evaluate((q) => {
        document.getElementById('query').value = q;
    }, testQuery);

    // Submit research
    await page.click('#submit-research');

    // Wait for research to complete
    log('⏳ Waiting for research to complete...', 'info');
    const startTime = Date.now();
    const maxWaitTime = 120000; // 2 minutes

    while (Date.now() - startTime < maxWaitTime) {
        const progressText = await page.$eval('.progress-info', el => el.textContent).catch(() => '');

        if (progressText.includes('100%') || progressText.includes('completed')) {
            log('✅ Research completed', 'success');
            break;
        }

        await delay(1000);
    }

    // Get research ID from URL or page
    const researchId = await page.evaluate(() => {
        // Try to extract from URL or page elements
        const urlMatch = window.location.pathname.match(/research\/([a-f0-9-]+)/);
        if (urlMatch) return urlMatch[1];

        // Try to find in page data
        const researchLink = document.querySelector('a[href*="/results/"]');
        if (researchLink) {
            const match = researchLink.href.match(/results\/([a-f0-9-]+)/);
            if (match) return match[1];
        }

        return null;
    });

    return { query: testQuery, id: researchId };
}

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

    const page = await browser.newPage();

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

    try {
        // Register and login
        await registerAndLogin(page);

        // Create a research and wait for completion
        const research = await createAndWaitForResearch(page);

        // Navigate to details page
        log('\n=== TESTING RESEARCH DETAILS PAGE ===', 'section');

        // First go to history to find the research
        await page.goto(`${BASE_URL}/history`);
        await page.waitForSelector('.history-item');

        // Click on the first research item
        const detailsLink = await page.$('.history-item a[href*="/details/"], .history-item a[href*="/results/"]');
        if (detailsLink) {
            await detailsLink.click();
            await page.waitForNavigation();
        } else {
            // Try direct navigation if we have the ID
            if (research.id) {
                await page.goto(`${BASE_URL}/results/${research.id}`);
            }
        }

        // Wait for details page to load
        await page.waitForSelector('.report-content, .results-container', { timeout: 10000 });

        // Capture details page content
        const pageDetails = await page.evaluate(() => {
            const details = {
                title: document.title,
                url: window.location.href,
                hasReport: !!document.querySelector('.report-content, .markdown-content'),
                sections: [],
                metadata: {},
                actions: {
                    hasDownloadButton: !!document.querySelector('.download-btn, [data-action="download"]'),
                    hasExportButton: !!document.querySelector('.export-btn, [data-action="export"]'),
                    hasPrintButton: !!document.querySelector('.print-btn, [data-action="print"]'),
                    hasShareButton: !!document.querySelector('.share-btn, [data-action="share"]'),
                    hasBackButton: !!document.querySelector('.back-btn, a[href*="/history"]')
                }
            };

            // Get report sections
            const headings = document.querySelectorAll('h1, h2, h3');
            headings.forEach(h => {
                details.sections.push({
                    level: h.tagName,
                    text: h.textContent.trim()
                });
            });

            // Get metadata if available
            const metaElements = document.querySelectorAll('.metadata-item, .meta-info, .research-info');
            metaElements.forEach(el => {
                const label = el.querySelector('.label, .meta-label')?.textContent || '';
                const value = el.querySelector('.value, .meta-value')?.textContent || el.textContent;
                if (label) {
                    details.metadata[label] = value;
                }
            });

            // Check for citations
            details.hasCitations = document.querySelectorAll('a[href*="http"], .citation, .reference').length > 0;

            // Check for research metrics
            details.hasMetrics = !!document.querySelector('.metrics, .research-metrics, .statistics');

            return details;
        });

        log('📊 Details page content:', 'info');
        log(`  - URL: ${pageDetails.url}`, 'info');
        log(`  - Has report content: ${pageDetails.hasReport}`, 'info');
        log(`  - Number of sections: ${pageDetails.sections.length}`, 'info');
        log(`  - Has citations: ${pageDetails.hasCitations}`, 'info');
        log(`  - Has metrics: ${pageDetails.hasMetrics}`, 'info');

        // Verify essential elements
        if (!pageDetails.hasReport) {
            throw new Error('No report content found on details page');
        }
        log('✅ Report content present', 'success');

        if (pageDetails.sections.length > 0) {
            log(`✅ Found ${pageDetails.sections.length} sections in report`, 'success');
            pageDetails.sections.slice(0, 5).forEach(section => {
                log(`  - ${section.level}: ${section.text}`, 'info');
            });
        }

        // Test export functionality
        log('\n=== TESTING EXPORT OPTIONS ===', 'section');

        if (pageDetails.actions.hasExportButton) {
            const exportButton = await page.$('.export-btn, [data-action="export"]');
            await exportButton.click();
            await delay(500);

            // Check for export options
            const exportOptions = await page.evaluate(() => {
                const options = [];
                const exportLinks = document.querySelectorAll('.export-option, .export-format, a[download]');
                exportLinks.forEach(link => {
                    options.push({
                        format: link.textContent || link.getAttribute('data-format') || '',
                        href: link.href || ''
                    });
                });
                return options;
            });

            if (exportOptions.length > 0) {
                log(`✅ Found ${exportOptions.length} export formats:`, 'success');
                exportOptions.forEach(opt => {
                    log(`  - ${opt.format}`, 'info');
                });
            }
        }

        // Test download functionality
        if (pageDetails.actions.hasDownloadButton) {
            log('✅ Download option available', 'success');
        }

        // Test print functionality
        if (pageDetails.actions.hasPrintButton) {
            log('✅ Print option available', 'success');
        }

        // Test navigation
        log('\n=== TESTING NAVIGATION ===', 'section');

        if (pageDetails.actions.hasBackButton) {
            const backButton = await page.$('.back-btn, a[href*="/history"]');
            await backButton.click();
            await page.waitForNavigation();

            const afterNavUrl = page.url();
            if (afterNavUrl.includes('/history')) {
                log('✅ Back navigation to history works', 'success');

                // Navigate back to details
                await page.goBack();
                await page.waitForSelector('.report-content, .results-container');
            }
        }

        // Test interactive elements
        log('\n=== TESTING INTERACTIVE ELEMENTS ===', 'section');

        // Check for collapsible sections
        const collapsibles = await page.$$('.collapsible, .accordion, details');
        if (collapsibles.length > 0) {
            log(`📊 Found ${collapsibles.length} collapsible sections`, 'info');

            // Test first collapsible
            await collapsibles[0].click();
            await delay(300);
            log('✅ Collapsible sections work', 'success');
        }

        // Check for copy buttons
        const copyButtons = await page.$$('.copy-btn, [data-action="copy"]');
        if (copyButtons.length > 0) {
            log(`📊 Found ${copyButtons.length} copy buttons`, 'info');
            log('✅ Copy functionality available', 'success');
        }

        // Capture final screenshot
        await page.screenshot({
            path: path.join(__dirname, 'screenshots', 'research_details_final.png'),
            fullPage: true
        });

        // Test metrics section if available
        if (pageDetails.hasMetrics) {
            log('\n=== TESTING METRICS SECTION ===', 'section');

            const metrics = await page.evaluate(() => {
                const metricsData = {};
                const metricElements = document.querySelectorAll('.metric, .stat, [data-metric]');

                metricElements.forEach(el => {
                    const label = el.querySelector('.metric-label, .label')?.textContent ||
                                el.getAttribute('data-metric') || '';
                    const value = el.querySelector('.metric-value, .value')?.textContent ||
                                el.textContent;
                    if (label) {
                        metricsData[label] = value;
                    }
                });

                return metricsData;
            });

            log('📊 Research metrics:', 'info');
            Object.entries(metrics).forEach(([key, value]) => {
                log(`  - ${key}: ${value}`, 'info');
            });
        }

        log('\n✅ Research details page test completed successfully!', 'success');

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

        // Capture error screenshot
        await page.screenshot({
            path: path.join(__dirname, 'screenshots', 'research_details_error.png'),
            fullPage: true
        });

        throw error;
    } finally {
        await browser.close();
    }
}

// Run the test
testResearchDetails().catch(error => {
    console.error('Test execution failed:', error);
    process.exit(1);
});
