#!/usr/bin/env node

/**
 * Comprehensive E2E Test for HVAC Event Edit Functionality
 * Tests complete event creation, editing, and field population
 * 
 * @package HVAC_Community_Events
 * @version 2.0.0
 */

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

// Configuration
const CONFIG = {
    baseUrl: 'https://upskill-staging.measurequick.com',
    credentials: {
        trainer: {
            email: 'test_trainer@example.com',
            password: 'TestTrainer123!'
        },
        master: {
            email: 'test_master@example.com',
            password: 'TestMaster123!'
        },
        admin: {
            email: 'ben@upskillhvac.com',
            password: process.env.ADMIN_PASSWORD || ''
        }
    },
    screenshotDir: 'screenshots/e2e-test',
    timeout: 60000
};

// Test data
const TEST_EVENT = {
    title: `E2E Test Event ${Date.now()}`,
    description: 'This is a comprehensive E2E test event for verifying all functionality.',
    venue: 'Dallas Training Center',
    organizer: 'HVAC Training Solutions',
    cost: '399',
    startDate: '2025-09-01',
    endDate: '2025-09-02',
    startTime: '09:00',
    endTime: '17:00',
    website: 'https://example.com/test-event',
    maxAttendees: '30'
};

// Test results tracking
const RESULTS = {
    startTime: Date.now(),
    tests: [],
    passed: 0,
    failed: 0,
    screenshots: []
};

// Helper functions
async function takeScreenshot(page, name) {
    try {
        await fs.mkdir(CONFIG.screenshotDir, { recursive: true });
        const filename = `${name}-${Date.now()}.png`;
        const filepath = path.join(CONFIG.screenshotDir, filename);
        await page.screenshot({ path: filepath, fullPage: true });
        RESULTS.screenshots.push(filepath);
        console.log(`📸 Screenshot: ${filename}`);
        return filepath;
    } catch (error) {
        console.log(`⚠️ Screenshot failed: ${error.message}`);
    }
}

async function logTest(name, status, details = '') {
    const icon = status === 'passed' ? '✅' : '❌';
    console.log(`${icon} ${name}: ${status.toUpperCase()} ${details}`);
    
    RESULTS.tests.push({ name, status, details, timestamp: Date.now() });
    if (status === 'passed') {
        RESULTS.passed++;
    } else {
        RESULTS.failed++;
    }
}

async function login(page, credentials) {
    try {
        console.log('\n🔐 Logging in...');
        await page.goto(`${CONFIG.baseUrl}/wp-login.php`);
        await page.fill('#user_login', credentials.email);
        await page.fill('#user_pass', credentials.password);
        await page.click('#wp-submit');
        
        // Wait for redirect
        await page.waitForURL(url => {
            const urlString = typeof url === 'string' ? url : url.toString();
            return !urlString.includes('wp-login');
        }, { timeout: 10000 });
        
        const currentUrl = page.url();
        if (currentUrl.includes('dashboard') || currentUrl.includes('admin')) {
            await logTest('Login', 'passed', credentials.email);
            return true;
        } else {
            await logTest('Login', 'failed', 'Unexpected redirect');
            return false;
        }
    } catch (error) {
        await logTest('Login', 'failed', error.message);
        return false;
    }
}

