/**
 * Event Creation Page Object Model
 * 
 * Handles event creation functionality including:
 * - Standard HVAC event creation
 * - TEC (The Events Calendar) integration
 * - Form validation and error handling
 * - Event data population and submission
 * 
 * @package HVAC_Community_Events
 * @version 2.0.0
 * @created 2025-08-27
 * @author Agent-B-Event-Management
 */

const BasePage = require('../base/BasePage');
const { expect } = require('@playwright/test');

class EventCreation extends BasePage {
    constructor(page) {
        super(page);
        
        // Event creation form selectors
        this.selectors = {
            // Main form containers
            createEventForm: [
                '[data-testid="create-event-form"]',
                '.hvac-create-event-form',
                '.tribe-events-community-form',
                '.event-creation-form',
                'form#create-event'
            ],
            
            // Form fields - Standard HVAC
            fields: {
                title: [
                    '[data-testid="event-title"]',
                    'input[name="event_title"]',
                    'input[name="post_title"]',
                    '#event-title',
                    '.event-title-input'
                ],
                description: [
                    '[data-testid="event-description"]',
                    'textarea[name="event_description"]',
                    'textarea[name="post_content"]',
                    '#event-description',
                    '.event-description-textarea'
                ],
                startDate: [
                    '[data-testid="event-start-date"]',
                    'input[name="event_start_date"]',
                    'input[name="EventStartDate"]',
                    '#event-start-date',
                    '.event-start-date'
                ],
                endDate: [
                    '[data-testid="event-end-date"]',
                    'input[name="event_end_date"]',
                    'input[name="EventEndDate"]',
                    '#event-end-date',
                    '.event-end-date'
                ],
                startTime: [
                    '[data-testid="event-start-time"]',
                    'input[name="event_start_time"]',
                    'input[name="EventStartTime"]',
                    '#event-start-time',
                    '.event-start-time'
                ],
                endTime: [
                    '[data-testid="event-end-time"]',
                    'input[name="event_end_time"]',
                    'input[name="EventEndTime"]',
                    '#event-end-time',
                    '.event-end-time'
                ],
                venue: [
                    '[data-testid="event-venue"]',
                    'select[name="venue"]',
                    'select[name="event_venue"]',
                    '#event-venue',
                    '.venue-select'
                ],
                organizer: [
                    '[data-testid="event-organizer"]',
                    'select[name="organizer"]',
                    'select[name="event_organizer"]',
                    '#event-organizer',
                    '.organizer-select'
                ],
                category: [
                    '[data-testid="event-category"]',
                    'select[name="event_category"]',
                    'select[name="tax_input[tribe_events_cat][]"]',
                    '#event-category',
                    '.event-category-select'
                ],
                capacity: [
                    '[data-testid="event-capacity"]',
                    'input[name="event_capacity"]',
                    'input[name="_EventCapacity"]',
                    '#event-capacity',
                    '.event-capacity'
                ],
                cost: [
                    '[data-testid="event-cost"]',
                    'input[name="event_cost"]',
                    'input[name="_EventCost"]',
                    '#event-cost',
                    '.event-cost'
                ],
                website: [
                    '[data-testid="event-website"]',
                    'input[name="event_website"]',
                    'input[name="_EventURL"]',
                    '#event-website',
                    '.event-website'
                ]
            },
            
            // TEC specific fields
            tecFields: {
                allDayEvent: [
                    '[data-testid="all-day-event"]',
                    'input[name="_EventAllDay"]',
                    '#allDayCheckbox',
                    '.all-day-checkbox'
                ],
                timezone: [
                    '[data-testid="event-timezone"]',
                    'select[name="_EventTimezone"]',
                    '#event-timezone',
                    '.timezone-select'
                ],
                showMapLink: [
                    '[data-testid="show-map-link"]',
                    'input[name="_EventShowMapLink"]',
                    '#show-map-link',
                    '.show-map-link'
                ],
                showMap: [
                    '[data-testid="show-map"]',
                    'input[name="_EventShowMap"]',
                    '#show-map',
                    '.show-map'
                ]
            },
            
            // Action buttons
            buttons: {
                submit: [
                    '[data-testid="submit-event"]',
                    'input[type="submit"]',
                    'button[type="submit"]',
                    '#submit-event',
                    '.submit-event-btn',
                    '.tribe-community-event-submit'
                ],
                preview: [
                    '[data-testid="preview-event"]',
                    'button[name="preview"]',
                    '#preview-event',
                    '.preview-event-btn'
                ],
                saveDraft: [
                    '[data-testid="save-draft"]',
                    'button[name="save_draft"]',
                    '#save-draft',
                    '.save-draft-btn'
                ],
                cancel: [
                    '[data-testid="cancel-event"]',
                    'button[name="cancel"]',
                    '#cancel-event',
                    '.cancel-btn'
                ]
            },
            
            // Validation and error elements
            validation: {
                errors: [
                    '[data-testid="form-errors"]',
                    '.form-errors',
                    '.tribe-community-notice-error',
                    '.event-validation-errors',
                    '.error-message'
                ],
                success: [
                    '[data-testid="form-success"]',
                    '.form-success',
                    '.tribe-community-notice-success',
                    '.event-success-message',
                    '.success-message'
                ],
                fieldError: [
                    '.field-error',
                    '.input-error',
                    '.validation-error'
                ]
            },
            
            // Loading states
            loading: [
                '[data-testid="form-loading"]',
                '.form-loading',
                '.tribe-community-loading',
                '.loading-spinner'
            ]
        };
        
        this.urls = {
            createEvent: '/trainer/create-event/',
            tecCreateEvent: '/trainer/tec-create-event/',
            customCreateEvent: '/create-event/',
            communityCreate: '/events/community/add/'
        };
        
        // Test data templates
        this.testEventData = {
            basic: {
                title: 'Test HVAC Training Event',
                description: 'Comprehensive HVAC training covering heat pump installation and maintenance.',
                startDate: this.getFormattedDate(7), // 7 days from now
                endDate: this.getFormattedDate(7),
                startTime: '09:00',
                endTime: '17:00',
                capacity: '25',
                cost: '299.00'
            },
            advanced: {
                title: 'Advanced Heat Pump Diagnostics Workshop',
                description: 'Deep dive into advanced heat pump diagnostic techniques using measureQuick tools and protocols.',
                startDate: this.getFormattedDate(14),
                endDate: this.getFormattedDate(15),
                startTime: '08:30',
                endTime: '16:30',
                capacity: '15',
                cost: '499.00',
                website: 'https://upskill-staging.measurequick.com/advanced-diagnostics'
            },
            multiDay: {
                title: 'HVAC Certification Bootcamp',
                description: 'Intensive 3-day certification program covering all aspects of HVAC systems.',
                startDate: this.getFormattedDate(21),
                endDate: this.getFormattedDate(23),
                startTime: '09:00',
                endTime: '17:00',
                capacity: '20',
                cost: '799.00'
            }
        };
    }
    
