#!/usr/bin/env node
/**
 * Comprehensive Mobile UI Test
 * Tests all UI elements for mobile compatibility, not just navigation
 */

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

class MobileUITester {
    constructor() {
        this.baseUrl = process.env.TEST_BASE_URL || 'http://127.0.0.1:5000';
        this.results = {
            passed: [],
            failed: [],
            warnings: []
        };
    }

    async test() {
        let browser;
        try {
            browser = await puppeteer.launch({
                headless: process.env.HEADLESS !== 'false',
                args: ['--no-sandbox', '--disable-setuid-sandbox']
            });

            const devices = [
                { name: 'iPhone_SE', width: 375, height: 667 },
                { name: 'iPhone_14_Pro', width: 430, height: 932 },
                { name: 'iPad_Mini', width: 768, height: 1024 }
            ];

            for (const device of devices) {
                await this.testDevice(browser, device);
            }

            this.printResults();

            // Exit with error if any tests failed
            process.exit(this.results.failed.length > 0 ? 1 : 0);

        } catch (error) {
            console.error('Test failed:', error);
            process.exit(1);
        } finally {
            if (browser) await browser.close();
        }
    }

    async testDevice(browser, device) {
        console.log(`\n📱 Testing ${device.name} (${device.width}x${device.height})`);
        console.log('═'.repeat(50));

        const page = await browser.newPage();
        await page.setViewport({
            width: device.width,
            height: device.height,
            isMobile: true,
            hasTouch: true
        });

        // Authenticate
        const authHelper = new AuthHelper(page, this.baseUrl);
        await authHelper.ensureAuthenticated();

        // Test pages
        const pages = [
            { path: '/', name: 'Research', tests: ['topBar', 'inputFields', 'buttons', 'modals'] },
            { path: '/history/', name: 'History', tests: ['topBar', 'searchBar', 'list'] },
            { path: '/news/', name: 'News', tests: ['topBar', 'filters', 'cards'] },
            { path: '/settings/', name: 'Settings', tests: ['topBar', 'tabs', 'forms', 'scrolling'] },
            { path: '/metrics/', name: 'Metrics', tests: ['topBar', 'charts', 'tables'] },
            { path: '/benchmark/', name: 'Benchmark', tests: ['topBar', 'forms', 'buttons'] }
        ];

        for (const pageInfo of pages) {
            console.log(`\n  📄 ${pageInfo.name}`);
            await page.goto(this.baseUrl + pageInfo.path, {
                waitUntil: 'domcontentloaded',
                timeout: 30000
            });

            // Run UI tests
            const results = await page.evaluate(() => {
                const tests = {};

                // 1. Check duplicate navigation bars
                tests.duplicateNavBars = {
                    oldNav: !!document.querySelector('.mobile-tab-bar'),
                    newNav: !!document.querySelector('.ldr-mobile-bottom-nav'),
                    hasDuplicates: false
                };
                tests.duplicateNavBars.hasDuplicates =
                    tests.duplicateNavBars.oldNav && tests.duplicateNavBars.newNav;

                // 2. Check top bar elements
                const topBar = document.querySelector('.top-bar');
                if (topBar) {
                    const topBarRect = topBar.getBoundingClientRect();
                    const userInfo = document.querySelector('.user-info');
                    const logoutBtn = document.querySelector('.logout-btn');

                    tests.topBar = {
                        exists: true,
                        overflowing: topBarRect.width < topBar.scrollWidth,
                        userInfoVisible: userInfo ?
                            window.getComputedStyle(userInfo).display !== 'none' : false,
                        logoutVisible: logoutBtn ?
                            window.getComputedStyle(logoutBtn).display !== 'none' : false,
                        height: topBarRect.height,
                        isClipped: false
                    };

                    // Check if elements are clipped
                    if (userInfo) {
                        const userRect = userInfo.getBoundingClientRect();
                        tests.topBar.isClipped = userRect.right > window.innerWidth;
                    }
                } else {
                    tests.topBar = { exists: false };
                }

                // 3. Check input fields accessibility
                const inputs = document.querySelectorAll('input, textarea, select');
                tests.inputs = {
                    total: inputs.length,
                    accessible: 0,
                    overlapped: [],
                    tooSmall: []
                };

                inputs.forEach(input => {
                    const rect = input.getBoundingClientRect();
                    const style = window.getComputedStyle(input);

                    // Check if visible and accessible
                    if (rect.width > 0 && rect.height > 0 &&
                        style.display !== 'none' && style.visibility !== 'hidden') {
                        tests.inputs.accessible++;

                        // Check if too small for touch (minimum 44x44px for iOS)
                        if (rect.height < 44) {
                            tests.inputs.tooSmall.push({
                                type: input.tagName,
                                height: rect.height,
                                id: input.id || input.name
                            });
                        }
                    }

                    // Check for overlaps with navigation
                    const navBar = document.querySelector('.ldr-mobile-bottom-nav, .mobile-tab-bar');
                    if (navBar) {
                        const navRect = navBar.getBoundingClientRect();
                        if (rect.bottom > navRect.top && rect.top < navRect.bottom) {
                            tests.inputs.overlapped.push({
                                type: input.tagName,
                                id: input.id || input.name
                            });
                        }
                    }
                });

                // 4. Check buttons and touch targets
                const buttons = document.querySelectorAll('button, .btn, a.btn');
                tests.buttons = {
                    total: buttons.length,
                    tooSmall: [],
                    overlapped: []
                };

                buttons.forEach(button => {
                    const rect = button.getBoundingClientRect();
                    if (rect.height < 44 || rect.width < 44) {
                        tests.buttons.tooSmall.push({
                            text: button.textContent.trim().substring(0, 20),
                            size: `${rect.width}x${rect.height}`
                        });
                    }
                });

                // 5. Check horizontal scrolling (should not exist)
                tests.horizontalScroll = {
                    bodyWidth: document.body.scrollWidth,
                    windowWidth: window.innerWidth,
                    hasScroll: document.body.scrollWidth > window.innerWidth
                };

                // 6. Check content padding for nav bars
                const mainContent = document.querySelector('.main-content, .page, main');
                if (mainContent) {
                    const contentRect = mainContent.getBoundingClientRect();
                    const navBar = document.querySelector('.ldr-mobile-bottom-nav');
                    tests.contentPadding = {
                        hasBottomPadding: false,
                        bottomSpace: 0
                    };

                    if (navBar) {
                        const navRect = navBar.getBoundingClientRect();
                        tests.contentPadding.bottomSpace = window.innerHeight - contentRect.bottom;
                        tests.contentPadding.hasBottomPadding =
                            tests.contentPadding.bottomSpace >= navRect.height;
                    }
                }

                // 7. Check tab navigation (Settings page)
                const tabs = document.querySelectorAll('.nav-tabs, .tab-navigation, [role="tablist"]');
                if (tabs.length > 0) {
                    const tabContainer = tabs[0];
                    const tabRect = tabContainer.getBoundingClientRect();
                    tests.tabs = {
                        exists: true,
                        overflowing: tabContainer.scrollWidth > tabRect.width,
                        scrollable: window.getComputedStyle(tabContainer).overflowX === 'auto' ||
                                   window.getComputedStyle(tabContainer).overflowX === 'scroll'
                    };
                }

                // 8. Check modals and overlays
                const modals = document.querySelectorAll('.modal, .sheet-menu, .overlay');
                tests.modals = {
                    visible: [],
                    zIndexIssues: []
                };

                modals.forEach(modal => {
                    const style = window.getComputedStyle(modal);
                    if (style.display !== 'none' && style.visibility !== 'hidden') {
                        tests.modals.visible.push(modal.className);

                        // Check z-index
                        const zIndex = parseInt(style.zIndex, 10) || 0;
                        if (zIndex < 1000) {
                            tests.modals.zIndexIssues.push({
                                class: modal.className,
                                zIndex
                            });
                        }
                    }
                });

                // 9. Check text readability
                const textElements = document.querySelectorAll('p, span, label, h1, h2, h3, h4, h5, h6');
                tests.text = {
                    tooSmall: [],
                    truncated: []
                };

                textElements.forEach(elem => {
                    const style = window.getComputedStyle(elem);
                    const fontSize = parseFloat(style.fontSize);

                    if (fontSize < 12) {
                        tests.text.tooSmall.push({
                            tag: elem.tagName,
                            fontSize,
                            text: elem.textContent.substring(0, 30)
                        });
                    }

                    // Check for text overflow
                    if (elem.scrollWidth > elem.clientWidth) {
                        tests.text.truncated.push({
                            tag: elem.tagName,
                            text: elem.textContent.substring(0, 30)
                        });
                    }
                });

                return tests;
            });

            // Analyze results
            this.analyzeResults(device.name, pageInfo.name, results);

            // Take screenshot for review
            const screenshotDir = './mobile-ui-tests';
            await fs.mkdir(screenshotDir, { recursive: true });
            const screenshotPath = path.join(screenshotDir, `${device.name}_${pageInfo.name}.png`);
            await page.screenshot({ path: screenshotPath, fullPage: false });
        }

        await page.close();
    }