async function testWordPressAdmin(page) {
    console.log('\n📊 Testing WordPress Admin Event Management...');
    
    try {
        // Navigate to events list
        await page.goto(`${CONFIG.baseUrl}/wp-admin/edit.php?post_type=tribe_events`);
        await page.waitForLoadState('domcontentloaded');
        
        await takeScreenshot(page, 'admin-events-list');
        
        // Count existing events
        const eventRows = await page.$$('tbody#the-list tr');
        console.log(`Found ${eventRows.length} existing events`);
        
        if (eventRows.length > 0) {
            await logTest('Admin Events List', 'passed', `${eventRows.length} events found`);
            
            // Test editing first event
            const editLink = await page.$('tbody#the-list tr:first-child .row-actions .edit a');
            if (editLink) {
                await editLink.click();
                await page.waitForLoadState('networkidle');
                
                await takeScreenshot(page, 'admin-edit-form');
                
                // Check if fields are populated
                const titleField = await page.$('#title');
                if (titleField) {
                    const currentTitle = await titleField.inputValue();
                    console.log(`Current title: ${currentTitle}`);
                    
                    // Update title
                    const newTitle = currentTitle + ' (Updated E2E)';
                    await titleField.fill(newTitle);
                    
                    // Check other fields
                    const fields = {
                        'Start Date': '#EventStartDate',
                        'End Date': '#EventEndDate',
                        'Cost': '#EventCost',
                        'Venue': '#venue-name, select[name="venue[VenueID]"]'
                    };
                    
                    for (const [name, selector] of Object.entries(fields)) {
                        const field = await page.$(selector);
                        if (field) {
                            const value = await field.inputValue().catch(() => '');
                            console.log(`  ${name}: ${value || 'N/A'}`);
                        }
                    }
                    
                    // Save changes
                    const updateButton = await page.$('#publish');
                    if (updateButton) {
                        await updateButton.click();
                        await page.waitForSelector('.notice-success, .updated', { timeout: 10000 });
                        
                        await takeScreenshot(page, 'admin-updated');
                        await logTest('Admin Event Edit', 'passed', 'Event updated successfully');
                    }
                } else {
                    await logTest('Admin Event Edit', 'failed', 'Title field not found');
                }
            }
        } else {
            await logTest('Admin Events List', 'failed', 'No events found');
        }
        
        // Test creating new event
        console.log('\n📝 Testing event creation in admin...');
        await page.goto(`${CONFIG.baseUrl}/wp-admin/post-new.php?post_type=tribe_events`);
        await page.waitForLoadState('domcontentloaded');
        
        await takeScreenshot(page, 'admin-new-event');
        
        // Fill new event form
        const titleField = await page.$('#title');
        if (titleField) {
            await titleField.fill(TEST_EVENT.title);
            
            // Fill description
            const contentFrame = await page.$('#content_ifr');
            if (contentFrame) {
                const frame = await contentFrame.contentFrame();
                await frame.fill('#tinymce', TEST_EVENT.description);
            } else {
                const contentArea = await page.$('#content');
                if (contentArea) {
                    await contentArea.fill(TEST_EVENT.description);
                }
            }
            
            // Set dates
            const startDate = await page.$('#EventStartDate');
            if (startDate) await startDate.fill(TEST_EVENT.startDate);
            
            const endDate = await page.$('#EventEndDate');
            if (endDate) await endDate.fill(TEST_EVENT.endDate);
            
            // Set cost
            const cost = await page.$('#EventCost');
            if (cost) await cost.fill(TEST_EVENT.cost);
            
            // Publish
            const publishButton = await page.$('#publish');
            if (publishButton) {
                await publishButton.click();
                await page.waitForSelector('.notice-success, .updated', { timeout: 10000 });
                
                await takeScreenshot(page, 'admin-created');
                await logTest('Admin Event Creation', 'passed', 'New event created');
            }
        } else {
            await logTest('Admin Event Creation', 'failed', 'Form fields not found');
        }
        
    } catch (error) {
        await logTest('WordPress Admin Test', 'failed', error.message);
        await takeScreenshot(page, 'admin-error');
    }
}