    /**
     * Navigate to event creation page
     */
    async navigate(pageType = 'standard') {
        let url;
        switch (pageType) {
            case 'tec':
                url = this.urls.tecCreateEvent;
                break;
            case 'community':
                url = this.urls.communityCreate;
                break;
            case 'custom':
                url = this.urls.customCreateEvent;
                break;
            default:
                url = this.urls.createEvent;
        }
        
        await this.goto(url);
        await this.waitForFormLoad();
        console.log(`✅ Navigated to event creation page: ${pageType}`);
    }
    
    /**
     * Wait for event creation form to load completely
     */
    async waitForFormLoad() {
        // Wait for form container
        await this.waitForVisible(this.selectors.createEventForm, { timeout: 10000 });
        
        // Wait for essential fields
        await this.waitForVisible(this.selectors.fields.title, { timeout: 5000 });
        await this.waitForVisible(this.selectors.fields.description, { timeout: 5000 });
        
        // Wait for WordPress and any AJAX to complete
        await this.waitForWordPressReady();
        await this.waitForAjax();
        
        // Wait for loading indicators to disappear
        await this.waitForHidden(this.selectors.loading, { timeout: 3000 });
        
        console.log('✅ Event creation form loaded');
    }
    
    /**
     * Fill event creation form with provided data
     */
    async fillEventForm(eventData) {
        console.log('📝 Filling event form with data:', eventData.title);
        
        // Fill basic event information
        if (eventData.title) {
            await this.fill(this.selectors.fields.title, eventData.title);
        }
        
        if (eventData.description) {
            await this.fill(this.selectors.fields.description, eventData.description);
        }
        
        // Fill date and time information
        if (eventData.startDate) {
            await this.fill(this.selectors.fields.startDate, eventData.startDate);
        }
        
        if (eventData.endDate) {
            await this.fill(this.selectors.fields.endDate, eventData.endDate);
        }
        
        if (eventData.startTime) {
            await this.fill(this.selectors.fields.startTime, eventData.startTime);
        }
        
        if (eventData.endTime) {
            await this.fill(this.selectors.fields.endTime, eventData.endTime);
        }
        
        // Fill additional event details
        if (eventData.capacity) {
            await this.fill(this.selectors.fields.capacity, eventData.capacity);
        }
        
        if (eventData.cost) {
            await this.fill(this.selectors.fields.cost, eventData.cost);
        }
        
        if (eventData.website) {
            await this.fill(this.selectors.fields.website, eventData.website);
        }
        
        // Handle venue selection if provided
        if (eventData.venue) {
            await this.selectVenue(eventData.venue);
        }
        
        // Handle organizer selection if provided
        if (eventData.organizer) {
            await this.selectOrganizer(eventData.organizer);
        }
        
        // Handle category selection if provided
        if (eventData.category) {
            await this.selectCategory(eventData.category);
        }
        
        // Wait for form validation
        await this.waitForAjax();
        
        console.log('✅ Event form filled successfully');
    }
    
