/**
 * Event Management Dashboard Page Object Model
 * 
 * Handles event management dashboard functionality including:
 * - Event listing and filtering
 * - Bulk operations on events
 * - Event status management
 * - Attendee management dashboard
 * - Event analytics and reporting
 * 
 * @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 EventManagement extends BasePage {
    constructor(page) {
        super(page);
        
        // Event management dashboard selectors
        this.selectors = {
            // Main dashboard containers
            managementDashboard: [
                '[data-testid="event-management-dashboard"]',
                '.hvac-event-management',
                '.event-management-dashboard',
                '.manage-events-dashboard'
            ],
            
            // Event listing
            eventsList: [
                '[data-testid="events-list"]',
                '.events-list',
                '.hvac-events-list',
                '.manage-events-list',
                'table.events-table'
            ],
            
            eventRow: [
                '[data-testid="event-row"]',
                '.event-row',
                'tr.event-item',
                '.event-listing-item'
            ],
            
            // Event actions
            actions: {
                createNew: [
                    '[data-testid="create-event-btn"]',
                    '.create-event-btn',
                    'a[href*="create-event"]',
                    'button.new-event'
                ],
                bulkActions: [
                    '[data-testid="bulk-actions"]',
                    'select[name="bulk_action"]',
                    '.bulk-actions-select'
                ],
                applyBulk: [
                    '[data-testid="apply-bulk"]',
                    'button[name="apply_bulk"]',
                    '.apply-bulk-btn'
                ],
                export: [
                    '[data-testid="export-events"]',
                    '.export-events-btn',
                    'button.export'
                ],
                import: [
                    '[data-testid="import-events"]',
                    '.import-events-btn',
                    'button.import'
                ]
            },
            
            // Event row actions
            rowActions: {
                edit: [
                    '[data-testid="edit-event"]',
                    '.edit-event',
                    'a.edit-link',
                    'text=Edit'
                ],
                view: [
                    '[data-testid="view-event"]',
                    '.view-event',
                    'a.view-link',
                    'text=View'
                ],
                delete: [
                    '[data-testid="delete-event"]',
                    '.delete-event',
                    'button.delete-link',
                    'text=Delete'
                ],
                duplicate: [
                    '[data-testid="duplicate-event"]',
                    '.duplicate-event',
                    'button.duplicate-link',
                    'text=Duplicate'
                ],
                cancel: [
                    '[data-testid="cancel-event"]',
                    '.cancel-event',
                    'button.cancel-link',
                    'text=Cancel'
                ]
            },
            
            // Filtering and search
            filters: {
                search: [
                    '[data-testid="events-search"]',
                    'input[name="search"]',
                    '#events-search',
                    '.search-events'
                ],
                status: [
                    '[data-testid="filter-status"]',
                    'select[name="status_filter"]',
                    '.status-filter'
                ],
                dateRange: [
                    '[data-testid="date-range-filter"]',
                    'input[name="date_range"]',
                    '.date-range-filter'
                ],
                category: [
                    '[data-testid="category-filter"]',
                    'select[name="category_filter"]',
                    '.category-filter'
                ],
                venue: [
                    '[data-testid="venue-filter"]',
                    'select[name="venue_filter"]',
                    '.venue-filter'
                ]
            },
            
            // Sorting
            sorting: {
                title: [
                    '[data-testid="sort-title"]',
                    'th.sort-title',
                    '.sort-by-title'
                ],
                date: [
                    '[data-testid="sort-date"]',
                    'th.sort-date',
                    '.sort-by-date'
                ],
                status: [
                    '[data-testid="sort-status"]',
                    'th.sort-status',
                    '.sort-by-status'
                ],
                attendees: [
                    '[data-testid="sort-attendees"]',
                    'th.sort-attendees',
                    '.sort-by-attendees'
                ]
            },
            
            // Pagination
            pagination: {
                container: [
                    '[data-testid="pagination"]',
                    '.pagination',
                    '.events-pagination'
                ],
                previous: [
                    '[data-testid="prev-page"]',
                    '.prev-page',
                    'a.prev'
                ],
                next: [
                    '[data-testid="next-page"]',
                    '.next-page',
                    'a.next'
                ],
                pageNumbers: [
                    '[data-testid="page-numbers"]',
                    '.page-numbers',
                    '.pagination-numbers'
                ]
            },
            
            // Event details in list view
            eventDetails: {
                title: [
                    '[data-testid="event-title"]',
                    '.event-title',
                    'td.title'
                ],
                date: [
                    '[data-testid="event-date"]',
                    '.event-date',
                    'td.date'
                ],
                status: [
                    '[data-testid="event-status"]',
                    '.event-status',
                    'td.status'
                ],
                attendeeCount: [
                    '[data-testid="attendee-count"]',
                    '.attendee-count',
                    'td.attendees'
                ],
                venue: [
                    '[data-testid="event-venue"]',
                    '.event-venue',
                    'td.venue'
                ],
                organizer: [
                    '[data-testid="event-organizer"]',
                    '.event-organizer',
                    'td.organizer'
                ]
            },
            
            // Dashboard statistics
            stats: {
                totalEvents: [
                    '[data-testid="total-events"]',
                    '.total-events-count',
                    '.stat-total-events'
                ],
                upcomingEvents: [
                    '[data-testid="upcoming-events"]',
                    '.upcoming-events-count',
                    '.stat-upcoming'
                ],
                draftEvents: [
                    '[data-testid="draft-events"]',
                    '.draft-events-count',
                    '.stat-drafts'
                ],
                publishedEvents: [
                    '[data-testid="published-events"]',
                    '.published-events-count',
                    '.stat-published'
                ],
                totalAttendees: [
                    '[data-testid="total-attendees"]',
                    '.total-attendees-count',
                    '.stat-attendees'
                ]
            },
            
            // Quick actions panel
            quickActions: {
                panel: [
                    '[data-testid="quick-actions"]',
                    '.quick-actions-panel',
                    '.management-quick-actions'
                ],
                bulkPublish: [
                    '[data-testid="bulk-publish"]',
                    '.bulk-publish-btn',
                    'button.quick-publish'
                ],
                bulkCancel: [
                    '[data-testid="bulk-cancel"]',
                    '.bulk-cancel-btn',
                    'button.quick-cancel'
                ],
                exportSelected: [
                    '[data-testid="export-selected"]',
                    '.export-selected-btn',
                    'button.export-selected'
                ]
            },
            
            // Messages and notifications
            messages: {
                success: [
                    '[data-testid="success-message"]',
                    '.success-message',
                    '.notice-success'
                ],
                error: [
                    '[data-testid="error-message"]',
                    '.error-message',
                    '.notice-error'
                ],
                warning: [
                    '[data-testid="warning-message"]',
                    '.warning-message',
                    '.notice-warning'
                ]
            },
            
            // Loading states
            loading: [
                '[data-testid="loading"]',
                '.loading-events',
                '.management-loading'
            ]
        };
        
        this.urls = {
            management: '/trainer/manage-event/',
            events: '/trainer/events/',
            dashboard: '/trainer/dashboard/',
            tecMyEvents: '/trainer/tec-my-events/'
        };
    }
    
    /**
     * Navigate to event management dashboard
     */
    async navigate(dashboardType = 'standard') {
        let url;
        switch (dashboardType) {
            case 'tec':
                url = this.urls.tecMyEvents;
                break;
            case 'events':
                url = this.urls.events;
                break;
            default:
                url = this.urls.management;
        }
        
        await this.goto(url);
        await this.waitForDashboardLoad();
        console.log(`✅ Navigated to event management: ${dashboardType}`);
    }
    
    /**
     * Wait for management dashboard to load
     */
    async waitForDashboardLoad() {
        // Wait for main dashboard container
        await this.waitForVisible(this.selectors.managementDashboard, { timeout: 10000 });
        
        // Wait for events list to load
        await this.waitForVisible(this.selectors.eventsList, { timeout: 8000 });
        
        // Wait for WordPress and AJAX
        await this.waitForWordPressReady();
        await this.waitForAjax();
        
        // Wait for any loading indicators to disappear
        await this.waitForHidden(this.selectors.loading, { timeout: 5000 });
        
        console.log('✅ Event management dashboard loaded');
    }
    
    /**
     * Get dashboard statistics
     */
    async getDashboardStats() {
        const stats = {};
        
        // Get various statistics if available
        const statFields = [
            'totalEvents',
            'upcomingEvents',
            'draftEvents',
            'publishedEvents',
            'totalAttendees'
        ];
        
        for (const statField of statFields) {
            const statSelectors = this.selectors.stats[statField];
            if (await this.isVisible(statSelectors)) {
                const statText = await this.getText(statSelectors);
                stats[statField] = this.extractNumber(statText);
            }
        }
        
        console.log('📊 Dashboard statistics:', stats);
        return stats;
    }
    
    /**
     * Get list of events with their details
     */
    async getEventsList() {
        const events = [];
        
        // Find all event rows
        const eventRows = await this.page.locator(this.selectors.eventRow.join(', ')).all();
        
        for (const row of eventRows) {
            const event = {};
            
            // Extract event details from each row
            try {
                const titleElement = await row.locator(this.selectors.eventDetails.title.join(', ')).first();
                event.title = await titleElement.textContent();
                
                const dateElement = await row.locator(this.selectors.eventDetails.date.join(', ')).first();
                event.date = await dateElement.textContent();
                
                const statusElement = await row.locator(this.selectors.eventDetails.status.join(', ')).first();
                event.status = await statusElement.textContent();
                
                // Optional fields
                if (await row.locator(this.selectors.eventDetails.attendeeCount.join(', ')).count() > 0) {
                    const attendeeElement = await row.locator(this.selectors.eventDetails.attendeeCount.join(', ')).first();
                    event.attendees = await attendeeElement.textContent();
                }
                
                if (await row.locator(this.selectors.eventDetails.venue.join(', ')).count() > 0) {
                    const venueElement = await row.locator(this.selectors.eventDetails.venue.join(', ')).first();
                    event.venue = await venueElement.textContent();
                }
                
                events.push(event);
            } catch (error) {
                console.warn('Could not extract event details from row:', error.message);
            }
        }
        
        console.log(`📋 Found ${events.length} events in list`);
        return events;
    }
    
    /**
     * Search for events
     */
    async searchEvents(searchTerm) {
        console.log(`🔍 Searching for events: "${searchTerm}"`);
        
        if (!await this.isVisible(this.selectors.filters.search)) {
            throw new Error('Search functionality not available');
        }
        
        // Clear existing search and enter new term
        await this.clear(this.selectors.filters.search);
        await this.fill(this.selectors.filters.search, searchTerm);
        await this.page.keyboard.press('Enter');
        
        // Wait for results to update
        await this.waitForAjax();
        
        const results = await this.getEventsList();
        console.log(`📋 Search returned ${results.length} results`);
        
        return results;
    }
    
    /**
     * Filter events by status
     */
    async filterByStatus(status) {
        console.log(`🎯 Filtering events by status: ${status}`);
        
        if (await this.isVisible(this.selectors.filters.status)) {
            await this.selectByValue(this.selectors.filters.status, status);
            await this.waitForAjax();
            
            const results = await this.getEventsList();
            console.log(`📋 Status filter returned ${results.length} results`);
            return results;
        }
        
        throw new Error('Status filter not available');
    }
    
    /**
     * Filter events by date range
     */
    async filterByDateRange(startDate, endDate) {
        console.log(`📅 Filtering events by date range: ${startDate} to ${endDate}`);
        
        if (await this.isVisible(this.selectors.filters.dateRange)) {
            const dateRange = `${startDate} - ${endDate}`;
            await this.fill(this.selectors.filters.dateRange, dateRange);
            await this.waitForAjax();
            
            const results = await this.getEventsList();
            console.log(`📋 Date filter returned ${results.length} results`);
            return results;
        }
        
        throw new Error('Date range filter not available');
    }
    
    /**
     * Sort events by specified field
     */
    async sortEvents(sortBy, direction = 'asc') {
        console.log(`⬆️ Sorting events by ${sortBy} (${direction})`);
        
        const sortSelectors = this.selectors.sorting[sortBy];
        if (!sortSelectors || !await this.isVisible(sortSelectors)) {
            throw new Error(`Sort option '${sortBy}' not available`);
        }
        
        // Click sort header
        await this.click(sortSelectors);
        
        // Click again if we need descending order
        if (direction === 'desc') {
            await this.click(sortSelectors);
        }
        
        await this.waitForAjax();
        console.log(`✅ Events sorted by ${sortBy} (${direction})`);
    }
    
    /**
     * Select events for bulk operations
     */
    async selectEvents(eventTitles) {
        console.log(`☑️ Selecting events for bulk operation:`, eventTitles);
        
        const selectedCount = 0;
        const eventRows = await this.page.locator(this.selectors.eventRow.join(', ')).all();
        
        for (const row of eventRows) {
            try {
                const titleElement = await row.locator(this.selectors.eventDetails.title.join(', ')).first();
                const title = await titleElement.textContent();
                
                if (eventTitles.includes(title.trim())) {
                    // Find and click checkbox in this row
                    const checkbox = await row.locator('input[type="checkbox"]').first();
                    await checkbox.click();
                    selectedCount++;
                }
            } catch (error) {
                console.warn('Could not select event in row:', error.message);
            }
        }
        
        console.log(`✅ Selected ${selectedCount} events`);
        return selectedCount;
    }
    
    /**
     * Perform bulk action on selected events
     */
    async performBulkAction(action) {
        console.log(`⚡ Performing bulk action: ${action}`);
        
        if (!await this.isVisible(this.selectors.actions.bulkActions)) {
            throw new Error('Bulk actions not available');
        }
        
        // Select the bulk action
        await this.selectByValue(this.selectors.actions.bulkActions, action);
        
        // Apply the bulk action
        await this.click(this.selectors.actions.applyBulk);
        
        // Wait for action to complete
        await this.waitForAjax();
        
        // Check for success/error messages
        const result = await this.getBulkActionResult();
        console.log(`${result.success ? '✅' : '❌'} Bulk action result:`, result.message);
        
        return result;
    }
    
    /**
     * Get bulk action result
     */
    async getBulkActionResult() {
        // Check for success message
        if (await this.isVisible(this.selectors.messages.success)) {
            return {
                success: true,
                message: await this.getText(this.selectors.messages.success)
            };
        }
        
        // Check for error message
        if (await this.isVisible(this.selectors.messages.error)) {
            return {
                success: false,
                message: await this.getText(this.selectors.messages.error)
            };
        }
        
        // Default success if no messages
        return {
            success: true,
            message: 'Bulk action completed (no confirmation message)'
        };
    }
    
    /**
     * Edit specific event
     */
    async editEvent(eventTitle) {
        console.log(`✏️ Editing event: ${eventTitle}`);
        
        const eventRow = await this.findEventRow(eventTitle);
        if (!eventRow) {
            throw new Error(`Event '${eventTitle}' not found`);
        }
        
        // Find and click edit button in this row
        const editButton = await eventRow.locator(this.selectors.rowActions.edit.join(', ')).first();
        await editButton.click();
        
        // Wait for navigation to edit page
        await this.waitForUrlChange();
        console.log(`✅ Navigated to edit page for: ${eventTitle}`);
    }
    
    /**
     * View specific event
     */
    async viewEvent(eventTitle) {
        console.log(`👁️ Viewing event: ${eventTitle}`);
        
        const eventRow = await this.findEventRow(eventTitle);
        if (!eventRow) {
            throw new Error(`Event '${eventTitle}' not found`);
        }
        
        // Find and click view button in this row
        const viewButton = await eventRow.locator(this.selectors.rowActions.view.join(', ')).first();
        await viewButton.click();
        
        // Wait for navigation or modal to open
        await this.waitForAjax();
        console.log(`✅ Viewing event: ${eventTitle}`);
    }
    
    /**
     * Delete specific event
     */
    async deleteEvent(eventTitle, confirmDelete = true) {
        console.log(`🗑️ Deleting event: ${eventTitle}`);
        
        const eventRow = await this.findEventRow(eventTitle);
        if (!eventRow) {
            throw new Error(`Event '${eventTitle}' not found`);
        }
        
        // Find and click delete button
        const deleteButton = await eventRow.locator(this.selectors.rowActions.delete.join(', ')).first();
        await deleteButton.click();
        
        // Handle confirmation dialog if it appears
        if (confirmDelete) {
            this.page.on('dialog', async dialog => {
                console.log(`🔔 Confirmation: ${dialog.message()}`);
                await dialog.accept();
            });
        }
        
        await this.waitForAjax();
        
        // Verify deletion
        const stillExists = await this.findEventRow(eventTitle);
        const deleted = !stillExists;
        
        console.log(`${deleted ? '✅' : '❌'} Event deletion: ${eventTitle}`);
        return { deleted, eventTitle };
    }
    
    /**
     * Duplicate specific event
     */
    async duplicateEvent(eventTitle) {
        console.log(`📋 Duplicating event: ${eventTitle}`);
        
        const eventRow = await this.findEventRow(eventTitle);
        if (!eventRow) {
            throw new Error(`Event '${eventTitle}' not found`);
        }
        
        const duplicateButton = await eventRow.locator(this.selectors.rowActions.duplicate.join(', ')).first();
        await duplicateButton.click();
        
        await this.waitForAjax();
        
        // Look for success message or new duplicate event
        const result = await this.getBulkActionResult();
        console.log(`✅ Event duplicated: ${eventTitle}`);
        return result;
    }
    
    /**
     * Find event row by title
     */
    async findEventRow(eventTitle) {
        const eventRows = await this.page.locator(this.selectors.eventRow.join(', ')).all();
        
        for (const row of eventRows) {
            try {
                const titleElement = await row.locator(this.selectors.eventDetails.title.join(', ')).first();
                const title = await titleElement.textContent();
                
                if (title.trim() === eventTitle.trim()) {
                    return row;
                }
            } catch (error) {
                continue;
            }
        }
        
        return null;
    }
    
    /**
     * Navigate through pagination
     */
    async navigateToPage(pageNumber) {
        console.log(`📄 Navigating to page: ${pageNumber}`);
        
        if (!await this.isVisible(this.selectors.pagination.container)) {
            console.log('⚠️ Pagination not available');
            return false;
        }
        
        // Look for specific page number link
        const pageLink = await this.getVisibleSelector([
            `text=${pageNumber}`,
            `[data-page="${pageNumber}"]`,
            `.page-${pageNumber}`
        ]);
        
        if (pageLink) {
            await this.click(pageLink);
            await this.waitForAjax();
            console.log(`✅ Navigated to page ${pageNumber}`);
            return true;
        }
        
        console.log(`⚠️ Page ${pageNumber} not found`);
        return false;
    }
    
    /**
     * Export events
     */
    async exportEvents(format = 'csv') {
        console.log(`📤 Exporting events in ${format} format`);
        
        if (!await this.isVisible(this.selectors.actions.export)) {
            throw new Error('Export functionality not available');
        }
        
        // Click export button
        await this.click(this.selectors.actions.export);
        
        // Handle format selection if needed
        const formatSelector = await this.getVisibleSelector([
            `select[name="export_format"]`,
            `input[value="${format}"]`,
            `.format-${format}`
        ]);
        
        if (formatSelector) {
            if (formatSelector.includes('select')) {
                await this.selectByValue(formatSelector, format);
            } else {
                await this.click(formatSelector);
            }
        }
        
        // Wait for export to process
        await this.waitForAjax();
        
        console.log(`✅ Events export initiated (${format})`);
        return { format, initiated: true };
    }
    
    /**
     * Get event management metrics
     */
    async getManagementMetrics() {
        const metrics = {
            totalEvents: 0,
            eventsByStatus: {},
            averageAttendeesPerEvent: 0,
            upcomingEventsCount: 0
        };
        
        // Get dashboard stats
        const stats = await this.getDashboardStats();
        metrics.totalEvents = stats.totalEvents || 0;
        metrics.upcomingEventsCount = stats.upcomingEvents || 0;
        
        // Get events list for detailed analysis
        const events = await this.getEventsList();
        
        // Analyze events by status
        events.forEach(event => {
            const status = event.status?.toLowerCase() || 'unknown';
            metrics.eventsByStatus[status] = (metrics.eventsByStatus[status] || 0) + 1;
        });
        
        // Calculate average attendees (if available)
        const eventsWithAttendees = events.filter(event => event.attendees && !isNaN(parseInt(event.attendees)));
        if (eventsWithAttendees.length > 0) {
            const totalAttendees = eventsWithAttendees.reduce((sum, event) => {
                return sum + parseInt(event.attendees);
            }, 0);
            metrics.averageAttendeesPerEvent = Math.round(totalAttendees / eventsWithAttendees.length);
        }
        
        console.log('📊 Management metrics:', metrics);
        return metrics;
    }
    
    /**
     * Verify management dashboard functionality
     */
    async verifyDashboardFunctionality() {
        const functionality = {
            canViewEvents: await this.isVisible(this.selectors.eventsList),
            canCreateEvents: await this.isVisible(this.selectors.actions.createNew),
            canSearch: await this.isVisible(this.selectors.filters.search),
            canFilter: await this.isVisible(this.selectors.filters.status),
            canSort: await this.isVisible(this.selectors.sorting.date),
            hasBulkActions: await this.isVisible(this.selectors.actions.bulkActions),
            canExport: await this.isVisible(this.selectors.actions.export),
            hasPagination: await this.isVisible(this.selectors.pagination.container),
            hasStats: await this.isVisible(this.selectors.stats.totalEvents)
        };
        
        const functionalityScore = Object.values(functionality).filter(Boolean).length;
        const totalFeatures = Object.keys(functionality).length;
        
        console.log(`🔧 Dashboard functionality: ${functionalityScore}/${totalFeatures} features available`);
        return { ...functionality, score: functionalityScore, total: totalFeatures };
    }
    
    /**
     * Extract number from text
     */
    extractNumber(text) {
        const match = text.match(/\d+/);
        return match ? parseInt(match[0], 10) : 0;
    }
    
    /**
     * Take screenshot of management dashboard
     */
    async screenshotDashboard(name = 'event-management-dashboard') {
        return await this.takeScreenshot(name, { fullPage: true });
    }
}

module.exports = EventManagement;