#!/usr/bin/env node

/**
 * Complete Event Edit Workflow Test
 * Tests the FULL edit cycle: access, populate, edit, save, verify
 */

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

const CONFIG = {
    baseUrl: 'https://upskill-staging.measurequick.com',
    credentials: {
        email: 'test_trainer@example.com',
        password: 'TestTrainer123!'
    }
};

// Track field values before and after
const FIELD_VALUES = {
    before: {},
    after: {},
    changes: {}
};

async function screenshot(page, name) {
    await fs.mkdir('screenshots/edit-workflow', { recursive: true });
    const path = `screenshots/edit-workflow/${name}-${Date.now()}.png`;
    await page.screenshot({ path, fullPage: true });
    console.log(`📸 Screenshot: ${name}`);
    return path;
}

async function createTestEvent(page) {
    console.log('\n📝 Creating test event via WordPress Admin...');
    
    await page.goto(`${CONFIG.baseUrl}/wp-admin/post-new.php?post_type=tribe_events`);
    await page.waitForLoadState('domcontentloaded');
    
    // Fill basic event data
    const eventData = {
        title: `Test Event for Edit Verification ${Date.now()}`,
        description: 'This event will be edited to verify all fields save correctly.',
        startDate: '2025-09-15',
        endDate: '2025-09-16',
        startTime: '09:00',
        endTime: '17:00',
        cost: '299',
        venue: 'Test Venue',
        organizer: 'Test Organizer',
        website: 'https://example.com/test'
    };
    
    // Title
    const titleField = await page.$('#title');
    if (titleField) {
        await titleField.fill(eventData.title);
        console.log('✅ Title set');
    }
    
    // Description (try different methods)
    const contentFrame = await page.$('#content_ifr');
    if (contentFrame) {
        const frame = await contentFrame.contentFrame();
        await frame.fill('#tinymce', eventData.description);
        console.log('✅ Description set (TinyMCE)');
    } else {
        const contentArea = await page.$('#content');
        if (contentArea) {
            await contentArea.fill(eventData.description);
            console.log('✅ Description set (textarea)');
        }
    }
    
    // Dates
    const startDate = await page.$('#EventStartDate');
    if (startDate) {
        await startDate.fill(eventData.startDate);
        console.log('✅ Start date set');
    }
    
    const endDate = await page.$('#EventEndDate');
    if (endDate) {
        await endDate.fill(eventData.endDate);
        console.log('✅ End date set');
    }
    
    // Times
    const startTime = await page.$('#EventStartTime');
    if (startTime) {
        await startTime.fill(eventData.startTime);
        console.log('✅ Start time set');
    }
    
    const endTime = await page.$('#EventEndTime');
    if (endTime) {
        await endTime.fill(eventData.endTime);
        console.log('✅ End time set');
    }
    
    // Cost
    const costField = await page.$('#EventCost');
    if (costField) {
        await costField.fill(eventData.cost);
        console.log('✅ Cost set');
    }
    
    // Website
    const urlField = await page.$('#EventURL');
    if (urlField) {
        await urlField.fill(eventData.website);
        console.log('✅ Website set');
    }
    
    // Save as draft first
    const saveDraft = await page.$('#save-post');
    if (saveDraft) {
        await saveDraft.click();
        await page.waitForSelector('.notice-success, #message', { timeout: 10000 });
        console.log('✅ Event saved as draft');
    }
    
    // Now publish
    const publishBtn = await page.$('#publish');
    if (publishBtn) {
        await publishBtn.click();
        await page.waitForSelector('.notice-success, #message', { timeout: 10000 });
        console.log('✅ Event published');
    }
    
    // Get the event ID from URL
    const url = page.url();
    const match = url.match(/post=(\d+)/);
    const eventId = match ? match[1] : null;
    
    console.log(`✅ Event created with ID: ${eventId}`);
    return eventId;
}