async function testTrainerPages(page) {
    console.log('\n🎯 Testing HVAC Trainer Event Pages...');
    
    try {
        // Navigate to trainer dashboard
        await page.goto(`${CONFIG.baseUrl}/trainer/dashboard/`);
        await page.waitForLoadState('domcontentloaded');
        
        await takeScreenshot(page, 'trainer-dashboard');
        
        const dashboardVisible = await page.locator('.hvac-dashboard-header, h1').first().isVisible();
        if (dashboardVisible) {
            await logTest('Trainer Dashboard', 'passed');
        } else {
            await logTest('Trainer Dashboard', 'failed', 'Dashboard not visible');
        }
        
        // Test events list
        await page.goto(`${CONFIG.baseUrl}/trainer/events/`);
        await page.waitForLoadState('domcontentloaded');
        
        await takeScreenshot(page, 'trainer-events-list');
        
        // Check page content
        const pageContent = await page.locator('body').textContent();
        
        if (pageContent.includes('404')) {
            await logTest('Trainer Events List', 'failed', '404 error');
        } else if (pageContent.includes('event') || pageContent.includes('Event')) {
            await logTest('Trainer Events List', 'passed');
            
            // Look for edit links
            const editLinks = await page.$$('a[href*="edit"]');
            if (editLinks.length > 0) {
                console.log(`Found ${editLinks.length} edit links`);
                
                // Click first edit link
                await editLinks[0].click();
                await page.waitForLoadState('networkidle');
                
                await takeScreenshot(page, 'trainer-edit-page');
                
                // Check if on edit page
                const editPageContent = await page.locator('body').textContent();
                if (editPageContent.includes('Edit') || editPageContent.includes('Update')) {
                    await logTest('Trainer Event Edit Page', 'passed');
                } else {
                    await logTest('Trainer Event Edit Page', 'failed', 'Edit form not found');
                }
            }
        } else {
            await logTest('Trainer Events List', 'failed', 'No event content');
        }
        
        // Test event creation page
        await page.goto(`${CONFIG.baseUrl}/trainer/events/create/`);
        await page.waitForLoadState('domcontentloaded');
        
        await takeScreenshot(page, 'trainer-create-page');
        
        const createPageContent = await page.locator('body').textContent();
        if (createPageContent.includes('404')) {
            await logTest('Trainer Create Event Page', 'failed', '404 error');
        } else {
            await logTest('Trainer Create Event Page', 'passed');
        }
        
    } catch (error) {
        await logTest('Trainer Pages Test', 'failed', error.message);
        await takeScreenshot(page, 'trainer-error');
    }
}

async function testCommunityPages(page) {
    console.log('\n🌐 Testing TEC Community Pages...');
    
    const communityUrls = [
        '/community/',
        '/community/add/',
        '/community/list/',
        '/events/community/',
        '/events/community/add/',
        '/events/community/list/'
    ];
    
    for (const url of communityUrls) {
        try {
            await page.goto(`${CONFIG.baseUrl}${url}`);
            await page.waitForLoadState('domcontentloaded');
            
            const content = await page.locator('body').textContent();
            
            if (content.includes('404') || content.includes('not found')) {
                await logTest(`Community ${url}`, 'failed', '404');
            } else if (content.includes('login') || content.includes('Login')) {
                await logTest(`Community ${url}`, 'failed', 'Login required');
            } else {
                await logTest(`Community ${url}`, 'passed');
            }
        } catch (error) {
            await logTest(`Community ${url}`, 'failed', error.message);
        }
    }
}

async function generateReport() {
    const duration = ((Date.now() - RESULTS.startTime) / 1000).toFixed(1);
    const successRate = RESULTS.tests.length > 0 
        ? ((RESULTS.passed / RESULTS.tests.length) * 100).toFixed(1)
        : 0;
    
    let report = `# HVAC Event Edit E2E Test Report\n\n`;
    report += `**Date:** ${new Date().toISOString()}\n`;
    report += `**Environment:** ${CONFIG.baseUrl}\n`;
    report += `**Duration:** ${duration} seconds\n\n`;
    
    report += `## Summary\n\n`;
    report += `- **Total Tests:** ${RESULTS.tests.length}\n`;
    report += `- **Passed:** ${RESULTS.passed} ✅\n`;
    report += `- **Failed:** ${RESULTS.failed} ❌\n`;
    report += `- **Success Rate:** ${successRate}%\n\n`;
    
    report += `## Test Results\n\n`;
    report += `| Test | Status | Details |\n`;
    report += `|------|--------|---------|\n`;
    
    for (const test of RESULTS.tests) {
        const icon = test.status === 'passed' ? '✅' : '❌';
        report += `| ${test.name} | ${icon} ${test.status} | ${test.details} |\n`;
    }
    
    report += `\n## Screenshots\n\n`;
    report += `${RESULTS.screenshots.length} screenshots captured:\n\n`;
    for (const screenshot of RESULTS.screenshots) {
        report += `- ${path.basename(screenshot)}\n`;
    }
    
    report += `\n## Assessment\n\n`;
    
    if (successRate >= 80) {
        report += `### ✅ SYSTEM READY\n\n`;
        report += `The event editing functionality is working well with ${successRate}% success rate.\n`;
    } else if (successRate >= 60) {
        report += `### ⚠️ PARTIAL FUNCTIONALITY\n\n`;
        report += `Some features are working but improvements needed. Success rate: ${successRate}%\n`;
    } else {
        report += `### ❌ NEEDS ATTENTION\n\n`;
        report += `Significant issues detected. Success rate: ${successRate}%\n`;
    }
    
    // Save report
    await fs.mkdir('reports', { recursive: true });
    const reportFile = `reports/e2e-test-report-${Date.now()}.md`;
    await fs.writeFile(reportFile, report);
    
    return { reportFile, successRate };
}