    /**
     * Submit event creation form
     */
    async submitEvent(options = {}) {
        const { 
            waitForRedirect = true, 
            expectedOutcome = 'success',
            timeout = 15000 
        } = options;
        
        console.log('🚀 Submitting event creation form');
        
        // Take screenshot before submission
        await this.takeScreenshot('before-event-submission');
        
        // Click submit button
        await this.click(this.selectors.buttons.submit, { timeout });
        
        if (waitForRedirect) {
            // Wait for form processing
            await this.waitForAjax();
            
            // Wait for either success or error message
            if (expectedOutcome === 'success') {
                await Promise.race([
                    this.waitForVisible(this.selectors.validation.success, { timeout }),
                    this.waitForUrlChange(timeout)
                ]);
                
                console.log('✅ Event submitted successfully');
            } else if (expectedOutcome === 'error') {
                await this.waitForVisible(this.selectors.validation.errors, { timeout });
                console.log('⚠️ Event submission resulted in expected error');
            }
        }
        
        // Take screenshot after submission
        await this.takeScreenshot('after-event-submission');
        
        return await this.getSubmissionResult();
    }
    
    /**
     * Get form submission result
     */
    async getSubmissionResult() {
        // Check for success messages
        if (await this.isVisible(this.selectors.validation.success)) {
            const successMessage = await this.getText(this.selectors.validation.success);
            return {
                success: true,
                message: successMessage,
                redirectUrl: await this.page.url()
            };
        }
        
        // Check for error messages
        if (await this.isVisible(this.selectors.validation.errors)) {
            const errorMessage = await this.getText(this.selectors.validation.errors);
            const fieldErrors = await this.getFieldErrors();
            return {
                success: false,
                message: errorMessage,
                fieldErrors,
                currentUrl: await this.page.url()
            };
        }
        
        // Check if URL changed (successful redirect)
        const currentUrl = await this.page.url();
        const isRedirected = !currentUrl.includes('create-event');
        
        return {
            success: isRedirected,
            redirected: isRedirected,
            currentUrl
        };
    }
    
    /**
     * Get field-specific validation errors
     */
    async getFieldErrors() {
        const fieldErrors = {};
        const errorElements = await this.page.locator(this.selectors.validation.fieldError.join(', ')).all();
        
        for (const errorElement of errorElements) {
            const fieldName = await errorElement.getAttribute('data-field') || 
                             await errorElement.getAttribute('for') ||
                             'unknown';
            const errorText = await errorElement.textContent();
            fieldErrors[fieldName] = errorText.trim();
        }
        
        return fieldErrors;
    }
    
    /**
     * Select venue from dropdown
     */
    async selectVenue(venueName) {
        if (await this.isVisible(this.selectors.fields.venue)) {
            // If venue is a dropdown
            await this.selectByText(this.selectors.fields.venue, venueName);
        } else {
            // If venue needs to be created or searched
            const venueInput = await this.getVisibleSelector([
                'input[name="venue_name"]',
                '#venue-search',
                '.venue-input'
            ]);
            
            if (venueInput) {
                await this.fill(venueInput, venueName);
                await this.waitForAjax();
            }
        }
        
        console.log(`📍 Selected venue: ${venueName}`);
    }
    
    /**
     * Select organizer from dropdown
     */
    async selectOrganizer(organizerName) {
        if (await this.isVisible(this.selectors.fields.organizer)) {
            await this.selectByText(this.selectors.fields.organizer, organizerName);
        } else {
            // Handle organizer creation if needed
            const organizerInput = await this.getVisibleSelector([
                'input[name="organizer_name"]',
                '#organizer-search',
                '.organizer-input'
            ]);
            
            if (organizerInput) {
                await this.fill(organizerInput, organizerName);
                await this.waitForAjax();
            }
        }
        
        console.log(`👤 Selected organizer: ${organizerName}`);
    }
    
    /**
     * Select event category
     */
    async selectCategory(categoryName) {
        if (await this.isVisible(this.selectors.fields.category)) {
            await this.selectByText(this.selectors.fields.category, categoryName);
            console.log(`🏷️ Selected category: ${categoryName}`);
        }
    }
    