async function accessEventFromDashboard(page) {
    console.log('\n🔍 Accessing event from dashboard...');
    
    // Go to events list
    await page.goto(`${CONFIG.baseUrl}/trainer/events/`);
    await page.waitForLoadState('domcontentloaded');
    
    await screenshot(page, 'events-list');
    
    // Try multiple selectors for edit links
    const editSelectors = [
        'a[href*="action=edit"]',
        'a[href*="/edit/"]',
        '.edit-link',
        'a:has-text("Edit")',
        'button:has-text("Edit")'
    ];
    
    let editLink = null;
    for (const selector of editSelectors) {
        editLink = await page.$(selector);
        if (editLink) {
            console.log(`✅ Found edit link with selector: ${selector}`);
            break;
        }
    }
    
    if (!editLink) {
        // If no edit links, go directly to admin
        console.log('⚠️ No edit links found on trainer page, using admin...');
        await page.goto(`${CONFIG.baseUrl}/wp-admin/edit.php?post_type=tribe_events`);
        
        const firstEdit = await page.$('#the-list .row-actions .edit a');
        if (firstEdit) {
            await firstEdit.click();
            await page.waitForLoadState('networkidle');
            return true;
        }
        return false;
    }
    
    await editLink.click();
    await page.waitForLoadState('networkidle');
    return true;
}

async function captureAllFields(page) {
    console.log('\n📊 Capturing all field values...');
    
    const fields = {};
    
    // Define all TEC fields to check
    const fieldSelectors = {
        'title': '#title, input[name="post_title"]',
        'content': '#content, #tinymce',
        'startDate': '#EventStartDate, input[name="EventStartDate"]',
        'endDate': '#EventEndDate, input[name="EventEndDate"]',
        'startTime': '#EventStartTime, input[name="EventStartTime"]',
        'endTime': '#EventEndTime, input[name="EventEndTime"]',
        'allDay': '#EventAllDay, input[name="EventAllDay"]',
        'timezone': '#event-timezone, select[name="EventTimezone"]',
        'cost': '#EventCost, input[name="EventCost"]',
        'currency': '#EventCurrencySymbol, input[name="EventCurrencySymbol"]',
        'website': '#EventURL, input[name="EventURL"]',
        'venue': '#venue-name, select[name="venue[VenueID]"], input[name="venue[Venue]"]',
        'address': '#VenueAddress, input[name="venue[Address]"]',
        'city': '#VenueCity, input[name="venue[City]"]',
        'state': '#VenueState, input[name="venue[State]"]',
        'zip': '#VenueZip, input[name="venue[Zip]"]',
        'country': '#VenueCountry, select[name="venue[Country]"]',
        'phone': '#VenuePhone, input[name="venue[Phone]"]',
        'organizer': '#organizer-name, select[name="organizer[OrganizerID]"], input[name="organizer[Organizer]"]',
        'organizerEmail': '#OrganizerEmail, input[name="organizer[Email]"]',
        'organizerPhone': '#OrganizerPhone, input[name="organizer[Phone]"]',
        'organizerWebsite': '#OrganizerWebsite, input[name="organizer[Website]"]'
    };
    
    for (const [fieldName, selector] of Object.entries(fieldSelectors)) {
        try {
            const element = await page.$(selector);
            if (element) {
                // Try different methods to get value
                let value = await element.inputValue().catch(() => null);
                
                if (!value) {
                    value = await element.textContent().catch(() => null);
                }
                
                if (!value) {
                    value = await element.evaluate(el => {
                        if (el.tagName === 'SELECT') {
                            return el.options[el.selectedIndex]?.text || '';
                        }
                        return el.value || el.innerText || '';
                    });
                }
                
                if (value) {
                    fields[fieldName] = value;
                    console.log(`  ${fieldName}: ${value.substring(0, 50)}${value.length > 50 ? '...' : ''}`);
                }
            } else {
                console.log(`  ${fieldName}: [field not found]`);
            }
        } catch (error) {
            console.log(`  ${fieldName}: [error reading]`);
        }
    }
    
    // Check for TinyMCE content
    const contentFrame = await page.$('#content_ifr');
    if (contentFrame && !fields.content) {
        try {
            const frame = await contentFrame.contentFrame();
            const content = await frame.$eval('#tinymce', el => el.textContent);
            if (content) {
                fields.content = content;
                console.log(`  content (TinyMCE): ${content.substring(0, 50)}...`);
            }
        } catch (error) {
            console.log('  content: [TinyMCE error]');
        }
    }
    
    await screenshot(page, 'fields-captured');
    
    return fields;
}

