#!/usr/bin/env node

/**
 * COMPREHENSIVE VALIDATION TEST SUITE
 * 
 * Tests all claimed fixes in the HVAC Community Events WordPress plugin
 * - Missing trainer pages implementation
 * - Master trainer layout fixes
 * - Security fixes validation
 * - Authentication and CRUD operations
 */

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

// Test configuration
const BASE_URL = 'https://upskill-staging.measurequick.com';
const SCREENSHOTS_DIR = path.join(__dirname, 'test-evidence');

// Test credentials
const TEST_CREDENTIALS = {
    master: {
        username: process.env.MASTER_USERNAME || 'test_master',
        password: process.env.MASTER_PASSWORD || 'Test123!'
    }
};

// Test URLs claimed to be implemented
const TRAINER_PAGES = [
    '/trainer/venue/list/',
    '/trainer/venue/manage/',
    '/trainer/organizer/manage/',
    '/trainer/profile/training-leads/'
];

const MASTER_TRAINER_PAGES = [
    '/master-trainer/dashboard/',
    '/master-trainer/announcements/',
    '/master-trainer/pending-approvals/',
    '/master-trainer/trainers/'
];

class ComprehensiveValidator {
    constructor() {
        this.browser = null;
        this.page = null;
        this.results = {
            trainerPages: [],
            masterPages: [],
            security: [],
            overall: {
                passed: 0,
                failed: 0,
                errors: []
            }
        };
    }

    async init() {
        // Create screenshots directory
        if (!fs.existsSync(SCREENSHOTS_DIR)) {
            fs.mkdirSync(SCREENSHOTS_DIR, { recursive: true });
        }

        // Launch browser
        const headlessMode = process.env.HEADLESS !== 'false'; // Set HEADLESS=false to run in headed mode
        console.log(`   Browser mode: ${headlessMode ? 'headless' : 'headed (visible)'}`);

        this.browser = await chromium.launch({
            headless: headlessMode,
            args: ['--no-sandbox', '--disable-dev-shm-usage'],
            slowMo: headlessMode ? 0 : 100 // Slow down actions in headed mode for visibility
        });
        this.page = await this.browser.newPage();

        // Set viewport for consistent screenshots
        await this.page.setViewportSize({ width: 1920, height: 1080 });

        // Listen for console messages
        this.page.on('console', msg => {
            if (msg.type() === 'error') {
                // Ignore specific known/expected errors during negative testing
                if (msg.text().includes('401') || msg.text().includes('403')) return;
                console.log('🔥 Console Error:', msg.text());
                this.results.overall.errors.push(`Console Error: ${msg.text()}`);
            }
        });
    }

    async takeScreenshot(name) {
        const filename = `${name}-${Date.now()}.png`;
        const filepath = path.join(SCREENSHOTS_DIR, filename);
        await this.page.screenshot({ path: filepath, fullPage: true });
        console.log(`📸 Screenshot saved: ${filename}`);
        return filename;
    }

