/**
 * MMPro Calendar JavaScript
 * Handles calendar initialization and event loading
 */

(function($) {
    'use strict';

    window.MMProCalendar = class MMProCalendar {
        constructor() {
            this.calendarEl = document.querySelector('.mmpro-calendar__container');
            this.colorKeyEl = document.querySelector('.mmpro-calendar__color-key');
            
            // Get configuration from wp_localize_script
            this.config = window.mmproCalendarConfig || {};
            
            this.calendar = null;
            this.waitAttempts = undefined;
            this.eventCategories = null;
        }

        init() {
            if (!this.calendarEl) {
                return;
            }

            this.waitForFullCalendar();
        }

        waitForFullCalendar() {
            let attempts = 0;
            const maxAttempts = 50; // 5 seconds max wait
            
            const interval = setInterval(() => {
                attempts++;
                
                if (typeof FullCalendar !== "undefined" && FullCalendar.Calendar) {
                    clearInterval(interval);
                    this.initializeCalendar();
                    this.loadEventCategories();
                } else if (attempts >= maxAttempts) {
                    clearInterval(interval);
                    this.calendarEl.innerHTML = '<div class="alert alert-danger">Calendar failed to load. Please refresh the page.</div>';
                }
            }, 100);
        }

        isMobile() {
            return window.innerWidth < 768;
        }

        initializeCalendar() {
            try {
                this.calendar = new FullCalendar.Calendar(this.calendarEl, {
                    initialView: this.isMobile() ? 'listMonth' : this.config.initialView,
                    views: {
                        dayGridMonth: {
                            titleFormat: { year: 'numeric', month: 'long' }
                        },
                        listMonth: {
                            titleFormat: { year: 'numeric', month: 'long' }
                        }
                    },
                    headerToolbar: {
                        left: 'prev,next today',
                        center: 'title',
                        right: 'dayGridMonth,listMonth'
                    },
                    height: 'auto',
                    events: this.fetchEvents.bind(this),
                    eventClick: this.handleEventClick.bind(this),
                    eventDidMount: this.handleEventMount.bind(this),
                    eventWillUnmount: this.handleEventUnmount.bind(this),
                    loading: this.handleLoading.bind(this),
                    windowResize: this.handleWindowResize.bind(this)
                });

                this.calendar.render();
            } catch (error) {
                this.calendarEl.innerHTML = '<div class="alert alert-danger">Calendar initialization failed.</div>';
            }
        }

        async fetchEvents(fetchInfo, successCallback, failureCallback) {
            try {
                const params = new URLSearchParams({
                    start: fetchInfo.start.toISOString(),
                    end: fetchInfo.end.toISOString(),
                    AccountID: this.config.accountId,
                    ClubID: this.config.clubId,
                    EventCategoryIDs: this.config.eventCategoryIds
                });

                // Add sector parameter if present
                if (this.config.sector) {
                    params.append('sector', this.config.sector);
                }

                const response = await fetch(`${this.config.eventUrl}?${params.toString()}`);
                
                if (!response.ok) {
                    const errorText = await response.text();
                    throw new Error(`Network response was not ok (${response.status}): ${errorText.substring(0, 200)}`);
                }

                const data = await response.json();
                
                // TIMEZONE HANDLING FIX - Added January 2025
                // Issue: The API returns times with 'Z' (UTC) suffix but these times are actually
                // in the event's local timezone, not UTC. This causes FullCalendar to incorrectly
                // convert them to the browser's timezone.
                // 
                // Example: A noon meeting in CDT is returned as "2025-07-08T12:00:00Z"
                // Without this fix, it shows as 7am CDT or 5am PDT in the browser.
                //
                // TO REVERT THIS FIX (when the API is corrected to send proper timezone data):
                // 1. Delete the entire processedData mapping code below (lines with processedData)
                // 2. Change 'successCallback(processedData);' back to 'successCallback(data);'
                // 3. The calendar will then properly handle UTC times and convert to local timezone
                //
                // Process events to remove UTC timezone indicator
                const processedData = data.map(event => {
                    if (event.start && event.start.endsWith('Z')) {
                        event.start = event.start.slice(0, -1);
                    }
                    if (event.end && event.end.endsWith('Z')) {
                        event.end = event.end.slice(0, -1);
                    }
                    return event;
                });
                
                successCallback(processedData);
            } catch (error) {
                failureCallback(error);
            }
        }

        handleEventClick(info) {
            const event = info.event;
            
            // Check if event has a URL
            if (event.url) {
                info.jsEvent.preventDefault();
                
                // Use ColorBox for modal display if available
                if (typeof $.colorbox !== 'undefined') {
                    $.colorbox({
                        href: event.url,
                        iframe: true,
                        width: '90%',
                        height: '90%',
                        onComplete: function() {
                            // Inject jQuery into iframe if needed
                            const iframe = document.getElementById('colorbox').querySelector('iframe');
                            if (iframe && iframe.contentWindow) {
                                iframe.contentWindow.jQuery = jQuery;
                                iframe.contentWindow.$ = jQuery;
                            }
                        }
                    });
                } else {
                    // Fallback to new window
                    window.open(event.url, '_blank');
                }
            }
        }

        handleWindowResize() {
            if (this.calendar) {
                this.calendar.updateSize();
            }
        }

        handleEventMount(info) {
            try {
                const { event, el } = info;
                
                // Add event color to element
                if (event.backgroundColor) {
                    el.style.backgroundColor = event.backgroundColor;
                    el.style.borderColor = event.backgroundColor;
                }

                // Create tooltip content
                const tooltipContent = `
                    <div class="mmpro-calendar-tooltip">
                        <div class="mmpro-calendar-tooltip__title">${event.title}</div>
                        ${event.extendedProps.description ? `
                            <div class="mmpro-calendar-tooltip__description">
                                ${event.extendedProps.description}
                            </div>
                        ` : ''}
                        ${event.extendedProps.location ? `
                            <div class="mmpro-calendar-tooltip__location">
                                Location: ${event.extendedProps.location}
                            </div>
                        ` : ''}
                        ${event.extendedProps.sector ? `
                            <div class="mmpro-calendar-tooltip__sector">
                                Sector: ${event.extendedProps.sector}
                            </div>
                        ` : ''}
                    </div>
                `;

                // Initialize tooltip using tippy.js
                if (typeof tippy !== 'undefined') {
                    const tooltip = tippy(el, {
                        content: tooltipContent,
                        allowHTML: true,
                        placement: 'top',
                        trigger: 'mouseenter focus',
                        interactive: false, // Changed to false to fix z-index issues
                        theme: 'mmpro-dark',
                        appendTo: () => document.body, // Use function for appendTo
                        zIndex: 2147483647, // Maximum z-index
                        popperOptions: {
                            strategy: 'fixed', // Always use fixed positioning
                            modifiers: [
                                {
                                    name: 'preventOverflow',
                                    options: {
                                        boundary: 'viewport'
                                    }
                                },
                                {
                                    name: 'flip',
                                    options: {
                                        fallbackPlacements: ['bottom', 'right', 'left']
                                    }
                                }
                            ]
                        }
                    });
                } else if (typeof Tooltip !== 'undefined') {
                    // Fallback to Bootstrap's Tooltip
                    new Tooltip(el, {
                        title: tooltipContent,
                        html: true,
                        placement: 'top',
                        trigger: 'hover',
                        container: 'body'
                    });
                } else {
                    // Basic fallback
                    el.title = event.title;
                }

            } catch (error) {
                // Fallback to basic title
                el.title = event.title;
            }
        }

        /**
         * Create a tooltip for any element
         * @param {HTMLElement} element - The element to attach tooltip to
         * @param {string} content - The tooltip content (HTML allowed)
         * @param {Object} options - Tooltip options
         */
        createTooltip(element, content, options = {}) {
            const defaultOptions = {
                placement: 'top',
                trigger: 'mouseenter focus',
                interactive: true,
                theme: 'mmpro-dark',
                appendTo: document.body, // Always append to body
                zIndex: 2147483647,
                popperOptions: {
                    strategy: 'fixed', // Always use fixed positioning
                    modifiers: [
                        {
                            name: 'zIndex',
                            options: {
                                zIndex: 2147483647
                            }
                        }
                    ]
                }
            };

            const finalOptions = { ...defaultOptions, ...options };

            if (typeof tippy !== 'undefined') {
                return tippy(element, {
                    content: content,
                    allowHTML: true,
                    ...finalOptions,
                    interactive: false, // Disable interactive to fix z-index issues
                    appendTo: () => document.body, // Use function for appendTo
                    popperOptions: {
                        ...finalOptions.popperOptions,
                        strategy: 'fixed',
                        modifiers: [
                            ...(finalOptions.popperOptions?.modifiers || []),
                            {
                                name: 'zIndex',
                                options: { zIndex: 2147483647 }
                            }
                        ]
                    }
                });
            } else if (typeof Tooltip !== 'undefined') {
                return new Tooltip(element, {
                    title: content,
                    html: true,
                    container: 'body',
                    ...finalOptions
                });
            } else {
                // Basic fallback
                element.title = content.replace(/<[^>]*>/g, ''); // Strip HTML for basic title
                return null;
            }
        }

        handleEventUnmount(info) {
             const eventElement = info.el;
             if (eventElement && eventElement._tooltip && typeof eventElement._tooltip.dispose === 'function') {
                 try {
                     eventElement._tooltip.dispose();
                 } catch (disposeError) {
                     // Silent fail
                 }
                 eventElement._tooltip = null;
             }
        }

        handleLoading(isLoading) {
            const loadingIndicator = $(this.calendarEl).find('.loading-indicator');
            if (isLoading) {
                if (!loadingIndicator.length) {
                    $(this.calendarEl).append('<div class="loading-indicator">Loading events...</div>');
                }
            } else {
                loadingIndicator.remove();
            }
        }

        async loadEventCategories() {
            if (!this.colorKeyEl) return;

            try {
                const response = await fetch(this.config.eventCategoryUrl);
                if (!response.ok) {
                    throw new Error('Network response was not ok');
                }

                const data = await response.json();
                
                // Store categories for later use in tooltips
                this.eventCategories = data;
                
                // Render the color key
                this.renderColorKey(data);
            } catch (error) {
                if (this.colorKeyEl) {
                    this.colorKeyEl.innerHTML = '<div class="alert alert-warning">Failed to load event categories</div>';
                }
            }
        }

        renderColorKey(categories) {
            if (!Array.isArray(categories)) {
                return;
            }

            const html = categories.reduce((acc, category) => {
                if (category.BGCOLOR && category.EVENTCATEGORY) {
                    return acc + `
                        <div class="mmpro-calendar__color-key-item">
                            <span class="mmpro-calendar__color-box" style="background-color: ${category.BGCOLOR};">
                                ${category.EVENTCATEGORY.trim()}
                            </span>
                        </div>`;
                }
                return acc;
            }, '<div class="mmpro-calendar__color-key-container">') + '</div>';

            this.colorKeyEl.innerHTML = html;
        }
    }

    // Initialize calendar when document is ready
    $(document).ready(function() {
        setTimeout(function() {
            if (typeof MMProCalendar !== "undefined") {
                const calendar = new MMProCalendar();
                calendar.init();
            } else {
                $(".mmpro-calendar__container").append(
                    `<div class="alert alert-danger">
                        Calendar initialization failed.
                    </div>`
                );
            }
        }, 200);
    });

})(jQuery);