/**
 * Master Trainer Events Management Page Object
 * Handles interactions with the master trainer events management page
 */

const BasePage = require('../base/BasePage');

class MasterTrainerEvents extends BasePage {
    constructor(page = null) {
        super(page);
        this.url = '/master-trainer/events/';
        this.title = 'Events Management';
        
        this.selectors = {
            // Main page elements
            pageTitle: 'h1, .page-title, .events-title',
            eventsContainer: '.events-container, .events-list, .events-table',
            
            // Events list and table
            eventsTable: 'table.events-table, .events-grid',
            eventRows: 'tr.event-row, .event-item',
            eventTitle: '.event-title, .event-name',
            eventDate: '.event-date, .event-start-date',
            eventStatus: '.event-status, .status',
            eventTrainer: '.event-trainer, .trainer-name',
            eventVenue: '.event-venue, .venue-name',
            
            // Action buttons
            createEventBtn: 'a[href*="create"], .create-event, .add-event',
            editEventBtn: 'a[href*="edit"], .edit-event, .event-edit',
            deleteEventBtn: 'a[href*="delete"], .delete-event, .event-delete',
            viewEventBtn: 'a[href*="view"], .view-event, .event-view',
            
            // Bulk actions
            bulkActionsSelect: 'select[name="bulk-action"], .bulk-actions select',
            bulkApplyBtn: '.bulk-apply, .apply-bulk-action',
            selectAllCheckbox: 'input[type="checkbox"].select-all',
            eventCheckboxes: 'input[type="checkbox"].event-select',
            
            // Filters and search
            searchInput: 'input[type="search"], .search-events, #event-search',
            searchBtn: '.search-btn, .search-submit',
            statusFilter: 'select.status-filter, #status-filter',
            trainerFilter: 'select.trainer-filter, #trainer-filter',
            dateFilter: 'input.date-filter, #date-filter',
            venueFilter: 'select.venue-filter, #venue-filter',
            clearFiltersBtn: '.clear-filters, .reset-filters',
            
            // Event statistics and overview
            eventStats: '.event-stats, .events-statistics',
            totalEvents: '.total-events, [data-metric="total"]',
            upcomingEvents: '.upcoming-events, [data-metric="upcoming"]',
            pastEvents: '.past-events, [data-metric="past"]',
            cancelledEvents: '.cancelled-events, [data-metric="cancelled"]',
            
            // Event categories and types
            categoryFilter: 'select.category-filter, #category-filter',
            eventTypes: '.event-types, .type-filter',
            
            // Pagination
            pagination: '.pagination, .page-navigation',
            prevPageBtn: '.prev-page, .previous',
            nextPageBtn: '.next-page, .next',
            pageNumbers: '.page-numbers a',
            
            // Export and reporting
            exportBtn: '.export-events, .download-events',
            reportingBtn: '.event-reports, .reporting',
            
            // Loading and status indicators
            loadingIndicator: '.loading, .spinner',
            errorMessage: '.error-message, .notice-error',
            successMessage: '.success-message, .notice-success',
            emptyState: '.no-events, .events-empty'
        };
    }

    /**
     * Wait for events page to be fully loaded
     */
    async waitForPageReady() {
        await this.waitForElement(this.selectors.pageTitle);
        await this.waitForAjaxComplete();
        
        // Wait for events container or empty state
        try {
            await Promise.race([
                this.waitForElement(this.selectors.eventsContainer, 10000),
                this.waitForElement(this.selectors.emptyState, 10000)
            ]);
        } catch (error) {
            console.warn('Events container or empty state not found, continuing...');
        }
    }

    /**
     * Get all events from the current page
     */
    async getEventsList() {
        const events = [];
        const eventRows = await this.page.$$(this.selectors.eventRows);
        
        for (const row of eventRows) {
            const event = {
                title: await this.getTextFromElement(row, this.selectors.eventTitle),
                date: await this.getTextFromElement(row, this.selectors.eventDate),
                status: await this.getTextFromElement(row, this.selectors.eventStatus),
                trainer: await this.getTextFromElement(row, this.selectors.eventTrainer),
                venue: await this.getTextFromElement(row, this.selectors.eventVenue)
            };
            events.push(event);
        }
        
        return events;
    }

    /**
     * Get event statistics from the page
     */
    async getEventStatistics() {
        const stats = {};
        
        try {
            if (await this.hasElement(this.selectors.totalEvents)) {
                const totalText = await this.getElementText(this.selectors.totalEvents);
                stats.total = this.extractNumber(totalText);
            }
            
            if (await this.hasElement(this.selectors.upcomingEvents)) {
                const upcomingText = await this.getElementText(this.selectors.upcomingEvents);
                stats.upcoming = this.extractNumber(upcomingText);
            }
            
            if (await this.hasElement(this.selectors.pastEvents)) {
                const pastText = await this.getElementText(this.selectors.pastEvents);
                stats.past = this.extractNumber(pastText);
            }
            
            if (await this.hasElement(this.selectors.cancelledEvents)) {
                const cancelledText = await this.getElementText(this.selectors.cancelledEvents);
                stats.cancelled = this.extractNumber(cancelledText);
            }
        } catch (error) {
            console.warn('Failed to get event statistics:', error.message);
        }
        
        return stats;
    }