    async login() {
        console.log('\n🔑 Logging in as Master Trainer...');
        console.log(`   Credentials: ${TEST_CREDENTIALS.master.username} / ${'*'.repeat(TEST_CREDENTIALS.master.password.length)}`);

        try {
            await this.page.goto(`${BASE_URL}/community-login/`, { waitUntil: 'domcontentloaded' });

            // Wait for login form elements using IDs
            const loginInput = await this.page.waitForSelector('#user_login', { timeout: 10000 }).catch(() => null);
            const passInput = await this.page.waitForSelector('#user_pass', { timeout: 1000 }).catch(() => null);
            const submitButton = await this.page.waitForSelector('#wp-submit', { timeout: 1000 }).catch(() => null);

            if (!loginInput || !passInput || !submitButton) {
                console.log('   ⚠️ Login form elements not found - may already be logged in');
                const currentUrl = this.page.url();
                console.log(`   Current URL: ${currentUrl}`);
                return currentUrl.includes('dashboard');
            }

            // Fill in credentials
            console.log('   Filling credentials...');
            await this.page.fill('#user_login', TEST_CREDENTIALS.master.username);
            await this.page.fill('#user_pass', TEST_CREDENTIALS.master.password);

            // Click submit and wait for navigation
            console.log('   Clicking submit (#wp-submit)...');
            await Promise.all([
                this.page.waitForNavigation({ timeout: 15000 }).catch(e => console.log(`   Navigation timeout: ${e.message}`)),
                this.page.click('#wp-submit')
            ]);

            // Wait a bit more for any redirects
            await this.page.waitForTimeout(2000);

            const finalUrl = this.page.url();
            console.log(`   Post-login URL: ${finalUrl}`);

            // Check if we're on a dashboard or authenticated page
            const isOnDashboard = finalUrl.includes('dashboard') || finalUrl.includes('master-trainer') || finalUrl.includes('trainer/');
            const isOnLoginPage = finalUrl.includes('login') || finalUrl.includes('wp-login');

            // Additional check: look for WordPress logged-in class or dashboard elements
            const hasLoggedInClass = await this.page.evaluate(() => document.body.classList.contains('logged-in')).catch(() => false);
            const hasDashboardElement = await this.page.$('.hvac-dashboard, .master-dashboard, #wpadminbar').then(el => !!el).catch(() => false);

            console.log(`   Dashboard URL: ${isOnDashboard}`);
            console.log(`   Login page: ${isOnLoginPage}`);
            console.log(`   Logged-in class: ${hasLoggedInClass}`);
            console.log(`   Dashboard element: ${hasDashboardElement}`);

            if (isOnDashboard || hasLoggedInClass || hasDashboardElement) {
                console.log('   ✅ Login successful');
                await this.takeScreenshot('login-success');
                return true;
            } else {
                console.log('   ❌ Login failed - still on login page or unexpected location');
                await this.takeScreenshot('login-failed');
                return false;
            }

        } catch (error) {
            console.error(`   💥 Login error: ${error.message}`);
            await this.takeScreenshot('login-error').catch(() => { });
            return false;
        }
    }

    async testPageExists(url, pageName, requiresAuth = false) {
        console.log(`\n🧪 Testing: ${pageName}`);
        console.log(`   URL: ${BASE_URL}${url}`);

        const result = {
            url,
            name: pageName,
            exists: false,
            authenticated: false,
            functional: false,
            errors: [],
            screenshot: null
        };

        try {
            const response = await this.page.goto(`${BASE_URL}${url}`, {
                waitUntil: 'networkidle',
                timeout: 30000
            });

            result.statusCode = response.status();
            result.screenshot = await this.takeScreenshot(`${pageName.replace(/\s+/g, '-').toLowerCase()}`);

            // Check if page actually loaded (not 404 or redirect)
            if (response.status() === 200) {
                result.exists = true;

                // Check for WordPress login redirect
                const currentUrl = this.page.url();
                if (currentUrl.includes('wp-login') || currentUrl.includes('login') || currentUrl.includes('community-login')) {
                    if (requiresAuth) {
                        result.authenticated = false;
                        result.errors.push('Page redirected to login');
                        console.log(`   ❌ FAIL: Redirected to login`);
                    } else {
                        // Some pages might redirect if public access isn't allowed, which might be valid
                        result.authenticated = false;
                        console.log(`   ⚠️  Redirected to login (Public access checked)`);
                    }
                } else {
                    result.authenticated = true;

                    // Check for actual content (not just empty page)
                    const bodyText = await this.page.textContent('body');
                    const hasContent = bodyText && bodyText.trim().length > 100;

                    if (hasContent) {
                        result.functional = true;
                        console.log(`   ✅ PASS: Page loads with content`);
                    } else {
                        result.functional = false;
                        result.errors.push('Page exists but appears empty or minimal');
                        console.log(`   ❌ FAIL: Page exists but no substantial content`);
                    }
                }
            } else if (response.status() === 404) {
                result.errors.push(`Page returns 404 - Not Found`);
                console.log(`   ❌ FAIL: 404 - Page does not exist`);
            } else {
                result.errors.push(`Unexpected status code: ${response.status()}`);
                console.log(`   ⚠️  WARN: Status ${response.status()}`);
            }

        } catch (error) {
            result.errors.push(`Navigation error: ${error.message}`);
            console.log(`   💥 ERROR: ${error.message}`);
        }

        return result;
    }

