/**
 * Event Editing Page Object Model
 * 
 * Handles event editing and modification functionality including:
 * - Event detail editing and updates
 * - Status transitions (Draft → Pending → Published)
 * - Event modification workflows
 * - Version control and change tracking
 * 
 * @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 EventEditing extends BasePage {
    constructor(page) {
        super(page);
        
        // Event editing form selectors
        this.selectors = {
            // Main form containers
            editEventForm: [
                '[data-testid="edit-event-form"]',
                '.hvac-edit-event-form',
                '.tribe-events-community-form',
                '.event-edit-form',
                'form#edit-event'
            ],
            
            // Form fields (similar to creation but for editing context)
            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'
                ],
                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'
                ],
                status: [
                    '[data-testid="event-status"]',
                    'select[name="post_status"]',
                    'select[name="event_status"]',
                    '#event-status',
                    '.event-status-select'
                ]
            },
            
            // Event status indicators
            status: {
                draft: [
                    '[data-testid="status-draft"]',
                    '.status-draft',
                    '.event-status-draft',
                    'text=Draft'
                ],
                pending: [
                    '[data-testid="status-pending"]',
                    '.status-pending',
                    '.event-status-pending',
                    'text=Pending Review'
                ],
                published: [
                    '[data-testid="status-published"]',
                    '.status-published',
                    '.event-status-published',
                    'text=Published'
                ],
                cancelled: [
                    '[data-testid="status-cancelled"]',
                    '.status-cancelled',
                    '.event-status-cancelled',
                    'text=Cancelled'
                ]
            },
            
            // Action buttons
            buttons: {
                update: [
                    '[data-testid="update-event"]',
                    'input[value="Update Event"]',
                    'button[name="update"]',
                    '#update-event',
                    '.update-event-btn'
                ],
                publish: [
                    '[data-testid="publish-event"]',
                    'input[value="Publish"]',
                    'button[name="publish"]',
                    '#publish-event',
                    '.publish-event-btn'
                ],
                submitForReview: [
                    '[data-testid="submit-for-review"]',
                    'input[value="Submit for Review"]',
                    'button[name="submit_review"]',
                    '#submit-for-review',
                    '.submit-review-btn'
                ],
                saveDraft: [
                    '[data-testid="save-draft"]',
                    'input[value="Save Draft"]',
                    'button[name="save_draft"]',
                    '#save-draft',
                    '.save-draft-btn'
                ],
                delete: [
                    '[data-testid="delete-event"]',
                    'button[name="delete"]',
                    '#delete-event',
                    '.delete-event-btn',
                    'text=Delete Event'
                ],
                cancel: [
                    '[data-testid="cancel-event"]',
                    'button[name="cancel_event"]',
                    '#cancel-event',
                    '.cancel-event-btn',
                    'text=Cancel Event'
                ],
                preview: [
                    '[data-testid="preview-event"]',
                    'button[name="preview"]',
                    '#preview-event',
                    '.preview-event-btn'
                ]
            },
            
            // Event info display
            eventInfo: {
                id: [
                    '[data-testid="event-id"]',
                    '.event-id',
                    '#event-id'
                ],
                createdDate: [
                    '[data-testid="created-date"]',
                    '.created-date',
                    '.event-created'
                ],
                lastModified: [
                    '[data-testid="last-modified"]',
                    '.last-modified',
                    '.event-modified'
                ],
                author: [
                    '[data-testid="event-author"]',
                    '.event-author',
                    '.post-author'
                ]
            },
            
            // Attendee management
            attendees: {
                list: [
                    '[data-testid="attendees-list"]',
                    '.attendees-list',
                    '.event-attendees'
                ],
                count: [
                    '[data-testid="attendee-count"]',
                    '.attendee-count',
                    '.event-attendee-count'
                ],
                addAttendee: [
                    '[data-testid="add-attendee"]',
                    '.add-attendee-btn',
                    'button.add-attendee'
                ],
                removeAttendee: [
                    '[data-testid="remove-attendee"]',
                    '.remove-attendee-btn',
                    'button.remove-attendee'
                ]
            },
            
            // Validation and messages
            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'
                ],
                warnings: [
                    '[data-testid="form-warnings"]',
                    '.form-warnings',
                    '.event-warnings',
                    '.warning-message'
                ]
            },
            
            // Version control and history
            versions: {
                history: [
                    '[data-testid="version-history"]',
                    '.version-history',
                    '.event-revisions'
                ],
                compareLink: [
                    '[data-testid="compare-versions"]',
                    '.compare-versions',
                    'a.compare-revisions'
                ]
            }
        };
        
        this.urls = {
            editEvent: '/trainer/edit-event/',
            tecEditEvent: '/trainer/tec-edit-event/',
            customEditEvent: '/edit-event/',
            communityEdit: '/events/community/edit/'
        };
    }
    
    /**
     * Navigate to event editing page
     */
    async navigateToEdit(eventId, pageType = 'standard') {
        let url;
        switch (pageType) {
            case 'tec':
                url = `${this.urls.tecEditEvent}?event_id=${eventId}`;
                break;
            case 'community':
                url = `${this.urls.communityEdit}${eventId}/`;
                break;
            case 'custom':
                url = `${this.urls.customEditEvent}?id=${eventId}`;
                break;
            default:
                url = `${this.urls.editEvent}?event_id=${eventId}`;
        }
        
        await this.goto(url);
        await this.waitForEditFormLoad();
        console.log(`✅ Navigated to event editing page: ${pageType} (ID: ${eventId})`);
    }
    
    /**
     * Wait for edit form to load completely
     */
    async waitForEditFormLoad() {
        // Wait for form container
        await this.waitForVisible(this.selectors.editEventForm, { 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 AJAX to complete
        await this.waitForWordPressReady();
        await this.waitForAjax();
        
        console.log('✅ Event editing form loaded');
    }
    
    /**
     * Get current event information
     */
    async getEventInfo() {
        const eventInfo = {};
        
        // Get event ID if available
        if (await this.isVisible(this.selectors.eventInfo.id)) {
            eventInfo.id = await this.getText(this.selectors.eventInfo.id);
        }
        
        // Get current values from form fields
        eventInfo.title = await this.getInputValue(this.selectors.fields.title);
        eventInfo.description = await this.getInputValue(this.selectors.fields.description);
        eventInfo.startDate = await this.getInputValue(this.selectors.fields.startDate);
        eventInfo.endDate = await this.getInputValue(this.selectors.fields.endDate);
        eventInfo.startTime = await this.getInputValue(this.selectors.fields.startTime);
        eventInfo.endTime = await this.getInputValue(this.selectors.fields.endTime);
        eventInfo.capacity = await this.getInputValue(this.selectors.fields.capacity);
        eventInfo.cost = await this.getInputValue(this.selectors.fields.cost);
        
        // Get status
        eventInfo.status = await this.getCurrentStatus();
        
        // Get created/modified dates if available
        if (await this.isVisible(this.selectors.eventInfo.createdDate)) {
            eventInfo.createdDate = await this.getText(this.selectors.eventInfo.createdDate);
        }
        
        if (await this.isVisible(this.selectors.eventInfo.lastModified)) {
            eventInfo.lastModified = await this.getText(this.selectors.eventInfo.lastModified);
        }
        
        console.log('📋 Current event info:', eventInfo);
        return eventInfo;
    }
    
    /**
     * Update specific event fields
     */
    async updateEventFields(updates) {
        console.log('✏️ Updating event fields:', Object.keys(updates));
        
        for (const [fieldName, newValue] of Object.entries(updates)) {
            const fieldSelectors = this.selectors.fields[fieldName];
            
            if (fieldSelectors && await this.isVisible(fieldSelectors)) {
                await this.clear(fieldSelectors);
                await this.fill(fieldSelectors, newValue);
                console.log(`   ✓ Updated ${fieldName}: ${newValue}`);
            } else {
                console.warn(`   ⚠️ Field '${fieldName}' not found or not visible`);
            }
        }
        
        // Wait for any auto-save or validation
        await this.waitForAjax();
    }
    
    /**
     * Get current event status
     */
    async getCurrentStatus() {
        // Check for status indicators
        const statusChecks = [
            { status: 'published', selectors: this.selectors.status.published },
            { status: 'pending', selectors: this.selectors.status.pending },
            { status: 'draft', selectors: this.selectors.status.draft },
            { status: 'cancelled', selectors: this.selectors.status.cancelled }
        ];
        
        for (const { status, selectors } of statusChecks) {
            if (await this.isVisible(selectors)) {
                return status;
            }
        }
        
        // Check status dropdown if available
        if (await this.isVisible(this.selectors.fields.status)) {
            return await this.getSelectedValue(this.selectors.fields.status);
        }
        
        return 'unknown';
    }
    
    /**
     * Change event status
     */
    async changeStatus(newStatus) {
        console.log(`🔄 Changing event status to: ${newStatus}`);
        
        // If status dropdown is available
        if (await this.isVisible(this.selectors.fields.status)) {
            await this.selectByValue(this.selectors.fields.status, newStatus);
            console.log(`✅ Status changed via dropdown: ${newStatus}`);
            return;
        }
        
        // Use status-specific buttons
        const statusButtonMap = {
            'draft': this.selectors.buttons.saveDraft,
            'pending': this.selectors.buttons.submitForReview,
            'published': this.selectors.buttons.publish
        };
        
        const buttonSelectors = statusButtonMap[newStatus];
        if (buttonSelectors && await this.isVisible(buttonSelectors)) {
            await this.click(buttonSelectors);
            console.log(`✅ Status changed via button: ${newStatus}`);
        } else {
            throw new Error(`Cannot change status to ${newStatus} - no available method found`);
        }
    }
    
    /**
     * Update event and save changes
     */
    async updateEvent(options = {}) {
        const { 
            waitForRedirect = true, 
            expectedOutcome = 'success',
            timeout = 15000 
        } = options;
        
        console.log('💾 Updating event');
        
        // Take screenshot before update
        await this.takeScreenshot('before-event-update');
        
        // Click update button (priority order)
        const updateButtons = [
            this.selectors.buttons.update,
            this.selectors.buttons.saveDraft,
            this.selectors.buttons.publish
        ];
        
        let updateClicked = false;
        for (const buttonSelectors of updateButtons) {
            if (await this.isVisible(buttonSelectors)) {
                await this.click(buttonSelectors, { timeout });
                updateClicked = true;
                break;
            }
        }
        
        if (!updateClicked) {
            throw new Error('No update button found on event edit form');
        }
        
        if (waitForRedirect) {
            // Wait for form processing
            await this.waitForAjax();
            
            // Wait for success/error message or URL change
            if (expectedOutcome === 'success') {
                await Promise.race([
                    this.waitForVisible(this.selectors.validation.success, { timeout }),
                    this.waitForUrlChange(timeout)
                ]);
                console.log('✅ Event updated successfully');
            } else if (expectedOutcome === 'error') {
                await this.waitForVisible(this.selectors.validation.errors, { timeout });
                console.log('⚠️ Event update resulted in expected error');
            }
        }
        
        // Take screenshot after update
        await this.takeScreenshot('after-event-update');
        
        return await this.getUpdateResult();
    }
    
    /**
     * Get update result with status and messages
     */
    async getUpdateResult() {
        // 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,
                currentUrl: await this.page.url(),
                newStatus: await this.getCurrentStatus()
            };
        }
        
        // Check for error messages
        if (await this.isVisible(this.selectors.validation.errors)) {
            const errorMessage = await this.getText(this.selectors.validation.errors);
            return {
                success: false,
                message: errorMessage,
                currentUrl: await this.page.url(),
                currentStatus: await this.getCurrentStatus()
            };
        }
        
        // Check for warnings
        if (await this.isVisible(this.selectors.validation.warnings)) {
            const warningMessage = await this.getText(this.selectors.validation.warnings);
            return {
                success: true,
                warning: true,
                message: warningMessage,
                currentUrl: await this.page.url(),
                newStatus: await this.getCurrentStatus()
            };
        }
        
        // Default success if no explicit messages
        return {
            success: true,
            message: 'Event updated (no confirmation message displayed)',
            currentUrl: await this.page.url(),
            newStatus: await this.getCurrentStatus()
        };
    }
    
    /**
     * Delete event (with confirmation handling)
     */
    async deleteEvent(confirmDelete = true) {
        console.log('🗑️ Attempting to delete event');
        
        if (!await this.isVisible(this.selectors.buttons.delete)) {
            throw new Error('Delete button not available');
        }
        
        await this.click(this.selectors.buttons.delete);
        
        // Handle confirmation dialog
        if (confirmDelete) {
            // Wait for browser confirmation dialog
            this.page.on('dialog', async dialog => {
                console.log(`🔔 Confirmation dialog: ${dialog.message()}`);
                await dialog.accept();
            });
        }
        
        await this.waitForAjax();
        const currentUrl = await this.page.url();
        
        const result = {
            deleted: !currentUrl.includes('edit-event'),
            currentUrl
        };
        
        console.log(result.deleted ? '✅ Event deleted' : '⚠️ Event deletion may have failed');
        return result;
    }
    
    /**
     * Cancel event (change status to cancelled)
     */
    async cancelEvent(reason = '') {
        console.log('❌ Cancelling event');
        
        // If there's a specific cancel button
        if (await this.isVisible(this.selectors.buttons.cancel)) {
            await this.click(this.selectors.buttons.cancel);
            
            // Handle reason input if available
            const reasonInput = await this.getVisibleSelector([
                '[data-testid="cancel-reason"]',
                'textarea[name="cancel_reason"]',
                '#cancel-reason'
            ]);
            
            if (reasonInput && reason) {
                await this.fill(reasonInput, reason);
            }
            
            await this.waitForAjax();
        } else {
            // Use status change
            await this.changeStatus('cancelled');
        }
        
        return await this.updateEvent();
    }
    
    /**
     * Get attendee information
     */
    async getAttendeeInfo() {
        const attendeeInfo = {
            count: 0,
            attendees: [],
            hasAttendeeManagement: false
        };
        
        // Check if attendee management is available
        if (await this.isVisible(this.selectors.attendees.list)) {
            attendeeInfo.hasAttendeeManagement = true;
            
            // Get attendee count
            if (await this.isVisible(this.selectors.attendees.count)) {
                const countText = await this.getText(this.selectors.attendees.count);
                attendeeInfo.count = parseInt(countText.match(/\d+/)?.[0] || '0', 10);
            }
            
            // Get attendee list
            const attendeeElements = await this.page.locator(`${this.selectors.attendees.list.join(', ')} .attendee`).all();
            for (const attendeeElement of attendeeElements) {
                const attendeeText = await attendeeElement.textContent();
                attendeeInfo.attendees.push(attendeeText.trim());
            }
        }
        
        console.log('👥 Attendee info:', attendeeInfo);
        return attendeeInfo;
    }
    
    /**
     * Test event status transitions
     */
    async testStatusTransitions() {
        console.log('🔄 Testing status transitions');
        
        const transitions = [];
        const currentStatus = await this.getCurrentStatus();
        transitions.push({ from: null, to: currentStatus, timestamp: Date.now() });
        
        // Test possible transitions based on current status
        const transitionMap = {
            'draft': ['pending', 'published'],
            'pending': ['published', 'draft'],
            'published': ['draft'],
            'cancelled': ['draft']
        };
        
        const possibleTransitions = transitionMap[currentStatus] || [];
        
        for (const targetStatus of possibleTransitions) {
            try {
                await this.changeStatus(targetStatus);
                await this.updateEvent({ waitForRedirect: false });
                
                const newStatus = await this.getCurrentStatus();
                transitions.push({
                    from: currentStatus,
                    to: newStatus,
                    expected: targetStatus,
                    successful: newStatus === targetStatus,
                    timestamp: Date.now()
                });
                
                console.log(`   ${currentStatus} → ${newStatus} ${newStatus === targetStatus ? '✅' : '❌'}`);
            } catch (error) {
                transitions.push({
                    from: currentStatus,
                    to: targetStatus,
                    expected: targetStatus,
                    successful: false,
                    error: error.message,
                    timestamp: Date.now()
                });
                
                console.log(`   ${currentStatus} → ${targetStatus} ❌ (${error.message})`);
            }
        }
        
        return transitions;
    }
    
    /**
     * Compare current event data with expected data
     */
    async compareEventData(expectedData) {
        const currentData = await this.getEventInfo();
        const comparison = {
            matches: {},
            differences: {},
            missing: {}
        };
        
        for (const [field, expectedValue] of Object.entries(expectedData)) {
            if (currentData.hasOwnProperty(field)) {
                const matches = currentData[field] === expectedValue;
                if (matches) {
                    comparison.matches[field] = expectedValue;
                } else {
                    comparison.differences[field] = {
                        expected: expectedValue,
                        actual: currentData[field]
                    };
                }
            } else {
                comparison.missing[field] = expectedValue;
            }
        }
        
        const overallMatch = Object.keys(comparison.differences).length === 0 && 
                           Object.keys(comparison.missing).length === 0;
        
        console.log('🔍 Event data comparison:', { overallMatch, ...comparison });
        return { overallMatch, ...comparison };
    }
    
    /**
     * Preview event
     */
    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;
        }
        console.log('⚠️ Preview not available');
        return false;
    }
    
    /**
     * Get version history if available
     */
    async getVersionHistory() {
        if (!await this.isVisible(this.selectors.versions.history)) {
            return { hasVersioning: false };
        }
        
        const versions = [];
        const versionElements = await this.page.locator(`${this.selectors.versions.history.join(', ')} .revision`).all();
        
        for (const versionElement of versionElements) {
            const versionText = await versionElement.textContent();
            versions.push(versionText.trim());
        }
        
        return {
            hasVersioning: true,
            versions,
            count: versions.length
        };
    }
    
    /**
     * Take screenshot of edit form
     */
    async screenshotEditForm(name = 'event-edit-form') {
        return await this.takeScreenshot(name, { fullPage: true });
    }
    
    /**
     * Verify edit form access and functionality
     */
    async verifyEditAccess() {
        const checks = {
            formVisible: await this.isVisible(this.selectors.editEventForm),
            fieldsEditable: await this.areFieldsEditable(),
            updateButtonAvailable: await this.isVisible(this.selectors.buttons.update),
            canChangeStatus: await this.canChangeStatus(),
            eventInfoDisplayed: await this.isVisible(this.selectors.eventInfo.id)
        };
        
        const hasEditAccess = Object.values(checks).every(check => check === true);
        
        console.log('🔐 Edit access verification:', { hasEditAccess, ...checks });
        return { hasEditAccess, checks };
    }
    
    /**
     * Check if form fields are editable
     */
    async areFieldsEditable() {
        const fieldsToCheck = ['title', 'description', 'startDate', 'capacity'];
        
        for (const fieldName of fieldsToCheck) {
            const fieldSelectors = this.selectors.fields[fieldName];
            if (await this.isVisible(fieldSelectors)) {
                const isDisabled = await this.page.locator(fieldSelectors.join(', ')).first().isDisabled();
                if (isDisabled) return false;
            }
        }
        
        return true;
    }
    
    /**
     * Check if user can change event status
     */
    async canChangeStatus() {
        return await this.isVisible(this.selectors.fields.status) ||
               await this.isVisible(this.selectors.buttons.publish) ||
               await this.isVisible(this.selectors.buttons.submitForReview);
    }
}

module.exports = EventEditing;