// Main test execution
async function runFullE2ETest() {
    console.log('🚀 HVAC EVENT EDIT FULL E2E TEST');
    console.log('═'.repeat(60));
    console.log(`Environment: ${CONFIG.baseUrl}`);
    console.log(`Time: ${new Date().toLocaleString()}`);
    console.log('═'.repeat(60));
    
    const browser = await chromium.launch({ 
        headless: true,
        timeout: CONFIG.timeout 
    });
    
    const context = await browser.newContext({
        viewport: { width: 1280, height: 720 }
    });
    
    const page = await context.newPage();
    
    try {
        // Test 1: Admin functionality (if password provided)
        if (CONFIG.credentials.admin.password) {
            console.log('\n👤 Testing with Admin Account...');
            if (await login(page, CONFIG.credentials.admin)) {
                await testWordPressAdmin(page);
            }
        } else {
            console.log('\n⚠️ Skipping admin tests (no password provided)');
        }
        
        // Test 2: Trainer functionality
        console.log('\n👤 Testing with Trainer Account...');
        if (await login(page, CONFIG.credentials.trainer)) {
            await testTrainerPages(page);
            await testCommunityPages(page);
        }
        
        // Test 3: Master trainer functionality
        console.log('\n👤 Testing with Master Trainer Account...');
        if (await login(page, CONFIG.credentials.master)) {
            await testTrainerPages(page);
        }
        
    } catch (error) {
        console.error('\n❌ Fatal error:', error.message);
        await takeScreenshot(page, 'fatal-error');
    } finally {
        await browser.close();
    }
    
    // Generate final report
    console.log('\n' + '═'.repeat(60));
    console.log('📊 GENERATING FINAL REPORT');
    console.log('═'.repeat(60));
    
    const { reportFile, successRate } = await generateReport();
    
    console.log(`\nTotal Tests: ${RESULTS.tests.length}`);
    console.log(`✅ Passed: ${RESULTS.passed}`);
    console.log(`❌ Failed: ${RESULTS.failed}`);
    console.log(`Success Rate: ${successRate}%`);
    
    console.log(`\n📄 Full report: ${reportFile}`);
    console.log(`📸 Screenshots: ${CONFIG.screenshotDir}/`);
    
    if (successRate >= 80) {
        console.log('\n🎉 EVENT EDITING FUNCTIONALITY VERIFIED!');
    } else if (successRate >= 60) {
        console.log('\n⚠️ PARTIAL SUCCESS - Some features need attention');
    } else {
        console.log('\n❌ SIGNIFICANT ISSUES - Review needed');
    }
    
    console.log('═'.repeat(60));
    
    process.exit(RESULTS.failed > 3 ? 1 : 0);
}

// Handle command line arguments
const args = process.argv.slice(2);
if (args.includes('--help')) {
    console.log(`
HVAC Event Edit E2E Test

Usage: node test-full-event-e2e.js [options]

Options:
  --admin-pass PASSWORD   Admin password for full testing
  --help                  Show this help message

Examples:
  node test-full-event-e2e.js
  node test-full-event-e2e.js --admin-pass MyPassword123
  ADMIN_PASSWORD=MyPassword123 node test-full-event-e2e.js
    `);
    process.exit(0);
}

// Check for admin password in arguments
const passIndex = args.indexOf('--admin-pass');
if (passIndex !== -1 && args[passIndex + 1]) {
    CONFIG.credentials.admin.password = args[passIndex + 1];
}

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