#!/usr/bin/env node

/**
 * COMPREHENSIVE DOCKER VALIDATION TEST SUITE
 * 
 * Tests all implemented features in the Docker environment:
 * - New trainer pages: venue management, organizer management, training leads
 * - Master trainer pages: Google Sheets, announcements, pending approvals, trainers
 * - Core functionality: authentication, dashboards, event management
 * - Layout fixes and navigation
 */

const { chromium } = require('playwright');
const fs = require('fs').promises;
const path = require('path');

// Configuration
const CONFIG = {
    baseUrl: 'http://localhost:8080',
    timeout: 30000,
    screenshotDir: path.join(__dirname, 'test-evidence', 'docker-validation'),
    reportFile: path.join(__dirname, 'test-evidence', 'docker-validation-report.json')
};

// Test accounts (Docker environment defaults)
const TEST_ACCOUNTS = {
    admin: {
        username: 'admin',
        password: 'admin',
        role: 'administrator'
    },
    trainer: {
        username: 'test_trainer',
        password: 'TestTrainer123!',
        role: 'hvac_trainer'
    },
    master: {
        username: 'test_master',
        password: 'TestMaster123!',
        role: 'hvac_master_trainer'
    }
};

// URLs to validate
const TEST_URLS = {
    // New trainer pages (claimed to be implemented)
    trainer: [
        '/trainer/dashboard/',
        '/trainer/venue/list/',
        '/trainer/venue/manage/',
        '/trainer/organizer/manage/',
        '/trainer/profile/training-leads/'
    ],
    // Master trainer pages (claimed to be fixed)
    master: [
        '/master-trainer/master-dashboard/',
        '/master-trainer/events/',
        '/master-trainer/google-sheets/',
        '/master-trainer/announcements/',
        '/master-trainer/pending-approvals/',
        '/master-trainer/trainers/',
        '/master-trainer/communication-templates/'
    ],
    // Core pages
    public: [
        '/',
        '/wp-login.php',
        '/training-login/',
        '/find-trainer/'
    ]
};

class DockerValidationTester {
    constructor() {
        this.browser = null;
        this.page = null;
        this.results = {
            timestamp: new Date().toISOString(),
            environment: 'docker-local',
            baseUrl: CONFIG.baseUrl,
            testResults: [],
            summary: {
                total: 0,
                passed: 0,
                failed: 0,
                errors: []
            }
        };
    }

    async initialize() {
        console.log('🚀 Starting Docker Environment Validation...');
        console.log('📍 Base URL:', CONFIG.baseUrl);
        
        // Ensure screenshot directory exists
        await fs.mkdir(CONFIG.screenshotDir, { recursive: true });
        
        this.browser = await chromium.launch({
            headless: true,
            timeout: CONFIG.timeout
        });
        
        this.page = await this.browser.newPage();
        this.page.setDefaultTimeout(CONFIG.timeout);
        
        // Set viewport for consistent screenshots
        await this.page.setViewportSize({ width: 1280, height: 720 });
    }

    async cleanup() {
        if (this.browser) {
            await this.browser.close();
        }
    }

    async takeScreenshot(name, description) {
        const filename = `${name.replace(/[^a-zA-Z0-9]/g, '-')}-${Date.now()}.png`;
        const filepath = path.join(CONFIG.screenshotDir, filename);
        
        await this.page.screenshot({ 
            path: filepath, 
            fullPage: true 
        });
        
        return { filename, filepath, description };
    }