async function editFields(page, originalValues) {
    console.log('\n✏️ Editing fields...');
    
    const changes = {};
    
    // Edit title
    const titleField = await page.$('#title');
    if (titleField && originalValues.title) {
        const newTitle = originalValues.title + ' (EDITED)';
        await titleField.fill(newTitle);
        changes.title = newTitle;
        console.log('✅ Title edited');
    }
    
    // Edit cost
    const costField = await page.$('#EventCost');
    if (costField && originalValues.cost) {
        const newCost = '399';
        await costField.fill(newCost);
        changes.cost = newCost;
        console.log('✅ Cost edited');
    }
    
    // Edit start date
    const startDateField = await page.$('#EventStartDate');
    if (startDateField && originalValues.startDate) {
        const newDate = '2025-10-01';
        await startDateField.fill(newDate);
        changes.startDate = newDate;
        console.log('✅ Start date edited');
    }
    
    // Edit website
    const urlField = await page.$('#EventURL');
    if (urlField) {
        const newUrl = 'https://edited.example.com/event';
        await urlField.fill(newUrl);
        changes.website = newUrl;
        console.log('✅ Website edited');
    }
    
    // Edit description
    const contentFrame = await page.$('#content_ifr');
    if (contentFrame) {
        try {
            const frame = await contentFrame.contentFrame();
            const tinymce = await frame.$('#tinymce');
            if (tinymce) {
                await tinymce.fill('EDITED: This event description has been updated.');
                changes.content = 'EDITED: This event description has been updated.';
                console.log('✅ Description edited');
            }
        } catch (error) {
            // Try textarea
            const contentArea = await page.$('#content');
            if (contentArea) {
                await contentArea.fill('EDITED: This event description has been updated.');
                changes.content = 'EDITED: This event description has been updated.';
                console.log('✅ Description edited (textarea)');
            }
        }
    }
    
    await screenshot(page, 'fields-edited');
    
    return changes;
}

async function saveAndVerify(page, expectedChanges) {
    console.log('\n💾 Saving changes...');
    
    // Find and click update/publish button
    const updateBtn = await page.$('#publish, #save-post, input[name="save"]');
    if (updateBtn) {
        await updateBtn.click();
        
        // Wait for success message
        await page.waitForSelector('.notice-success, #message, .updated', { timeout: 10000 });
        console.log('✅ Changes saved');
        
        await screenshot(page, 'saved-success');
    } else {
        console.log('❌ Save button not found');
        return false;
    }
    
    // Reload the page to verify persistence
    console.log('\n🔄 Reloading to verify persistence...');
    await page.reload();
    await page.waitForLoadState('networkidle');
    
    // Capture fields again
    const afterValues = await captureAllFields(page);
    
    // Verify changes persisted
    console.log('\n✅ Verifying changes persisted...');
    let allChangesPersisted = true;
    
    for (const [field, expectedValue] of Object.entries(expectedChanges)) {
        const actualValue = afterValues[field];
        
        if (actualValue && actualValue.includes(expectedValue)) {
            console.log(`  ✅ ${field}: Change persisted`);
        } else {
            console.log(`  ❌ ${field}: Expected "${expectedValue}", got "${actualValue}"`);
            allChangesPersisted = false;
        }
    }
    
    return allChangesPersisted;
}