    analyzeResults(device, pageName, results) {
        const context = `${device} - ${pageName}`;

        // Check for critical issues
        if (results.duplicateNavBars?.hasDuplicates) {
            this.results.failed.push(`${context}: Duplicate navigation bars (both old and new)`);
        }

        if (results.topBar?.isClipped) {
            this.results.failed.push(`${context}: Top bar elements are clipped/cut off`);
        }

        if (results.inputs?.overlapped?.length > 0) {
            this.results.failed.push(`${context}: ${results.inputs.overlapped.length} input(s) overlapped by navigation`);
        }

        if (results.horizontalScroll?.hasScroll) {
            this.results.failed.push(`${context}: Horizontal scroll detected (${results.horizontalScroll.bodyWidth}px > ${results.horizontalScroll.windowWidth}px)`);
        }

        if (results.contentPadding && !results.contentPadding.hasBottomPadding) {
            this.results.warnings.push(`${context}: Content may be hidden behind navigation bar`);
        }

        if (results.tabs?.overflowing && !results.tabs?.scrollable) {
            this.results.failed.push(`${context}: Tab navigation overflowing and not scrollable`);
        }

        // Check for warnings
        if (results.inputs?.tooSmall?.length > 0) {
            this.results.warnings.push(`${context}: ${results.inputs.tooSmall.length} input(s) below 44px touch target`);
        }

        if (results.buttons?.tooSmall?.length > 0) {
            this.results.warnings.push(`${context}: ${results.buttons.tooSmall.length} button(s) below 44px touch target`);
        }

        if (results.text?.tooSmall?.length > 0) {
            this.results.warnings.push(`${context}: ${results.text.tooSmall.length} text element(s) below 12px`);
        }

        if (results.text?.truncated?.length > 0) {
            this.results.warnings.push(`${context}: ${results.text.truncated.length} text element(s) truncated`);
        }

        // Log success if no issues
        if (!this.hasIssues(results)) {
            this.results.passed.push(`${context}: All UI elements properly displayed`);
        }
    }