    /**
     * Search for events by term
     */
    async searchEvents(searchTerm) {
        if (await this.hasElement(this.selectors.searchInput)) {
            await this.fillField(this.selectors.searchInput, searchTerm);
            
            if (await this.hasElement(this.selectors.searchBtn)) {
                await this.clickElement(this.selectors.searchBtn);
            } else {
                // Submit by pressing Enter
                await this.page.keyboard.press('Enter');
            }
            
            await this.waitForAjaxComplete();
            await this.waitForPageReady();
        }
    }

    /**
     * Filter events by status
     */
    async filterByStatus(status) {
        if (await this.hasElement(this.selectors.statusFilter)) {
            await this.selectOption(this.selectors.statusFilter, status);
            await this.waitForAjaxComplete();
            await this.waitForPageReady();
        }
    }

    /**
     * Filter events by trainer
     */
    async filterByTrainer(trainerId) {
        if (await this.hasElement(this.selectors.trainerFilter)) {
            await this.selectOption(this.selectors.trainerFilter, trainerId);
            await this.waitForAjaxComplete();
            await this.waitForPageReady();
        }
    }

    /**
     * Clear all filters
     */
    async clearAllFilters() {
        if (await this.hasElement(this.selectors.clearFiltersBtn)) {
            await this.clickElement(this.selectors.clearFiltersBtn);
            await this.waitForAjaxComplete();
            await this.waitForPageReady();
        }
    }

    /**
     * Navigate to create event page
     */
    async createNewEvent() {
        if (await this.hasElement(this.selectors.createEventBtn)) {
            await this.clickElement(this.selectors.createEventBtn);
            await this.waitForPageLoad();
            return true;
        }
        return false;
    }

    /**
     * Edit an event by index or title
     */
    async editEvent(identifier) {
        const eventRows = await this.page.$$(this.selectors.eventRows);
        
        if (typeof identifier === 'number' && eventRows[identifier]) {
            // Edit by index
            const editBtn = await eventRows[identifier].$(this.selectors.editEventBtn);
            if (editBtn) {
                await editBtn.click();
                await this.waitForPageLoad();
                return true;
            }
        } else if (typeof identifier === 'string') {
            // Edit by event title
            for (const row of eventRows) {
                const titleElement = await row.$(this.selectors.eventTitle);
                if (titleElement) {
                    const title = await titleElement.textContent();
                    if (title.trim().includes(identifier)) {
                        const editBtn = await row.$(this.selectors.editEventBtn);
                        if (editBtn) {
                            await editBtn.click();
                            await this.waitForPageLoad();
                            return true;
                        }
                    }
                }
            }
        }
        
        return false;
    }

    /**
     * Perform bulk actions on selected events
     */
    async performBulkAction(action, eventIndices = []) {
        // Select events by index
        const eventRows = await this.page.$$(this.selectors.eventRows);
        
        for (const index of eventIndices) {
            if (eventRows[index]) {
                const checkbox = await eventRows[index].$(this.selectors.eventCheckboxes);
                if (checkbox) {
                    await checkbox.click();
                }
            }
        }
        
        // Select bulk action
        if (await this.hasElement(this.selectors.bulkActionsSelect)) {
            await this.selectOption(this.selectors.bulkActionsSelect, action);
            
            if (await this.hasElement(this.selectors.bulkApplyBtn)) {
                await this.clickElement(this.selectors.bulkApplyBtn);
                await this.waitForAjaxComplete();
                await this.waitForPageReady();
                return true;
            }
        }
        
        return false;
    }

    /**
     * Select all events on current page
     */
    async selectAllEvents() {
        if (await this.hasElement(this.selectors.selectAllCheckbox)) {
            await this.clickElement(this.selectors.selectAllCheckbox);
            return true;
        }
        return false;
    }

    /**
     * Export events data
     */
    async exportEvents() {
        if (await this.hasElement(this.selectors.exportBtn)) {
            await this.clickElement(this.selectors.exportBtn);
            // Wait for download to start
            await this.page.waitForTimeout(2000);
            return true;
        }
        return false;
    }

    /**
     * Check if events page has any events
     */
    async hasEvents() {
        return await this.hasElement(this.selectors.eventRows);
    }

    /**
     * Check if page is showing empty state
     */
    async isEmptyState() {
        return await this.isElementVisible(this.selectors.emptyState);
    }

    /**
     * Get available event management features
     */
    async getAvailableFeatures() {
        return {
            canCreate: await this.hasElement(this.selectors.createEventBtn),
            canSearch: await this.hasElement(this.selectors.searchInput),
            canFilter: await this.hasElement(this.selectors.statusFilter),
            canBulkAction: await this.hasElement(this.selectors.bulkActionsSelect),
            canExport: await this.hasElement(this.selectors.exportBtn),
            hasStatistics: await this.hasElement(this.selectors.eventStats)
        };
    }

    /**
     * Helper method to get text from child element
     */
    async getTextFromElement(parentElement, selector) {
        try {
            const element = await parentElement.$(selector);
            return element ? await element.textContent() : '';
        } catch (error) {
            return '';
        }
    }

    /**
     * Extract number from text string
     */
    extractNumber(text) {
        const match = text.match(/\d+/);
        return match ? parseInt(match[0], 10) : 0;
    }
}

module.exports = MasterTrainerEvents;