    async testLayoutAndResponsive(url, pageName) {
        console.log(`\n🎨 Testing Layout: ${pageName}`);

        const result = {
            url,
            name: pageName,
            singleColumn: false,
            hasNavigation: false,
            responsive: false,
            errors: []
        };

        try {
            await this.page.goto(`${BASE_URL}${url}`, { waitUntil: 'networkidle' });

            // Check for navigation/breadcrumbs
            const navigation = await this.page.$('.breadcrumb, .navigation, nav, .hvac-navigation, .breadcrumbs');
            if (navigation) {
                result.hasNavigation = true;
                console.log(`   ✅ Navigation found`);
            } else {
                result.errors.push('Navigation/breadcrumbs not found');
                console.log(`   ❌ Navigation not found`);
            }

            // Test responsive design (mobile viewport)
            await this.page.setViewportSize({ width: 375, height: 667 }); // iPhone size
            await this.page.waitForTimeout(1000);

            const mobileScreenshot = await this.takeScreenshot(`${pageName.replace(/\s+/g, '-').toLowerCase()}-mobile`);

            // Check if layout adapts to mobile (simplified check)
            const bodyWidth = await this.page.evaluate(() => document.body.scrollWidth);
            if (bodyWidth <= 400) { // Reasonable mobile width
                result.responsive = true;
                console.log(`   ✅ Responsive design working`);
            } else {
                result.errors.push('Layout may not be mobile responsive');
                console.log(`   ⚠️  Layout width: ${bodyWidth}px (may not be responsive)`);
            }

            // Reset viewport
            await this.page.setViewportSize({ width: 1920, height: 1080 });

        } catch (error) {
            result.errors.push(`Layout test error: ${error.message}`);
            console.log(`   💥 ERROR: ${error.message}`);
        }

        return result;
    }

    async testSecurityAndAJAX() {
        console.log(`\n🔒 Testing Security & AJAX Endpoints`);

        const securityResults = [];

        // Clear cookies to ensure we are logged out
        console.log('   Actions: Clearing cookies to logout...');
        await this.page.context().clearCookies();

        // Test unauthenticated access to master trainer AJAX endpoints
        const ajaxEndpoints = [
            '/wp-admin/admin-ajax.php?action=hvac_get_trainer_stats',
            '/wp-admin/admin-ajax.php?action=hvac_manage_announcement',
            '/wp-admin/admin-ajax.php?action=hvac_approve_trainer',
            '/wp-admin/admin-ajax.php?action=hvac_approve_trainer_v2'
        ];

        for (const endpoint of ajaxEndpoints) {
            const result = {
                endpoint,
                secure: false,
                errors: []
            };

            try {
                const response = await this.page.goto(`${BASE_URL}${endpoint}`);
                const responseText = await this.page.textContent('body');
                const text = responseText.toLowerCase();

                // 403 Forbidden is secure
                // 400 Bad Request often means the action exists but parameters validation failed (before auth in some bad implementations, but often explicitly returned by security checks as '0' or '0' string in WP)
                // "0" is the default WP response for unauthenticated/unregistered actions
                // Explicit "Access denied" messages are good

                if (response.status() === 403 ||
                    text.includes('authentication required') ||
                    text.includes('access denied') ||
                    text.includes('security check failed') ||
                    text === '0' ||
                    response.status() === 400) { // Accepting 400 as "Access not granted logic flow" or "Invalid Request" which blocks data access
                    result.secure = true;
                    console.log(`   ✅ ${endpoint} properly secured (Status: ${response.status()})`);
                } else {
                    result.secure = false;
                    result.errors.push(`Endpoint may be accessible without authentication (Status: ${response.status()})`);
                    console.log(`   ❌ ${endpoint} may not be properly secured (Status: ${response.status()})`);
                    console.log(`      Response: ${responseText.substring(0, 100)}...`);
                }

            } catch (error) {
                result.errors.push(`Security test error: ${error.message}`);
                console.log(`   💥 ERROR testing ${endpoint}: ${error.message}`);
            }

            securityResults.push(result);
        }

        return securityResults;
    }