    /**
     * Create event with test data
     */
    async createTestEvent(dataType = 'basic', options = {}) {
        const eventData = { ...this.testEventData[dataType], ...options.data };
        
        console.log(`🧪 Creating test event: ${dataType}`);
        
        await this.fillEventForm(eventData);
        const result = await this.submitEvent(options);
        
        return {
            ...result,
            eventData,
            testType: dataType
        };
    }
    
    /**
     * Validate form fields
     */
    async validateForm() {
        const validationResults = {
            requiredFields: [],
            validationErrors: [],
            fieldsPresent: {}
        };
        
        // Check required fields
        const requiredFields = ['title', 'description', 'startDate', 'startTime'];
        
        for (const fieldName of requiredFields) {
            const fieldSelectors = this.selectors.fields[fieldName];
            const isPresent = await this.isVisible(fieldSelectors);
            
            validationResults.fieldsPresent[fieldName] = isPresent;
            
            if (!isPresent) {
                validationResults.requiredFields.push(fieldName);
            }
        }
        
        // Check for existing validation errors
        if (await this.isVisible(this.selectors.validation.errors)) {
            const errors = await this.getText(this.selectors.validation.errors);
            validationResults.validationErrors.push(errors);
        }
        
        console.log('🔍 Form validation results:', validationResults);
        return validationResults;
    }
    
    /**
     * Test form validation by submitting empty form
     */
    async testValidation() {
        console.log('🧪 Testing form validation');
        
        // Clear any existing data
        await this.clearForm();
        
        // Attempt to submit empty form
        await this.click(this.selectors.buttons.submit);
        
        // Wait for validation errors
        await this.waitForVisible(this.selectors.validation.errors, { timeout: 5000 });
        
        return await this.getFieldErrors();
    }
    
    /**
     * Clear all form fields
     */
    async clearForm() {
        const fieldsToCheck = ['title', 'description', 'startDate', 'endDate', 'startTime', 'endTime', 'capacity', 'cost'];
        
        for (const fieldName of fieldsToCheck) {
            const fieldSelectors = this.selectors.fields[fieldName];
            if (await this.isVisible(fieldSelectors)) {
                await this.clear(fieldSelectors);
            }
        }
        
        console.log('🧹 Form cleared');
    }
    
    /**
     * Handle TEC-specific functionality
     */
    async configureTECOptions(options = {}) {
        if (options.allDay) {
            await this.check(this.selectors.tecFields.allDayEvent);
            console.log('☑️ Set as all-day event');
        }
        
        if (options.timezone) {
            await this.selectByText(this.selectors.tecFields.timezone, options.timezone);
            console.log(`🌍 Set timezone: ${options.timezone}`);
        }
        
        if (options.showMap !== undefined) {
            if (options.showMap) {
                await this.check(this.selectors.tecFields.showMap);
            } else {
                await this.uncheck(this.selectors.tecFields.showMap);
            }
            console.log(`🗺️ Show map: ${options.showMap}`);
        }
    }
    
    /**
     * Preview event before submission
     */
    async previewEvent() {
        if (await this.isVisible(this.selectors.buttons.preview)) {
            await this.click(this.selectors.buttons.preview);
            await this.waitForAjax();
            console.log('👁️ Event preview opened');
            return true;
        }
        return false;
    }
    
    /**
     * Save event as draft
     */
    async saveDraft() {
        if (await this.isVisible(this.selectors.buttons.saveDraft)) {
            await this.click(this.selectors.buttons.saveDraft);
            await this.waitForAjax();
            
            const result = await this.getSubmissionResult();
            console.log('📝 Event saved as draft');
            return result;
        }
        
        throw new Error('Save draft button not available');
    }
    
    /**
     * Get formatted date for form input
     */
    getFormattedDate(daysFromNow = 0) {
        const date = new Date();
        date.setDate(date.getDate() + daysFromNow);
        return date.toISOString().split('T')[0]; // YYYY-MM-DD format
    }
    
    /**
     * Take screenshot of form state
     */
    async screenshotForm(name = 'event-creation-form') {
        return await this.takeScreenshot(name, { fullPage: true });
    }
    
    /**
     * Verify form is accessible and ready for input
     */
    async verifyFormAccessibility() {
        const checks = {
            formVisible: await this.isVisible(this.selectors.createEventForm),
            titleFieldAccessible: await this.isVisible(this.selectors.fields.title),
            descriptionFieldAccessible: await this.isVisible(this.selectors.fields.description),
            submitButtonAccessible: await this.isVisible(this.selectors.buttons.submit),
            hasNoLoadingIndicators: !await this.isVisible(this.selectors.loading)
        };
        
        const isAccessible = Object.values(checks).every(check => check === true);
        
        console.log('♿ Form accessibility check:', { isAccessible, ...checks });
        return { isAccessible, checks };
    }
}

module.exports = EventCreation;