/**
 * Member Minder Pro Calendar JavaScript
 * Handles calendar initialization and event management for the Member Minder Pro WordPress plugin.
 */

(function($) {
    'use strict';

    // Calendar class to handle all calendar-related functionality
    class MMProCalendar {
        constructor() {
            this.calendarEl = document.querySelector('.mmpro-calendar__container');
            this.colorKeyEl = document.querySelector('.mmpro-calendar__color-key');
            this.config = window.mmproCalendarConfig || {};
            this.calendar = null;
            this.waitAttempts = undefined;
        }

        /**
         * Initialize the calendar
         */
        init() {
            if (!this.calendarEl) {
                console.error('Calendar element not found');
                return;
            }

            // Wait for FullCalendar to be fully loaded
            this.waitForFullCalendar();
        }

        /**
         * Wait for FullCalendar and its plugins to be loaded
         */
        waitForFullCalendar() {
            let attempts = 0;
            let interval = setInterval(() => {
                if (typeof FullCalendar !== "undefined" && FullCalendar.Calendar) {
                    console.log("FullCalendar loaded successfully!");
                    clearInterval(interval);
                    this.initializeCalendar();
                    this.loadEventCategories();
                } else {
                    attempts++;
                    console.log(`Waiting for FullCalendar to load... Attempt: ${attempts}`);
                    if (attempts > 20) {
                        clearInterval(interval);
                        console.error("FullCalendar failed to load after multiple attempts");
                        console.log("FullCalendar initialization status:", {
                            fullCalendar: typeof FullCalendar !== "undefined" ? FullCalendar : "undefined",
                            windowFullCalendar: window.FullCalendar,
                            hasCalendarClass: typeof FullCalendar !== "undefined" ? Boolean(FullCalendar.Calendar) : false
                        });
                        $(this.calendarEl).append('<div class="alert alert-danger">Failed to initialize calendar: FullCalendar library not loaded</div>');
                    }
                }
            }, 300); // Check every 300ms
        }
        

        /**
         * Check if the device is mobile
         */
        isMobile() {
            return window.matchMedia('only screen and (max-width: 760px)').matches;
        }

        /**
         * Initialize the FullCalendar instance
         */
        initializeCalendar() {
            try {
                this.calendar = new FullCalendar.Calendar(this.calendarEl, {
                    initialView: this.isMobile() ? 'listMonth' : this.config.initialView,
                    headerToolbar: {
                        left: 'prev,next today',
                        center: 'title',
                        right: this.config.views
                    },
                    views: {
                        dayGridMonth: { buttonText: 'Month' },
                        listMonth: { 
                            buttonText: 'List',
                            duration: { months: 1 }
                        }
                    },
                    timeZone: 'UTC',
                    themeSystem: 'standard',
                    height: 'auto',
                    navLinks: true,
                    editable: false,
                    selectable: true,
                    dayMaxEvents: false,
                    eventDisplay: 'block',
                    events: this.fetchEvents.bind(this),
                    eventDidMount: this.handleEventMount.bind(this),
                    loading: this.handleLoading.bind(this),
                    eventClick: this.handleEventClick.bind(this),
                    windowResize: this.handleWindowResize.bind(this)
                });

                this.calendar.render();
            } catch (error) {
                console.error('Error initializing calendar:', error);
                $(this.calendarEl).append('<div class="alert alert-danger">Error initializing calendar: ' + error.message + '</div>');
            }
        }

        /**
         * Fetch events from the server
         */
        async fetchEvents(fetchInfo, successCallback, failureCallback) {
            try {
                const params = new URLSearchParams({
                    baseUrl: this.config.eventBaseUrl,
                    start: fetchInfo.startStr,
                    end: fetchInfo.endStr,
                    AccountID: this.config.accountId,
                    ClubID: this.config.clubId,
                    EventCategoryIDs: this.config.eventCategoryIds
                });

                const response = await fetch(`${this.config.eventUrl}?${params.toString()}`);
                if (!response.ok) {
                    throw new Error('Network response was not ok');
                }

                const data = await response.json();
                successCallback(data);
            } catch (error) {
                console.error('Error fetching events:', error);
                failureCallback(error);
                $(this.calendarEl).append('<div class="alert alert-danger">Error loading calendar events</div>');
            }
        }

        /**
         * Handle event clicks - open in colorbox on desktop, direct link on mobile
         */
        handleEventClick(info) {
            info.jsEvent.preventDefault();
            
            if (this.isMobile()) {
                // On mobile, navigate directly to the event URL
                window.location.href = info.event.url;
            } else {
                // On desktop, open in colorbox
                if (typeof jQuery !== 'undefined' && typeof jQuery.colorbox !== 'undefined') {
                    try {
                        jQuery(info.el).colorbox({
                            href: info.event.url,
                            iframe: true,
                            width: "90%",
                            height: "90%",
                            fastIframe: false,
                            onComplete: function() {
                                // Only trigger resize for responsive behavior
                                jQuery(window).trigger('resize');
                            },
                            onError: function() {
                                console.error('ColorBox failed to load content');
                                window.location.href = info.event.url;
                            }
                        });
                    } catch (error) {
                        console.error('Error opening ColorBox:', error);
                        window.location.href = info.event.url;
                    }
                } else {
                    console.error('ColorBox not initialized. Falling back to direct link.');
                    window.location.href = info.event.url;
                }
            }
        }

        /**
         * Handle window resize - update calendar view for mobile/desktop
         */
        handleWindowResize() {
            const isMobileView = this.isMobile();
            const currentView = this.calendar.view.type;
            
            // Switch view based on screen size if needed
            if (isMobileView && currentView === 'dayGridMonth') {
                this.calendar.changeView('listMonth');
            } else if (!isMobileView && currentView === 'listMonth' && this.config.initialView === 'dayGridMonth') {
                this.calendar.changeView('dayGridMonth');
            }
        }

        /**
         * Handle event mounting - add tooltips and enhance event display
         */
        handleEventMount(info) {
            // Wait for next tick to ensure DOM is ready
            requestAnimationFrame(() => {
                try {
                    // Only add tooltip if the element exists, is in the DOM, and has content
                    if (info.el && 
                        info.el.isConnected && 
                        info.event.title && 
                        document.contains(info.el) &&
                        typeof Tooltip !== 'undefined') {
                        
                        // Create tooltip container if it doesn't exist
                        let tooltipContainer = document.querySelector('.mmpro-calendar__tooltip-container');
                        if (!tooltipContainer) {
                            tooltipContainer = document.createElement('div');
                            tooltipContainer.className = 'mmpro-calendar__tooltip-container';
                            const calendarContainer = document.querySelector('.mmpro-calendar');
                            if (calendarContainer) {
                                calendarContainer.appendChild(tooltipContainer);
                            } else {
                                console.warn('Calendar container not found for tooltip');
                                return;
                            }
                        }

                        // Add tooltip with namespaced classes
                        const tooltipInstance = new Tooltip(info.el, {
                            title: info.event.title || '',
                            placement: 'top',
                            trigger: 'hover',
                            container: tooltipContainer,
                            template: `
                                <div class="mmpro-tooltip" role="tooltip">
                                    <div class="mmpro-tooltip-arrow"></div>
                                    <div class="mmpro-tooltip-inner"></div>
                                </div>
                            `
                        });

                        // Store tooltip instance on element for cleanup
                        info.el._tooltip = tooltipInstance;

                        // Clean up tooltip when event element is removed
                        const observer = new MutationObserver((mutations, obs) => {
                            if (!document.contains(info.el)) {
                                if (info.el._tooltip && info.el._tooltip.dispose) {
                                    info.el._tooltip.dispose();
                                }
                                obs.disconnect();
                            }
                        });

                        observer.observe(document.body, {
                            childList: true,
                            subtree: true
                        });
                    }

                    // Add visual indicator for events with additional details
                    if (info.el && info.event.extendedProps && info.event.extendedProps.description) {
                        const dotEl = document.createElement('span');
                        dotEl.className = 'mmpro-calendar__event-dot';
                        info.el.appendChild(dotEl);
                    }
                } catch (error) {
                    console.warn('Failed to initialize tooltip:', error);
                }
            });
        }

        /**
         * Handle loading state
         */
        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();
            }
        }

        /**
         * Load and display event categories
         */
        async loadEventCategories() {
            if (!this.colorKeyEl) return;

            try {
                const params = new URLSearchParams({
                    baseUrl: this.config.categoryBaseUrl,
                    D: this.config.accountId
                });

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

                const data = await response.json();
                this.renderColorKey(data);
            } catch (error) {
                console.error('Error loading event categories:', error);
            }
        }

        /**
         * Render the color key
         */
        renderColorKey(categories) {
            if (!Array.isArray(categories)) {
                console.error('Invalid category data');
                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 DOM is ready
    $(document).ready(() => {
        const calendar = new MMProCalendar();
        calendar.init();
    });

})(jQuery); 