    hasIssues(results) {
        return results.duplicateNavBars?.hasDuplicates ||
               results.topBar?.isClipped ||
               results.inputs?.overlapped?.length > 0 ||
               results.horizontalScroll?.hasScroll ||
               (results.tabs?.overflowing && !results.tabs?.scrollable);
    }

    printResults() {
        console.log('\n' + '═'.repeat(60));
        console.log('📊 MOBILE UI TEST RESULTS');
        console.log('═'.repeat(60));

        if (this.results.passed.length > 0) {
            console.log('\n✅ PASSED:');
            this.results.passed.forEach(p => console.log(`  ${p}`));
        }

        if (this.results.failed.length > 0) {
            console.log('\n❌ FAILED:');
            this.results.failed.forEach(f => console.log(`  ${f}`));
        }

        if (this.results.warnings.length > 0) {
            console.log('\n⚠️  WARNINGS:');
            this.results.warnings.forEach(w => console.log(`  ${w}`));
        }

        console.log('\n' + '═'.repeat(60));
        console.log(`Total: ${this.results.passed.length} passed, ${this.results.failed.length} failed, ${this.results.warnings.length} warnings`);

        if (this.results.failed.length === 0) {
            console.log('✅ All critical UI tests passed!');
        } else {
            console.log('❌ Critical UI issues found - see failures above');
        }
    }
}

// Run tests
if (require.main === module) {
    const tester = new MobileUITester();
    tester.test();
}

module.exports = MobileUITester;
