/**
 * Performance & Resource Optimization Test Suite
 * 
 * Tests the major performance improvements after architectural refactoring:
 * - CSS consolidation (250+ files → 5 bundles)
 * - HTTP request reduction (85% target)
 * - Page load performance (85% faster)
 * - Safari browser stability
 * - Memory usage optimization
 * 
 * @package HVAC_Community_Events
 * @version 3.0.0
 * @created 2025-08-20
 */

const { test, expect, authHelpers, LoginPage } = require('../helpers/auth-fixtures');
const path = require('path');

// Test configuration
const BASE_URL = process.env.UPSKILL_STAGING_URL || 'https://upskill-staging.measurequick.com';
const TEST_TIMEOUT = 120000; // Extended for performance tests

// Performance thresholds (based on 85% improvement target)
const PERFORMANCE_TARGETS = {
    maxCssFiles: 5,           // Down from 250+
    maxJsFiles: 10,           // Reasonable limit
    maxPageLoadTime: 3000,    // 3 seconds (85% faster)
    maxHttpRequests: 25,      // 85% reduction target
    maxMemoryUsage: 100,      // MB threshold
    maxDomNodes: 5000         // DOM complexity limit
};

async function measurePagePerformance(page, url) {
    const startTime = Date.now();
    
    // Clear cache and storage
    await page.evaluate(() => {
        if (window.performance && window.performance.clearResourceTimings) {
            window.performance.clearResourceTimings();
        }
        if (window.caches) {
            caches.keys().then(names => {
                names.forEach(name => caches.delete(name));
            });
        }
    });

    // Navigate and measure
    await page.goto(url, { waitUntil: 'networkidle' });
    const loadTime = Date.now() - startTime;
    
    // Get resource counts
    const resources = await page.evaluate(() => {
        const entries = performance.getEntriesByType('resource');
        const cssFiles = entries.filter(e => e.name.includes('.css')).length;
        const jsFiles = entries.filter(e => e.name.includes('.js')).length;
        const totalRequests = entries.length;
        
        return { cssFiles, jsFiles, totalRequests, loadTime: performance.timing.loadEventEnd - performance.timing.navigationStart };
    });

    // Get DOM complexity
    const domStats = await page.evaluate(() => {
        return {
            nodeCount: document.querySelectorAll('*').length,
            depth: Math.max(...Array.from(document.querySelectorAll('*')).map(el => {
                let depth = 0;
                let parent = el.parentElement;
                while (parent) {
                    depth++;
                    parent = parent.parentElement;
                }
                return depth;
            }))
        };
    });

    return {
        loadTime,
        clientLoadTime: resources.loadTime,
        ...resources,
        ...domStats
    };
}

async function monitorMemoryUsage(page) {
    const memoryInfo = await page.evaluate(() => {
        if (performance.memory) {
            return {
                usedJSHeapSize: performance.memory.usedJSHeapSize / 1024 / 1024, // MB
                totalJSHeapSize: performance.memory.totalJSHeapSize / 1024 / 1024, // MB
                jsHeapSizeLimit: performance.memory.jsHeapSizeLimit / 1024 / 1024 // MB
            };
        }
        return null;
    });
    
    return memoryInfo;
}

async function takePerformanceScreenshot(page, name, metrics) {
    const screenshotDir = path.join(__dirname, '../../screenshots/performance');
    await require('fs').promises.mkdir(screenshotDir, { recursive: true });
    
    await page.screenshot({ 
        path: path.join(screenshotDir, `${name}-${Date.now()}.png`),
        fullPage: true 
    });
    
    // Log metrics for debugging
    console.log(`Performance metrics for ${name}:`, metrics);
}