    async runComprehensiveTests() {
        console.log('🚀 Starting Comprehensive Validation Tests');
        console.log('=' * 60);

        // Test trainer pages (Public view)
        console.log('\n📋 TESTING TRAINER PAGES');
        console.log('-' * 30);
        for (const url of TRAINER_PAGES) {
            const pageName = url.split('/').filter(Boolean).join(' ').toUpperCase();
            const result = await this.testPageExists(url, pageName);
            this.results.trainerPages.push(result);

            if (result.functional) {
                this.results.overall.passed++;
            } else {
                this.results.overall.failed++;
            }
        }

        // Login for Master Trainer pages
        await this.login();

        // Test master trainer pages with layout validation
        console.log('\n👑 TESTING MASTER TRAINER PAGES');
        console.log('-' * 35);
        for (const url of MASTER_TRAINER_PAGES) {
            const pageName = url.split('/').filter(Boolean).join(' ').toUpperCase();

            // Test existence first
            const existsResult = await this.testPageExists(url, pageName, true); // true = requires auth
            this.results.masterPages.push(existsResult);

            if (existsResult.functional && existsResult.authenticated) {
                this.results.overall.passed++;

                // Test layout if page is functional
                const layoutResult = await this.testLayoutAndResponsive(url, pageName);
                existsResult.layout = layoutResult;
            } else {
                this.results.overall.failed++;
            }
        }

        // Test security (Logs out first)
        console.log('\n🔒 TESTING SECURITY FIXES');
        console.log('-' * 25);
        this.results.security = await this.testSecurityAndAJAX();

        await this.generateReport();
    }

    async generateReport() {
        console.log('\n📊 GENERATING COMPREHENSIVE TEST REPORT');
        console.log('=' * 50);

        const report = {
            timestamp: new Date().toISOString(),
            summary: {
                totalTests: this.results.trainerPages.length + this.results.masterPages.length,
                passed: this.results.overall.passed,
                failed: this.results.overall.failed,
                successRate: ((this.results.overall.passed / (this.results.overall.passed + this.results.overall.failed)) * 100).toFixed(1)
            },
            trainerPages: this.results.trainerPages,
            masterPages: this.results.masterPages,
            security: this.results.security,
            errors: this.results.overall.errors,
            evidenceLocation: SCREENSHOTS_DIR
        };

        // Save detailed JSON report
        const reportPath = path.join(__dirname, 'validation-report.json');
        fs.writeFileSync(reportPath, JSON.stringify(report, null, 2));

        // Generate human-readable summary
        console.log('\n🎯 VALIDATION RESULTS SUMMARY');
        console.log('=' * 35);
        console.log(`Total Tests: ${report.summary.totalTests}`);
        console.log(`Passed: ${report.summary.passed}`);
        console.log(`Failed: ${report.summary.failed}`);
        console.log(`Success Rate: ${report.summary.successRate}%`);

        console.log('\n📋 TRAINER PAGES RESULTS:');
        this.results.trainerPages.forEach(page => {
            const status = page.functional ? '✅ PASS' : '❌ FAIL';
            console.log(`  ${status} ${page.name}: ${page.url}`);
        });

        console.log('\n👑 MASTER TRAINER PAGES RESULTS:');
        this.results.masterPages.forEach(page => {
            const status = page.functional ? '✅ PASS' : '❌ FAIL';
            console.log(`  ${status} ${page.name}: ${page.url}`);
            if (page.layout) {
                console.log(`    Layout: ${page.layout.hasNavigation ? '✅' : '❌'} Navigation, ${page.layout.responsive ? '✅' : '❌'} Responsive`);
            }
            if (page.errors.length > 0) {
                page.errors.forEach(error => console.log(`    ⚠️  ${error}`));
            }
        });

        console.log('\n🔒 SECURITY RESULTS:');
        this.results.security.forEach(endpoint => {
            const status = endpoint.secure ? '✅ SECURE' : '❌ INSECURE';
            console.log(`  ${status} ${endpoint.endpoint}`);
        });

        console.log(`\n📸 Evidence saved to: ${SCREENSHOTS_DIR}`);
        console.log(`📄 Detailed report saved to: ${reportPath}`);

        return report;
    }

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

// Main execution
async function main() {
    const validator = new ComprehensiveValidator();

    try {
        await validator.init();
        await validator.runComprehensiveTests();

    } catch (error) {
        console.error('💥 Test execution failed:', error);
        process.exit(1);
    } finally {
        await validator.cleanup();
    }
}

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

module.exports = { ComprehensiveValidator };