/**
 * 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
    window.MMProCalendar = 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;
            this.eventCategories = null;
        }

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

            // Log configuration for debugging
            console.log('Calendar configuration:', this.config);

            // 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++;
                    if (attempts === 1) {
                        console.log("Waiting for FullCalendar to load...");
                        console.log("Current script status:", {
                            fullCalendar: typeof FullCalendar !== "undefined",
                            jQuery: typeof jQuery !== "undefined",
                            colorbox: typeof jQuery !== "undefined" ? typeof jQuery.colorbox !== "undefined" : false
                        });
                    }
                    if (attempts > 20) {
                        clearInterval(interval);
                        console.error("FullCalendar failed to load after multiple attempts");
                        const error = new Error('FullCalendar failed to load');
                        error.details = {
                            fullCalendar: typeof FullCalendar !== "undefined" ? FullCalendar : "undefined",
                            windowFullCalendar: window.FullCalendar,
                            hasCalendarClass: typeof FullCalendar !== "undefined" ? Boolean(FullCalendar.Calendar) : false,
                            scripts: Array.from(document.scripts).map(s => s.src)
                        };
                        console.error(error);
                        $(this.calendarEl).append('<div class="alert alert-danger">Failed to initialize calendar: FullCalendar library not loaded. Please check the console for details.</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 {
                console.log('Initializing calendar with config:', {
                    initialView: this.isMobile() ? 'listMonth' : this.config.initialView,
                    views: this.config.views
                });

                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 || 'dayGridMonth,listMonth'
                    },
                    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),
                    eventWillUnmount: this.handleEventUnmount.bind(this),
                    loading: this.handleLoading.bind(this),
                    eventClick: this.handleEventClick.bind(this),
                    windowResize: this.handleWindowResize.bind(this)
                });

                this.calendar.render();
                console.log('Calendar rendered successfully');
            } 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 {
                // Don't encode the sector parameter here - let URLSearchParams handle it
                const sector = this.config.sector || '';
                
                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
                });

                // Only add sector if it's not empty - use correct case for API
                if (sector) {
                    params.append('Sector', sector);
                    if (this.config.debug) {
                        console.log('Fetching events with sector filter:', sector);
                    }
                }

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

                const data = await response.json();
                console.log(`Loaded ${data.length} events from API`);
                
                successCallback(data);
            } catch (error) {
                console.error('Error fetching events:', error);
                failureCallback(error);
                const errorMessage = error.message || 'Error loading calendar events';
                if (!document.querySelector('.mmpro-calendar__error')) {
                    $(this.calendarEl).append(`<div class="mmpro-calendar__error alert alert-danger">${errorMessage}</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) {
            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') {
                    tippy(el, {
                        content: tooltipContent,
                        allowHTML: true,
                        placement: 'top',
                        trigger: 'mouseenter focus',
                        interactive: true,
                        theme: 'mmpro-dark',
                        appendTo: document.body
                    });
                } 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) {
                console.error('Error in handleEventMount:', error);
                // Fallback to basic title
                el.title = event.title;
            }
        }

        /**
         * Helper function to darken or lighten a color
         * @param {string} color - The color to adjust (hex format)
         * @param {number} amount - The amount to adjust (-100 to 100)
         * @returns {string} - The adjusted color
         */
        adjustColorBrightness(color, amount) {
            let usePound = false;
            
            if (color[0] === "#") {
                color = color.slice(1);
                usePound = true;
            }
            
            // Handle shorthand hex (e.g. #fff)
            if (color.length === 3) {
                color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2];
            }
            
            let r = parseInt(color.substring(0, 2), 16);
            let g = parseInt(color.substring(2, 4), 16);
            let b = parseInt(color.substring(4, 6), 16);
            
            // Adjust each color component
            r = Math.max(0, Math.min(255, r + amount));
            g = Math.max(0, Math.min(255, g + amount));
            b = Math.max(0, Math.min(255, b + amount));
            
            const newColor = ((r << 16) | (g << 8) | b).toString(16).padStart(6, '0');
            return (usePound ? "#" : "") + newColor;
        }

        // Ensure handleEventUnmount is still present and correctly configured
        /**
         * Handle event unmounting - clean up tooltips
         */
        handleEventUnmount(info) {
             const eventElement = info.el;
             if (eventElement && eventElement._tooltip && typeof eventElement._tooltip.dispose === 'function') {
                 try {
                     // console.log('Disposing tooltip on unmount for:', eventElement);
                     eventElement._tooltip.dispose();
                 } catch (disposeError) {
                     console.warn('Error disposing tooltip on unmount:', disposeError);
                 }
                 eventElement._tooltip = null; // Clear reference
             }
        }

        /**
         * 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();
                
                // Store categories for later use in tooltips
                this.eventCategories = data;
                
                // Render the color key as before
                this.renderColorKey(data);
            } catch (error) {
                console.error('Error loading event categories:', error);
                // Don't fail silently - show error to user
                if (this.colorKeyEl) {
                    this.colorKeyEl.innerHTML = '<div class="alert alert-warning">Failed to load event categories</div>';
                }
            }
        }

        /**
         * 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 document is ready
    $(document).ready(function() {
        if (typeof MMProCalendar !== "undefined") {
            const calendar = new MMProCalendar();
            calendar.init();
        } else {
            console.error("MMProCalendar class not found. Check if show-calendar.js is loaded correctly.");
            $(".mmpro-calendar__container").append(
                `<div class="alert alert-danger">
                    Calendar initialization failed. Please check the browser console for details.
                </div>`
            );
        }
    });

})(jQuery);