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

// NAVIGATION NOTE: Using 'domcontentloaded' instead of 'networkidle2' for page.goto()
// because networkidle2 waits for no network activity for 500ms, but WebSocket
// connections and background polling keep the network active, causing infinite hangs.
// See: test_login_validation.js and auth_helper.js for detailed explanation.
// Test configuration
const BASE_URL = 'http://127.0.0.1:5000';

// 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 createResearch(page, query, waitForCompletion = false) {
    log(`🔬 Creating research: "${query}"`, 'info');

    // Navigate to home/research page
    await page.goto(BASE_URL, { waitUntil: 'domcontentloaded' });

    // Wait for the query input
    await page.waitForSelector('#query', { timeout: 10000 });

    // Clear and type query
    await page.click('#query', { clickCount: 3 });
    await page.type('#query', query);

    // Submit the research
    const submitButton = await page.$('button[type="submit"]');
    if (submitButton) {
        await submitButton.click();
    } else {
        // Try pressing Enter
        await page.keyboard.press('Enter');
    }

    // Wait for navigation or status update
    await delay(3000);

    if (waitForCompletion) {
        log('⏳ Waiting for research to complete...', 'info');

        // Wait for completion (max 30 seconds for test)
        const startTime = Date.now();
        const maxWaitTime = 30000;

        while (Date.now() - startTime < maxWaitTime) {
            try {
                // Check if we're on results page
                const url = page.url();
                if (url.includes('/results/') || url.includes('/research/')) {
                    // Check for completion indicators
                    const completed = await page.evaluate(() => {
                        const statusEl = document.querySelector('.status-badge, .research-status');
                        if (statusEl && statusEl.textContent.toLowerCase().includes('completed')) {
                            return true;
                        }
                        const progressEl = document.querySelector('.progress-bar, .progress');
                        if (progressEl && progressEl.textContent.includes('100%')) {
                            return true;
                        }
                        return false;
                    });

                    if (completed) {
                        log('✅ Research completed', 'success');
                        break;
                    }
                }
            } catch (e) {
                // Continue waiting
            }

            await delay(1000);
        }
    }
}

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

    let page = await browser.newPage();

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

    try {
        // Create auth helper and register user
        const authHelper = new AuthHelper(page, BASE_URL);

        log('🔐 Authenticating...', 'info');
        await authHelper.ensureAuthenticatedWithTimeout();
        page = authHelper.page;

        // Verify we're logged in
        const isLoggedIn = await authHelper.isLoggedIn();
        if (!isLoggedIn) {
            throw new Error('Failed to login after registration');
        }
        log('✅ User registered and logged in', 'success');

        // Create some research items for history
        log('\n=== CREATING TEST RESEARCH ITEMS ===', 'section');
        const queries = [
            'What is machine learning?',
            'History of artificial intelligence'
        ];

        for (const query of queries) {
            await createResearch(page, query, false); // Don't wait for full completion
            await delay(2000); // Wait between researches
        }

        // Navigate to history page
        log('\n=== TESTING HISTORY PAGE ===', 'section');
        await page.goto(`${BASE_URL}/history`, { waitUntil: 'domcontentloaded' });

        // Wait for history content to load
        await page.waitForSelector('body', { timeout: 10000 });

        // Check if we have history items or appropriate message
        const pageContent = await page.evaluate(() => {
            const historyItems = document.querySelectorAll('.history-item, .research-item, .list-group-item, [data-research-id]');
            const emptyMessage = document.querySelector('.empty-state, .no-history, .alert-info');

            return {
                title: document.title,
                hasHistoryContainer: !!document.querySelector('.ldr-history-container, .ldr-history-list, .research-history'),
                itemCount: historyItems.length,
                hasEmptyMessage: !!emptyMessage,
                emptyMessageText: emptyMessage?.textContent || '',
                items: Array.from(historyItems).slice(0, 5).map(item => ({
                    text: item.textContent?.trim().substring(0, 100) || '',
                    hasLink: !!item.querySelector('a'),
                    hasDeleteButton: !!item.querySelector('.delete-btn, .btn-danger, [onclick*="delete"]')
                }))
            };
        });

        log(`📊 History page content:`, 'info');
        log(`  - Title: ${pageContent.title}`, 'info');
        log(`  - Has history container: ${pageContent.hasHistoryContainer}`, 'info');
        log(`  - Total items found: ${pageContent.itemCount}`, 'info');
        log(`  - Has empty message: ${pageContent.hasEmptyMessage}`, 'info');

        if (pageContent.itemCount > 0) {
            log('✅ History items found on page', 'success');

            // Log first few items
            pageContent.items.forEach((item, index) => {
                log(`  - Item ${index + 1}: ${item.text.substring(0, 50)}...`, 'info');
            });
        } else if (pageContent.hasEmptyMessage) {
            log(`ℹ️ Empty history message: ${pageContent.emptyMessageText.substring(0, 100)}`, 'info');
            log('⚠️ No history items found (research might not have saved)', 'warning');
        } else {
            log('⚠️ No history items or empty message found', 'warning');
        }

        // Test search/filter if available
        const searchInput = await page.$('#search-input, input[type="search"], .search-input');
        if (searchInput && pageContent.itemCount > 0) {
            log('\n=== TESTING SEARCH/FILTER ===', 'section');
            await searchInput.type('machine learning');
            await delay(500); // Wait for filter to apply

            const filteredCount = await page.evaluate(() => {
                const visibleItems = document.querySelectorAll('.history-item:not([style*="display: none"]), .research-item:not(.d-none)');
                return visibleItems.length;
            });

            log(`📊 Filtered results: ${filteredCount} items`, 'info');

            if (filteredCount >= 0) {
                log('✅ Search field is present', 'success');
            }
        }

        // Test navigation elements
        const navigationElements = await page.evaluate(() => {
            return {
                hasPagination: !!document.querySelector('.pagination, .page-link'),
                hasBackButton: !!document.querySelector('a[href="/"], .back-btn'),
                hasNewResearchButton: !!document.querySelector('a[href="/research"], .new-research-btn')
            };
        });

        log('\n=== NAVIGATION ELEMENTS ===', 'section');
        log(`  - Has pagination: ${navigationElements.hasPagination}`, 'info');
        log(`  - Has back/home button: ${navigationElements.hasBackButton}`, 'info');
        log(`  - Has new research button: ${navigationElements.hasNewResearchButton}`, 'info');

        // Test re-run button on history items
        log('\n=== TESTING RE-RUN BUTTON ===', 'section');
        const rerunButtonInfo = await page.evaluate(() => {
            const historyItems = document.querySelectorAll('.ldr-history-item, [data-research-id]');
            const rerunButtons = document.querySelectorAll('.ldr-rerun-btn');

            // Helper to check true visibility
            function isVisible(el) {
                if (!el) return false;
                const style = getComputedStyle(el);
                const rect = el.getBoundingClientRect();
                return style.display !== 'none' &&
                       style.visibility !== 'hidden' &&
                       parseFloat(style.opacity) > 0 &&
                       rect.width > 0 && rect.height > 0;
            }

            // Check each item for re-run button
            const itemDetails = [];
            historyItems.forEach(item => {
                const status = item.querySelector('.ldr-status-badge, .status-badge');
                const rerunBtn = item.querySelector('.ldr-rerun-btn');
                const statusText = status?.textContent?.trim().toLowerCase() || 'unknown';

                itemDetails.push({
                    status: statusText,
                    hasRerunBtn: !!rerunBtn,
                    isVisible: isVisible(rerunBtn),
                    // Re-run should only show on completed items
                    isCorrect: statusText === 'completed' ? (!!rerunBtn && isVisible(rerunBtn)) : !rerunBtn
                });
            });

            // Check button styling if any exist
            let buttonStyle = null;
            if (rerunButtons.length > 0) {
                const btn = rerunButtons[0];
                const style = getComputedStyle(btn);
                buttonStyle = {
                    hasIcon: !!btn.querySelector('i, .fa-redo, [class*="fa-"]'),
                    cursor: style.cursor,
                    hasTitle: !!btn.title
                };
            }

            return {
                totalItems: historyItems.length,
                totalRerunButtons: rerunButtons.length,
                items: itemDetails,
                allCorrect: itemDetails.every(i => i.isCorrect),
                buttonStyle
            };
        });

        log(`  - Total history items: ${rerunButtonInfo.totalItems}`, 'info');
        log(`  - Re-run buttons found: ${rerunButtonInfo.totalRerunButtons}`, 'info');

        if (rerunButtonInfo.totalItems > 0) {
            rerunButtonInfo.items.forEach((item, idx) => {
                const mark = item.isCorrect ? '✓' : '✗';
                log(`  - Item ${idx + 1}: status=${item.status}, hasBtn=${item.hasRerunBtn}, visible=${item.isVisible} ${mark}`, 'info');
            });

            if (rerunButtonInfo.allCorrect) {
                log('✅ Re-run buttons correctly shown only on completed items', 'success');
            } else {
                log('⚠️ Re-run button visibility issue detected', 'warning');
            }

            if (rerunButtonInfo.buttonStyle) {
                log(`  - Button has icon: ${rerunButtonInfo.buttonStyle.hasIcon}`, 'info');
                log(`  - Button cursor: ${rerunButtonInfo.buttonStyle.cursor}`, 'info');
                if (rerunButtonInfo.buttonStyle.cursor === 'pointer') {
                    log('✅ Re-run button has pointer cursor', 'success');
                }
            }
        } else {
            log('ℹ️ No history items to test re-run button on', 'info');
        }

        // Test re-run button click if available
        if (rerunButtonInfo.totalRerunButtons > 0) {
            log('\n=== TESTING RE-RUN BUTTON CLICK ===', 'section');

            // Get query before clicking
            const queryBefore = await page.evaluate(() => {
                const item = document.querySelector('.ldr-history-item, [data-research-id]');
                const queryEl = item?.querySelector('.ldr-history-item-query, .query-text, h5, h6');
                return queryEl?.textContent?.trim() || '';
            });

            log(`  - Query to re-run: "${queryBefore.substring(0, 50)}..."`, 'info');

            // Click the re-run button
            await page.click('.ldr-rerun-btn');
            await delay(2000);

            // Check if we navigated and form is populated
            const afterClick = await page.evaluate(() => {
                const queryEl = document.getElementById('query');
                return {
                    url: window.location.pathname,
                    queryValue: queryEl?.value || '',
                    hasNotification: !!document.querySelector('.alert-info')
                };
            });

            log(`  - Navigated to: ${afterClick.url}`, 'info');
            log(`  - Form query: "${afterClick.queryValue.substring(0, 50)}..."`, 'info');
            log(`  - Re-run notification: ${afterClick.hasNotification}`, 'info');

            if (afterClick.url === '/' && afterClick.queryValue.length > 0) {
                log('✅ Re-run button works correctly', 'success');
            } else {
                log('⚠️ Re-run navigation or form population issue', 'warning');
            }
        }

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

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


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

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