    async testUrl(url, expectedTitle = null, description = null) {
        const testName = `URL: ${url}`;
        const result = {
            test: testName,
            url: url,
            description: description || `Testing ${url}`,
            passed: false,
            error: null,
            screenshot: null,
            details: {}
        };

        this.results.summary.total++;

        try {
            console.log(`\n🧪 Testing: ${url}`);
            
            const response = await this.page.goto(CONFIG.baseUrl + url, {
                waitUntil: 'networkidle',
                timeout: CONFIG.timeout
            });

            const status = response.status();
            const title = await this.page.title();
            
            result.details.httpStatus = status;
            result.details.pageTitle = title;

            // Take screenshot for evidence
            result.screenshot = await this.takeScreenshot(
                url.replace(/\//g, '-') || 'homepage',
                `Screenshot of ${url}`
            );

            // Check for WordPress errors
            const hasWordPressError = await this.page.evaluate(() => {
                return document.body.innerHTML.includes('Fatal error') ||
                       document.body.innerHTML.includes('Parse error') ||
                       document.body.innerHTML.includes('Warning:') ||
                       document.body.innerHTML.includes('Notice:');
            });

            // Check for HTTP errors
            if (status >= 400) {
                result.error = `HTTP ${status} error`;
            } else if (hasWordPressError) {
                result.error = 'WordPress PHP error detected';
            } else if (expectedTitle && !title.includes(expectedTitle)) {
                result.error = `Title mismatch. Expected: ${expectedTitle}, Got: ${title}`;
            } else {
                result.passed = true;
                this.results.summary.passed++;
                console.log(`✅ ${url} - ${title}`);
            }

        } catch (error) {
            result.error = error.message;
            result.screenshot = await this.takeScreenshot(
                `error-${url.replace(/\//g, '-')}`,
                `Error screenshot for ${url}`
            );
            console.log(`❌ ${url} - ${error.message}`);
        }

        if (!result.passed) {
            this.results.summary.failed++;
            this.results.summary.errors.push({
                url: url,
                error: result.error
            });
        }

        this.results.testResults.push(result);
        return result;
    }

    async testAuthentication(account) {
        console.log(`\n🔐 Testing authentication for ${account.role}...`);
        
        try {
            // Go to wp-login.php
            await this.page.goto(CONFIG.baseUrl + '/wp-login.php');
            
            // Fill login form
            await this.page.fill('#user_login', account.username);
            await this.page.fill('#user_pass', account.password);
            
            // Take screenshot before login
            await this.takeScreenshot(`login-form-${account.role}`, `Login form for ${account.role}`);
            
            // Click login
            await this.page.click('#wp-submit');
            
            // Wait for navigation
            await this.page.waitForLoadState('networkidle');
            
            // Check if logged in successfully
            const currentUrl = this.page.url();
            const title = await this.page.title();
            
            // Take screenshot after login
            await this.takeScreenshot(`after-login-${account.role}`, `After login for ${account.role}`);
            
            if (currentUrl.includes('wp-admin') || title.includes('Dashboard')) {
                console.log(`✅ Authentication successful for ${account.role}`);
                return true;
            } else {
                console.log(`❌ Authentication failed for ${account.role} - redirected to ${currentUrl}`);
                return false;
            }
            
        } catch (error) {
            console.log(`❌ Authentication error for ${account.role}: ${error.message}`);
            return false;
        }
    }

    async testWordPressHealth() {
        console.log('\n🏥 Testing WordPress Health...');
        
        const healthResult = {
            test: 'WordPress Health Check',
            passed: false,
            details: {}
        };

        try {
            // Test WordPress admin access
            await this.page.goto(CONFIG.baseUrl + '/wp-admin/', { timeout: 10000 });
            
            const title = await this.page.title();
            const hasLoginForm = await this.page.locator('#loginform').isVisible().catch(() => false);
            const hasAdminBar = await this.page.locator('#wpadminbar').isVisible().catch(() => false);
            
            healthResult.details.adminPageTitle = title;
            healthResult.details.hasLoginForm = hasLoginForm;
            healthResult.details.hasAdminBar = hasAdminBar;
            
            // Take screenshot
            healthResult.screenshot = await this.takeScreenshot('wp-health-check', 'WordPress health check');
            
            // WordPress is healthy if we get login form or admin bar
            if (hasLoginForm || hasAdminBar || title.includes('WordPress')) {
                healthResult.passed = true;
                console.log('✅ WordPress is responding correctly');
            } else {
                console.log('⚠️ WordPress health check inconclusive');
            }
            
        } catch (error) {
            healthResult.error = error.message;
            console.log(`❌ WordPress health check failed: ${error.message}`);
        }

        this.results.testResults.push(healthResult);
        return healthResult;
    }

    async runComprehensiveValidation() {
        try {
            await this.initialize();
            
            // 1. WordPress Health Check
            await this.testWordPressHealth();
            
            // 2. Test Public URLs
            console.log('\n📄 Testing Public Pages...');
            for (const url of TEST_URLS.public) {
                await this.testUrl(url);
            }
            
            // 3. Test Authentication
            console.log('\n🔐 Testing Authentication...');
            const authResults = {};
            for (const [role, account] of Object.entries(TEST_ACCOUNTS)) {
                authResults[role] = await this.testAuthentication(account);
            }
            
            // 4. Test Protected URLs (without authentication for now)
            console.log('\n🔒 Testing Protected Pages (access control)...');
            
            // Test trainer pages
            console.log('\n👨‍🔧 Testing New Trainer Pages...');
            for (const url of TEST_URLS.trainer) {
                await this.testUrl(url, null, `New trainer page: ${url}`);
            }
            
            // Test master trainer pages
            console.log('\n👨‍💼 Testing Master Trainer Pages...');
            for (const url of TEST_URLS.master) {
                await this.testUrl(url, null, `Master trainer page: ${url}`);
            }
            
            // 5. Generate summary
            this.generateSummary();
            
        } catch (error) {
            console.error('❌ Critical test failure:', error);
            this.results.summary.errors.push({
                type: 'critical',
                error: error.message
            });
        } finally {
            await this.cleanup();
        }
    }

    generateSummary() {
        console.log('\n📊 TEST SUMMARY');
        console.log('================');
        console.log(`Total Tests: ${this.results.summary.total}`);
        console.log(`Passed: ${this.results.summary.passed}`);
        console.log(`Failed: ${this.results.summary.failed}`);
        console.log(`Success Rate: ${((this.results.summary.passed / this.results.summary.total) * 100).toFixed(1)}%`);
        
        if (this.results.summary.errors.length > 0) {
            console.log('\n❌ ERRORS:');
            this.results.summary.errors.forEach(error => {
                console.log(`   • ${error.url || error.type}: ${error.error}`);
            });
        }
        
        // Key findings
        console.log('\n🔍 KEY FINDINGS:');
        
        const newTrainerPages = this.results.testResults.filter(r => 
            r.url && TEST_URLS.trainer.includes(r.url)
        );
        const newTrainerPagesWorking = newTrainerPages.filter(r => r.passed).length;
        console.log(`   • New Trainer Pages: ${newTrainerPagesWorking}/${newTrainerPages.length} working`);
        
        const masterPages = this.results.testResults.filter(r => 
            r.url && TEST_URLS.master.includes(r.url)
        );
        const masterPagesWorking = masterPages.filter(r => r.passed).length;
        console.log(`   • Master Trainer Pages: ${masterPagesWorking}/${masterPages.length} working`);
        
        const publicPages = this.results.testResults.filter(r => 
            r.url && TEST_URLS.public.includes(r.url)
        );
        const publicPagesWorking = publicPages.filter(r => r.passed).length;
        console.log(`   • Public Pages: ${publicPagesWorking}/${publicPages.length} working`);
        
        // Recommendations
        console.log('\n💡 RECOMMENDATIONS:');
        if (this.results.summary.failed > 0) {
            console.log('   • Review failed tests and fix underlying issues');
            console.log('   • Check WordPress error logs for PHP errors');
            console.log('   • Verify plugin activation and configuration');
        }
        
        if (newTrainerPagesWorking === newTrainerPages.length) {
            console.log('   ✅ All new trainer pages are accessible');
        } else {
            console.log('   ⚠️ Some new trainer pages need attention');
        }
        
        if (masterPagesWorking === masterPages.length) {
            console.log('   ✅ All master trainer pages are accessible');
        } else {
            console.log('   ⚠️ Some master trainer pages need attention');
        }
        
        console.log(`\n📸 Screenshots saved to: ${CONFIG.screenshotDir}`);
        console.log(`📋 Full report will be saved to: ${CONFIG.reportFile}`);
    }

    async saveReport() {
        try {
            await fs.writeFile(
                CONFIG.reportFile,
                JSON.stringify(this.results, null, 2)
            );
            console.log(`\n✅ Full report saved: ${CONFIG.reportFile}`);
        } catch (error) {
            console.error('❌ Failed to save report:', error.message);
        }
    }
}

// Run the validation
async function main() {
    const tester = new DockerValidationTester();
    
    try {
        await tester.runComprehensiveValidation();
        await tester.saveReport();
        
        // Exit with appropriate code
        const success = tester.results.summary.failed === 0;
        process.exit(success ? 0 : 1);
        
    } catch (error) {
        console.error('❌ Test suite failed:', error);
        process.exit(1);
    }
}

// Run if called directly
if (require.main === module) {
    main().catch(console.error);
}

module.exports = { DockerValidationTester };