async function runCompleteEditWorkflow() {
    console.log('🎯 COMPLETE EVENT EDIT WORKFLOW TEST');
    console.log('=' .repeat(60));
    console.log('This test will:');
    console.log('1. Create/access an event');
    console.log('2. Verify ALL fields populate');
    console.log('3. Edit multiple fields');
    console.log('4. Save and verify persistence');
    console.log('=' .repeat(60));
    
    const browser = await chromium.launch({ headless: true });
    const page = await browser.newPage();
    
    const results = {
        steps: [],
        fieldsBefore: 0,
        fieldsAfter: 0,
        changesPersisted: 0,
        totalChanges: 0
    };
    
    try {
        // Login
        console.log('\n🔐 Logging in...');
        await page.goto(`${CONFIG.baseUrl}/wp-login.php`);
        await page.fill('#user_login', CONFIG.credentials.email);
        await page.fill('#user_pass', CONFIG.credentials.password);
        await page.click('#wp-submit');
        await page.waitForURL(/dashboard|admin/, { timeout: 10000 });
        console.log('✅ Logged in successfully');
        results.steps.push({ step: 'Login', status: 'passed' });
        
        // Create a test event first
        const eventId = await createTestEvent(page);
        if (eventId) {
            results.steps.push({ step: 'Create Test Event', status: 'passed', eventId });
        }
        
        // Access event for editing
        const accessed = await accessEventFromDashboard(page);
        if (accessed) {
            console.log('✅ Accessed event edit form');
            results.steps.push({ step: 'Access Edit Form', status: 'passed' });
        } else {
            console.log('❌ Could not access edit form');
            results.steps.push({ step: 'Access Edit Form', status: 'failed' });
        }
        
        // Capture all field values
        FIELD_VALUES.before = await captureAllFields(page);
        results.fieldsBefore = Object.keys(FIELD_VALUES.before).length;
        console.log(`\n📊 Fields populated: ${results.fieldsBefore}`);
        results.steps.push({ 
            step: 'Capture Fields', 
            status: results.fieldsBefore > 0 ? 'passed' : 'failed',
            fieldsFound: results.fieldsBefore 
        });
        
        // Edit fields
        FIELD_VALUES.changes = await editFields(page, FIELD_VALUES.before);
        results.totalChanges = Object.keys(FIELD_VALUES.changes).length;
        console.log(`\n✏️ Fields edited: ${results.totalChanges}`);
        results.steps.push({ 
            step: 'Edit Fields', 
            status: results.totalChanges > 0 ? 'passed' : 'failed',
            changesAttempted: results.totalChanges 
        });
        
        // Save and verify
        const changesPersisted = await saveAndVerify(page, FIELD_VALUES.changes);
        results.changesPersisted = changesPersisted ? results.totalChanges : 0;
        results.steps.push({ 
            step: 'Save and Verify', 
            status: changesPersisted ? 'passed' : 'failed',
            changesPersisted: results.changesPersisted 
        });
        
    } catch (error) {
        console.error('❌ Error:', error.message);
        results.steps.push({ step: 'Error', status: 'failed', error: error.message });
    } finally {
        await browser.close();
    }
    
    // Generate final report
    console.log('\n' + '=' .repeat(60));
    console.log('📊 FINAL RESULTS');
    console.log('=' .repeat(60));
    
    const passed = results.steps.filter(s => s.status === 'passed').length;
    const failed = results.steps.filter(s => s.status === 'failed').length;
    const successRate = ((passed / results.steps.length) * 100).toFixed(0);
    
    console.log(`\nWorkflow Steps: ${results.steps.length}`);
    console.log(`✅ Passed: ${passed}`);
    console.log(`❌ Failed: ${failed}`);
    console.log(`Success Rate: ${successRate}%`);
    
    console.log('\n📋 Details:');
    console.log(`- Fields found before edit: ${results.fieldsBefore}`);
    console.log(`- Fields edited: ${results.totalChanges}`);
    console.log(`- Changes persisted: ${results.changesPersisted}/${results.totalChanges}`);
    
    console.log('\n🔍 Step Results:');
    results.steps.forEach(step => {
        const icon = step.status === 'passed' ? '✅' : '❌';
        console.log(`${icon} ${step.step}: ${step.status.toUpperCase()}`);
        if (step.fieldsFound) console.log(`   Fields: ${step.fieldsFound}`);
        if (step.changesAttempted) console.log(`   Changes: ${step.changesAttempted}`);
        if (step.error) console.log(`   Error: ${step.error}`);
    });
    
    console.log('\n🎯 ASSESSMENT:');
    if (successRate === '100' && results.changesPersisted === results.totalChanges) {
        console.log('✅ COMPLETE EDIT WORKFLOW VERIFIED!');
        console.log('All fields populate correctly and changes persist.');
    } else if (successRate >= '60') {
        console.log('⚠️ PARTIAL SUCCESS');
        console.log('Some aspects work but issues detected.');
    } else {
        console.log('❌ EDIT WORKFLOW NEEDS ATTENTION');
        console.log('Significant issues with field population or persistence.');
    }
    
    console.log('\n📁 Screenshots: screenshots/edit-workflow/');
    console.log('=' .repeat(60));
}

// Run the test
console.log('Starting complete edit workflow test...\n');
runCompleteEditWorkflow().catch(error => {
    console.error('Fatal error:', error);
    process.exit(1);
});