test.describe('Performance & Resource Optimization Tests', () => {
    test.setTimeout(TEST_TIMEOUT);
    
    test.beforeEach(async ({ page }) => {
        await page.setViewportSize({ width: 1280, height: 720 });
        // Login before each performance test
        await authHelpers.loginAs(page, 'trainer');
    });

    test.describe('CSS Consolidation Tests', () => {
        test('should load maximum 5 CSS files on dashboard', async ({ page }) => {
            const metrics = await measurePagePerformance(page, `${BASE_URL}/trainer/dashboard/`);
            
            console.log(`CSS files loaded: ${metrics.cssFiles}`);
            expect(metrics.cssFiles).toBeLessThanOrEqual(PERFORMANCE_TARGETS.maxCssFiles);
            
            await takePerformanceScreenshot(page, 'css-consolidation-dashboard', metrics);
        });

        test('should maintain CSS consolidation across all trainer pages', async ({ page }) => {
            const pages = [
                '/trainer/dashboard/',
                '/trainer/profile/',
                '/trainer/certificate-reports/',
                '/trainer/events/',
                '/trainer/events/create/'
            ];
            
            for (const pagePath of pages) {
                const metrics = await measurePagePerformance(page, `${BASE_URL}${pagePath}`);
                
                console.log(`CSS files on ${pagePath}: ${metrics.cssFiles}`);
                expect(metrics.cssFiles).toBeLessThanOrEqual(PERFORMANCE_TARGETS.maxCssFiles);
            }
        });

        test('should not load foreign CSS files', async ({ page }) => {
            await page.goto(`${BASE_URL}/trainer/dashboard/`);
            
            // Check for unwanted CSS files
            const foreignCss = await page.evaluate(() => {
                const links = Array.from(document.querySelectorAll('link[rel="stylesheet"]'));
                return links.filter(link => {
                    const href = link.href;
                    return !href.includes('hvac-') && 
                           !href.includes('wordpress') && 
                           !href.includes('wp-') &&
                           !href.includes('astra') &&
                           href.includes('.css');
                }).map(link => link.href);
            });
            
            console.log('Foreign CSS files detected:', foreignCss);
            expect(foreignCss.length).toBeLessThan(10); // Allow some theme/plugin CSS
        });
    });

    test.describe('Page Load Performance Tests', () => {
        test('should load dashboard within performance target', async ({ page }) => {
            // Dashboard is already loaded from beforeEach login, measure reload performance
            const dashboardStartTime = Date.now();
            await page.goto(`${BASE_URL}/trainer/dashboard/`, { waitUntil: 'networkidle' });
            const dashboardLoadTime = Date.now() - dashboardStartTime;
            
            console.log(`Dashboard load time: ${dashboardLoadTime}ms`);
            expect(dashboardLoadTime).toBeLessThan(PERFORMANCE_TARGETS.maxPageLoadTime);
            
            await takePerformanceScreenshot(page, 'dashboard-performance', { loadTime: dashboardLoadTime });
        });

        test('should maintain fast load times on subsequent pages', async ({ page }) => {
            const pages = [
                '/trainer/profile/',
                '/trainer/certificate-reports/',
                '/trainer/events/'
            ];
            
            for (const pagePath of pages) {
                const startTime = Date.now();
                await page.goto(`${BASE_URL}${pagePath}`, { waitUntil: 'networkidle' });
                const loadTime = Date.now() - startTime;
                
                console.log(`Load time for ${pagePath}: ${loadTime}ms`);
                expect(loadTime).toBeLessThan(PERFORMANCE_TARGETS.maxPageLoadTime);
            }
        });

        test('should handle concurrent page loads without degradation', async ({ browser }) => {
            const contexts = await Promise.all([
                browser.newContext(),
                browser.newContext(),
                browser.newContext()
            ]);
            
            const pages = await Promise.all(contexts.map(ctx => ctx.newPage()));
            
            // Simulate concurrent users
            const loadPromises = pages.map(async (page, index) => {
                const startTime = Date.now();
                await page.goto(`${BASE_URL}/trainer/dashboard/`);
                const loadTime = Date.now() - startTime;
                
                return { page: index, loadTime };
            });
            
            const results = await Promise.all(loadPromises);
            
            // All concurrent loads should complete within acceptable time
            results.forEach(result => {
                console.log(`Concurrent load ${result.page}: ${result.loadTime}ms`);
                expect(result.loadTime).toBeLessThan(PERFORMANCE_TARGETS.maxPageLoadTime * 2); // Allow 2x for concurrent
            });
            
            // Cleanup
            await Promise.all(contexts.map(ctx => ctx.close()));
        });
    });

    test.describe('HTTP Request Optimization Tests', () => {
        test('should minimize HTTP requests on dashboard', async ({ page }) => {
            const metrics = await measurePagePerformance(page, `${BASE_URL}/trainer/dashboard/`);
            
            console.log(`Total HTTP requests: ${metrics.totalRequests}`);
            expect(metrics.totalRequests).toBeLessThan(PERFORMANCE_TARGETS.maxHttpRequests);
            
            await takePerformanceScreenshot(page, 'http-requests-dashboard', metrics);
        });

        test('should use resource caching effectively', async ({ page }) => {
            // First load
            const firstLoad = await measurePagePerformance(page, `${BASE_URL}/trainer/dashboard/`);
            
            // Second load (should use cache)
            const secondLoad = await measurePagePerformance(page, `${BASE_URL}/trainer/dashboard/`);
            
            console.log(`First load requests: ${firstLoad.totalRequests}, Second load: ${secondLoad.totalRequests}`);
            
            // Second load should have fewer requests due to caching
            expect(secondLoad.totalRequests).toBeLessThanOrEqual(firstLoad.totalRequests);
        });
    });

    test.describe('Safari Browser Stability Tests', () => {
        test('should load without hanging in Safari/WebKit', async ({ page, browserName }) => {
            test.skip(browserName !== 'webkit', 'Safari-specific test');
            
            // Extended timeout for Safari
            test.setTimeout(180000);
            
            const startTime = Date.now();
            
            try {
                await page.goto(`${BASE_URL}/find-trainer/`, { 
                    waitUntil: 'networkidle',
                    timeout: 60000 
                });
                
                const loadTime = Date.now() - startTime;
                console.log(`Safari load time: ${loadTime}ms`);
                
                // Verify page actually loaded
                await expect(page.locator('body')).toBeVisible();
                
                // Check for interactive elements
                const interactiveElements = await page.$$('button, a, input, select');
                expect(interactiveElements.length).toBeGreaterThan(0);
                
                await takePerformanceScreenshot(page, 'safari-stability', { loadTime });
                
            } catch (error) {
                console.error('Safari loading failed:', error);
                await page.screenshot({ 
                    path: path.join(__dirname, '../../screenshots/safari-failure.png'),
                    fullPage: true 
                });
                throw error;
            }
        });

        test('should handle Safari resource loading efficiently', async ({ page, browserName }) => {
            test.skip(browserName !== 'webkit', 'Safari-specific test');
            
            await page.goto(`${BASE_URL}/trainer/dashboard/`);
            
            // Monitor for resource loading cascade issues
            const resourceTimings = await page.evaluate(() => {
                const entries = performance.getEntriesByType('resource');
                return entries.map(entry => ({
                    name: entry.name,
                    duration: entry.duration,
                    transferSize: entry.transferSize || 0
                }));
            });
            
            // Check for excessively long resource loads
            const slowResources = resourceTimings.filter(r => r.duration > 5000);
            console.log('Slow resources in Safari:', slowResources);
            
            expect(slowResources.length).toBeLessThan(3); // Allow some tolerance
        });
    });

    test.describe('Memory Usage Tests', () => {
        test('should maintain reasonable memory usage', async ({ page, browserName }) => {
            test.skip(browserName !== 'chromium', 'Memory API only available in Chromium');
            
            // Initial memory
            const initialMemory = await monitorMemoryUsage(page);
            
            // Navigate through multiple pages to stress test
            const pages = [
                '/trainer/dashboard/',
                '/trainer/profile/',
                '/trainer/certificate-reports/',
                '/trainer/events/',
                '/trainer/profile/edit/'
            ];
            
            for (const pagePath of pages) {
                await page.goto(`${BASE_URL}${pagePath}`);
                await page.waitForLoadState('networkidle');
            }
            
            // Final memory check
            const finalMemory = await monitorMemoryUsage(page);
            
            if (initialMemory && finalMemory) {
                const memoryIncrease = finalMemory.usedJSHeapSize - initialMemory.usedJSHeapSize;
                console.log(`Memory usage increase: ${memoryIncrease.toFixed(2)}MB`);
                
                expect(finalMemory.usedJSHeapSize).toBeLessThan(PERFORMANCE_TARGETS.maxMemoryUsage);
                expect(memoryIncrease).toBeLessThan(50); // Max 50MB increase during navigation
            }
        });

        test('should clean up memory after heavy operations', async ({ page, browserName }) => {
            test.skip(browserName !== 'chromium', 'Memory API only available in Chromium');
            
            await page.goto(`${BASE_URL}/trainer/events/create/`);
            
            const beforeMemory = await monitorMemoryUsage(page);
            
            // Simulate heavy form interaction
            for (let i = 0; i < 10; i++) {
                await page.reload();
                await page.waitForLoadState('networkidle');
            }
            
            // Force garbage collection if available
            await page.evaluate(() => {
                if (window.gc) {
                    window.gc();
                }
            });
            
            const afterMemory = await monitorMemoryUsage(page);
            
            if (beforeMemory && afterMemory) {
                console.log(`Memory before: ${beforeMemory.usedJSHeapSize.toFixed(2)}MB, after: ${afterMemory.usedJSHeapSize.toFixed(2)}MB`);
                
                // Memory should not have grown excessively
                const memoryGrowth = afterMemory.usedJSHeapSize - beforeMemory.usedJSHeapSize;
                expect(memoryGrowth).toBeLessThan(30); // Max 30MB growth for heavy operations
            }
        });
    });

    test.describe('DOM Complexity Tests', () => {
        test('should maintain reasonable DOM complexity', async ({ page }) => {
            const pages = [
                '/trainer/dashboard/',
                '/trainer/profile/',
                '/trainer/events/'
            ];
            
            for (const pagePath of pages) {
                const metrics = await measurePagePerformance(page, `${BASE_URL}${pagePath}`);
                
                console.log(`DOM nodes on ${pagePath}: ${metrics.nodeCount}`);
                expect(metrics.nodeCount).toBeLessThan(PERFORMANCE_TARGETS.maxDomNodes);
                expect(metrics.depth).toBeLessThan(20); // Reasonable DOM depth
            }
        });

        test('should optimize form rendering performance', async ({ page }) => {
            await page.goto(`${BASE_URL}/trainer/events/create/`);
            
            const formMetrics = await page.evaluate(() => {
                const forms = document.querySelectorAll('form');
                const inputs = document.querySelectorAll('input, select, textarea');
                
                return {
                    formCount: forms.length,
                    inputCount: inputs.length,
                    renderTime: performance.now()
                };
            });
            
            console.log('Form complexity:', formMetrics);
            
            // Forms should render efficiently
            expect(formMetrics.inputCount).toBeLessThan(100); // Reasonable form complexity
            expect(formMetrics.renderTime).toBeLessThan(1000); // Quick render time
        });
    });
});

// Export performance test configuration
module.exports = {
    testDir: __dirname,
    timeout: TEST_TIMEOUT,
    retries: 2, // Performance tests may need retries
    workers: 1, // Sequential for accurate performance measurement
    use: {
        baseURL: BASE_URL,
        screenshot: 'only-on-failure',
        video: 'retain-on-failure',
        trace: 'retain-on-failure'
    }
};