/**
 * UltraGuard Pro - Modals & Sidebar Module
 * Version: 2.1.0 - Generic Modal Handler
 * 
 * Features:
 * - Generic modal system (works with any modal)
 * - Handles all modal triggers automatically
 * - No hardcoded modal IDs or button types
 * - Dynamic content loading support
 * - Accessibility (ARIA, focus management)
 * - Keyboard navigation (ESC, Tab trap)
 * - Body scroll lock
 * - Modal stacking
 * - Event system
 */

(function($) {
    'use strict';

    window.UltraGuardModals = window.UltraGuardModals || {};

    // ==================== Modal Manager ====================
    /**
     * ModalManager - Handles all modal operations generically
     */
    class ModalManager {
        constructor() {
            this.modals = new Map();
            this.openModals = [];
            this.config = {
                animationSpeed: 200,
                closeOnEscape: true,
                closeOnOverlay: true,
                lockBodyScroll: true,
                defaultModalId: null // No default, works with any modal
            };
            this.bodyScrollLocked = false;
            this.originalBodyPadding = null;
            this.initialized = false;
        }

        /**
         * Initialize modal system
         */
        init() {
            if (this.initialized) return;
            
            this.discoverModals();
            this.bindGlobalEvents();
            this.initialized = true;
            
        }

        /**
         * Discover all modals in DOM
         */
        discoverModals() {
            $('.ultraguard-modal-overlay').each((index, element) => {
                const $modal = $(element);
                const modalId = $modal.attr('id');
                
                if (modalId) {
                    this.registerModal(modalId, $modal);
                } else {
                    // Generate an ID if none exists
                    const generatedId = 'ultraguard-modal-' + Math.random().toString(36).substr(2, 9);
                    $modal.attr('id', generatedId);
                    this.registerModal(generatedId, $modal);
                }
            });
        }

        /**
         * Register a modal
         */
        registerModal(modalId, $modal) {
            // Ensure modal has proper structure
            if (!$modal.find('.ultraguard-modal').length) {
                console.warn('Modal', modalId, 'missing .ultraguard-modal container');
                return;
            }
            
            const modal = {
                id: modalId,
                $element: $modal,
                $dialog: $modal.find('.ultraguard-modal').first(),
                $header: $modal.find('.ultraguard-modal-header').first(),
                $title: $modal.find('.ultraguard-modal-title').first(),
                $body: $modal.find('.ultraguard-modal-body').first(),
                $footer: $modal.find('.ultraguard-modal-footer').first(),
                $closeBtn: $modal.find('.ultraguard-modal-close, [data-modal-close]'),
                isOpen: false,
                previousFocus: null,
                data: {} // Store any custom data
            };

            // If no close button found, create one
            if (!modal.$closeBtn.length && modal.$header.length) {
                const $closeBtn = $('<button class="ultraguard-modal-close" aria-label="Close">&times;</button>');
                modal.$header.append($closeBtn);
                modal.$closeBtn = $closeBtn;
            }

            this.modals.set(modalId, modal);
            this.setupModalEvents(modal);
            this.enhanceAccessibility(modal);
            
        }

        /**
         * Setup modal-specific events
         */
        setupModalEvents(modal) {
            // Close button
            modal.$closeBtn.off('click.ultraguard-modal').on('click.ultraguard-modal', (e) => {
                e.preventDefault();
                e.stopPropagation();
                this.close(modal.id);
            });

            // Overlay click
            modal.$element.off('click.ultraguard-modal').on('click.ultraguard-modal', (e) => {
                if (e.target === modal.$element[0] && this.config.closeOnOverlay) {
                    this.close(modal.id);
                }
            });

            // Trap focus
            modal.$element.off('keydown.ultraguard-modal').on('keydown.ultraguard-modal', (e) => {
                if (modal.isOpen && e.key === 'Tab') {
                    this.trapFocus(e, modal);
                }
            });
        }

        /**
         * Bind global events for all modal triggers
         */
        bindGlobalEvents() {
            // Generic modal triggers - handles ANY element with data-modal-trigger
            $(document).off('click.ultraguard-modal', '[data-modal-trigger]')
                .on('click.ultraguard-modal', '[data-modal-trigger]', (e) => {
                    const $trigger = $(e.currentTarget);
                    const modalId = $trigger.data('modal-trigger');
                    
                    if (modalId) {
                        e.preventDefault();
                        e.stopPropagation();
                        
                        // Get any data attributes to pass to the modal
                        const triggerData = this.getTriggerData($trigger);
                        
                        // Open the modal with trigger data
                        this.open(modalId, triggerData, $trigger);
                    }
                });

            // Generic close triggers
            $(document).off('click.ultraguard-modal', '[data-modal-close]')
                .on('click.ultraguard-modal', '[data-modal-close]', (e) => {
                    e.preventDefault();
                    e.stopPropagation();
                    
                    const $trigger = $(e.currentTarget);
                    const modalId = $trigger.data('modal-close');
                    
                    if (modalId) {
                        this.close(modalId);
                    } else {
                        // Find parent modal and close it
                        const $modal = $trigger.closest('.ultraguard-modal-overlay');
                        if ($modal.length) {
                            const id = $modal.attr('id');
                            if (id) this.close(id);
                        } else {
                            this.closeTopModal();
                        }
                    }
                });

            // ESC key
            $(document).off('keydown.ultraguard-modal-esc')
                .on('keydown.ultraguard-modal-esc', (e) => {
                    if (e.key === 'Escape' && this.config.closeOnEscape && this.openModals.length > 0) {
                        this.closeTopModal();
                    }
                });

            // Watch for dynamically added modals
            this.watchForNewModals();
        }

        /**
         * Watch for dynamically added modals
         */
        watchForNewModals() {
            // Use MutationObserver to detect new modals
            if (window.MutationObserver) {
                const observer = new MutationObserver((mutations) => {
                    mutations.forEach((mutation) => {
                        if (mutation.addedNodes.length) {
                            mutation.addedNodes.forEach((node) => {
                                if (node.nodeType === 1) { // Element node
                                    const $node = $(node);
                                    if ($node.is('.ultraguard-modal-overlay') || $node.find('.ultraguard-modal-overlay').length) {
                                        this.discoverModals();
                                    }
                                }
                            });
                        }
                    });
                });

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

        /**
         * Extract all data attributes from trigger
         */
        getTriggerData($trigger) {
            const data = {};
            
            // Get all data-* attributes
            $.each($trigger.data(), (key, value) => {
                // Skip modal-trigger and other reserved attributes
                if (key !== 'modalTrigger' && key !== 'modalClose') {
                    data[key] = value;
                }
            });
            
            // Also get specific attributes
            const attributes = ['id', 'href', 'src', 'title', 'alt', 'value'];
            attributes.forEach(attr => {
                const val = $trigger.attr(attr);
                if (val) data[attr] = val;
            });
            
            return data;
        }

        /**
         * Open a modal with optional data
         */
        open(modalId, data = {}, $trigger = null) {
            const modal = this.modals.get(modalId);
            if (!modal) {
                console.error('Modal not found:', modalId);
                return false;
            }
            
            if (modal.isOpen) return false;

            // Store trigger data
            if ($trigger) {
                modal.$trigger = $trigger;
                modal.triggerData = data;
                
                // Check if we need to load content
                const contentUrl = $trigger.data('content-url') || $trigger.attr('href');
                if (contentUrl && contentUrl !== '#') {
                    this.loadContent(modal, contentUrl, data);
                } else {
                    // Check for inline content
                    const contentSelector = $trigger.data('content-selector');
                    if (contentSelector) {
                        const $content = $(contentSelector);
                        if ($content.length) {
                            this.setContent(modalId, $content.html(), 'body');
                        }
                    }
                }
                
                // Fire trigger-specific event
                $(document).trigger('ultraguard:modal:triggered', {
                    modalId,
                    modal,
                    trigger: $trigger,
                    data
                });
            }

            // Store previous focus
            modal.previousFocus = document.activeElement;

            // Lock body scroll if first modal
            if (this.openModals.length === 0 && this.config.lockBodyScroll) {
                this.lockBodyScroll();
            }

            // Add to open stack
            this.openModals.push(modalId);
            modal.isOpen = true;
            modal.data = { ...modal.data, ...data };

            // Show modal with animation
            modal.$element
                .removeClass('ultraguard-modal-hidden')
                .css('display', 'flex')
                .hide()
                .fadeIn(this.config.animationSpeed, () => {
                    this.setInitialFocus(modal);
                    $(document).trigger('ultraguard:modal:opened', { 
                        modalId, 
                        modal,
                        data 
                    });
                });

            $('body').addClass('ultraguard-modal-open');
            this.updateZIndex();

            return true;
        }

        /**
         * Load content via AJAX
         */
        loadContent(modal, url, data) {
            this.showLoading(modal.id);
            
            $.ajax({
                url: url,
                method: 'GET',
                data: data,
                success: (response) => {
                    this.setContent(modal.id, response, 'body');
                    $(document).trigger('ultraguard:modal:content:loaded', {
                        modalId: modal.id,
                        modal,
                        response
                    });
                },
                error: (xhr, status, error) => {
                    console.error('Error loading modal content:', error);
                    this.setContent(modal.id, 
                        '<div class="ultraguard-alert ultraguard-alert-error">' +
                        '<span class="dashicons dashicons-warning"></span>' +
                        '<div class="ultraguard-alert-content">' +
                        '<strong>Error loading content</strong><br>' +
                        'Please try again or contact support.' +
                        '</div></div>', 
                        'body'
                    );
                }
            });
        }

        /**
         * Close a modal
         */
        close(modalId) {
            const modal = this.modals.get(modalId);
            if (!modal || !modal.isOpen) return false;

            // Hide modal
            modal.$element.fadeOut(this.config.animationSpeed, () => {
                // Remove from stack
                const index = this.openModals.indexOf(modalId);
                if (index > -1) {
                    this.openModals.splice(index, 1);
                }

                modal.isOpen = false;

                // Restore focus
                if (modal.previousFocus) {
                    try {
                        modal.previousFocus.focus();
                    } catch (e) {
                        // Element might not exist anymore
                    }
                    modal.previousFocus = null;
                }

                // Clear temporary data
                modal.$trigger = null;
                modal.triggerData = null;

                // Unlock body if no modals
                if (this.openModals.length === 0) {
                    $('body').removeClass('ultraguard-modal-open');
                    if (this.config.lockBodyScroll) {
                        this.unlockBodyScroll();
                    }
                }

                this.updateZIndex();
                $(document).trigger('ultraguard:modal:closed', { 
                    modalId, 
                    modal 
                });
            });

            return true;
        }

        /**
         * Close top modal
         */
        closeTopModal() {
            if (this.openModals.length > 0) {
                const topModalId = this.openModals[this.openModals.length - 1];
                this.close(topModalId);
            }
        }

        /**
         * Close all modals
         */
        closeAll() {
            [...this.openModals].reverse().forEach(modalId => {
                this.close(modalId);
            });
        }

        /**
         * Check if modal is open
         */
        isOpen(modalId) {
            const modal = this.modals.get(modalId);
            return modal ? modal.isOpen : false;
        }

        /**
         * Get modal instance
         */
        getModal(modalId) {
            return this.modals.get(modalId);
        }

        /**
         * Get all registered modals
         */
        getAllModals() {
            return Array.from(this.modals.values());
        }

        /**
         * Set modal content
         */
        setContent(modalId, content, target = 'body') {
            const modal = this.modals.get(modalId);
            if (!modal) return false;

            switch (target) {
                case 'body':
                    modal.$body.html(content);
                    break;
                case 'header':
                    modal.$header.html(content);
                    break;
                case 'footer':
                    modal.$footer.html(content);
                    break;
                case 'title':
                    modal.$title.html(content);
                    break;
                default:
                    modal.$element.find(target).html(content);
            }

            $(document).trigger('ultraguard:modal:contentChanged', { 
                modalId, 
                target,
                modal 
            });
            
            return true;
        }

        /**
         * Show loading state
         */
        showLoading(modalId, message = 'Loading...') {
            const loadingHtml = `
                <div class="ultraguard-modal-loading">
                    <div class="ultraguard-spinner"></div>
                    <p>${this.escapeHtml(message)}</p>
                </div>
            `;
            return this.setContent(modalId, loadingHtml, 'body');
        }

        /**
         * Lock body scroll
         */
        lockBodyScroll() {
            if (this.bodyScrollLocked) return;

            const $body = $('body');
            const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
            
            this.originalBodyPadding = $body.css('padding-right');
            
            if (scrollbarWidth > 0) {
                $body.css('padding-right', `${scrollbarWidth}px`);
            }
            
            $body.css('overflow', 'hidden');
            this.bodyScrollLocked = true;
        }

        /**
         * Unlock body scroll
         */
        unlockBodyScroll() {
            if (!this.bodyScrollLocked) return;

            $('body').css({
                'overflow': '',
                'padding-right': this.originalBodyPadding || ''
            });
            
            this.bodyScrollLocked = false;
        }

        /**
         * Update z-index for stacking
         */
        updateZIndex() {
            const baseZIndex = 999999;
            this.openModals.forEach((modalId, index) => {
                const modal = this.modals.get(modalId);
                if (modal) {
                    modal.$element.css('z-index', baseZIndex + (index * 10));
                }
            });
        }

        /**
         * Set initial focus
         */
        setInitialFocus(modal) {
            setTimeout(() => {
                const $firstInput = modal.$body.find('input, textarea, select, button').filter(':visible').first();
                const $firstButton = modal.$footer.find('button').filter(':visible').first();
                
                if ($firstInput.length) {
                    $firstInput[0].focus();
                } else if ($firstButton.length) {
                    $firstButton[0].focus();
                } else if (modal.$closeBtn.length) {
                    modal.$closeBtn[0].focus();
                }
            }, 50);
        }

        /**
         * Trap focus within modal
         */
        trapFocus(e, modal) {
            const $focusable = modal.$element.find(
                'a[href], button, input, textarea, select, [tabindex]:not([tabindex="-1"])'
            ).filter(':visible');
            
            if ($focusable.length === 0) return;

            const $first = $focusable.first();
            const $last = $focusable.last();

            if (e.shiftKey) {
                if (document.activeElement === $first[0]) {
                    $last[0].focus();
                    e.preventDefault();
                }
            } else {
                if (document.activeElement === $last[0]) {
                    $first[0].focus();
                    e.preventDefault();
                }
            }
        }

        /**
         * Enhance accessibility
         */
        enhanceAccessibility(modal) {
            const titleId = modal.id + '-title';
            
            modal.$element.attr({
                'role': 'dialog',
                'aria-modal': 'true',
                'aria-labelledby': titleId
            });

            modal.$title.attr('id', titleId);
            
            modal.$closeBtn.attr({
                'aria-label': 'Close modal',
                'title': 'Close (Esc)'
            });
        }

        /**
         * Escape HTML
         */
        escapeHtml(text) {
            const div = document.createElement('div');
            div.textContent = text;
            return div.innerHTML;
        }

        /**
         * Refresh modal list (useful after dynamic content changes)
         */
        refresh() {
            this.discoverModals();
        }
    }

    // Create modal manager instance
    const modalManager = new ModalManager();

    // ==================== Sidebar Component ====================
    window.UltraGuardModals.UltraGuardSidebar = class UltraGuardSidebar {

        constructor() {
            this.$sidebar   = $('.ultraguard-app-sidebar');
            this.$drawer    = this.$sidebar.find('.ultraguard-app-sidebar-drawer');
            this.$toggle    = this.$sidebar.find('.ultraguard-app-sidebar-toggle');
            this.$backdrop  = null;
            this.isOpen     = false;
            this.initialized = false;
            this.init();
        }

        init() {
            if (this.initialized || !this.$sidebar.length) return;
            this.injectBackdrop();
            this.bindEvents();
            this.setInitialActiveStates();
            this.initialized = true;
        }

        injectBackdrop() {
            if (!$('.ug-sidebar-backdrop').length) {
                this.$backdrop = $('<div class="ug-sidebar-backdrop"></div>');
                // Append inside the framework so position:absolute covers
                // only our content area, not the WP admin menu
                const $fw = $('.ultraguard-framework');
                if ($fw.length) {
                    $fw.append(this.$backdrop);
                } else {
                    $('body').append(this.$backdrop);
                }
            } else {
                this.$backdrop = $('.ug-sidebar-backdrop');
            }
        }

        bindEvents() {
            // Hamburger
            this.$toggle.on('click.ugsidebar', (e) => {
                e.preventDefault(); e.stopPropagation();
                this.toggle();
            });

            // Backdrop closes drawer
            $(document).on('click.ugsidebar-backdrop', '.ug-sidebar-backdrop', () => this.close());

            // Escape key
            $(document).on('keydown.ugsidebar', (e) => {
                if (e.key === 'Escape' && this.isOpen) this.close();
            });

            // Parent items: expand/collapse
            this.$sidebar.on('click.ugsidebar',
                '.ultraguard-app-sidebar-item.has-children > .ultraguard-app-sidebar-link',
                (e) => {
                    e.preventDefault();
                    e.stopPropagation();
                    e.stopImmediatePropagation();
                    this.toggleChildren($(e.currentTarget).parent());
                }
            );

            // Child links: set active, close on mobile
            this.$sidebar.on('click.ugsidebar', '.ultraguard-app-sidebar-child-link', (e) => {
                const $link = $(e.currentTarget);
                const href = $link.attr('href');
                if (!href || href === '#') { e.preventDefault(); return; }
                this.setActiveChild($link);
                if (this.isMobile()) this.close();
            });

            // Leaf nav links: close on mobile
            this.$sidebar.on('click.ugsidebar',
                '.ultraguard-app-sidebar-item:not(.has-children) > .ultraguard-app-sidebar-link',
                () => { if (this.isMobile()) setTimeout(() => this.close(), 60); }
            );

            // Resize
            let rt;
            $(window).on('resize.ugsidebar', () => {
                clearTimeout(rt);
                rt = setTimeout(() => { if (!this.isMobile() && this.isOpen) this.close(true); }, 200);
            });
        }

        toggle() { this.isOpen ? this.close() : this.open(); }

        open() {
            if (!this.isMobile()) return;
            this.isOpen = true;
            this.$sidebar.addClass('sidebar-open');
            this.$toggle.attr('aria-expanded', 'true');
            this.setIcon(true);
            $('body').addClass('ultraguard-mobile-nav-open');
        }

        close(force) {
            if (!this.isOpen && !force) return;
            this.isOpen = false;
            this.$sidebar.removeClass('sidebar-open');
            this.$toggle.attr('aria-expanded', 'false');
            this.setIcon(false);
            $('body').removeClass('ultraguard-mobile-nav-open');
        }

        setIcon(open) {
            const $i = this.$toggle.find('.dashicons');
            if (open) {
                $i.removeClass('dashicons-menu-alt3 dashicons-menu').addClass('dashicons-no-alt');
                this.$toggle.attr('aria-label', 'Close navigation');
            } else {
                $i.removeClass('dashicons-no-alt').addClass('dashicons-menu-alt3');
                this.$toggle.attr('aria-label', 'Open navigation');
            }
        }

        toggleChildren($item) {
            const $ch   = $item.find('> .ultraguard-app-sidebar-children');
            const $arr  = $item.find('> .ultraguard-app-sidebar-link .ultraguard-app-sidebar-arrow');
            const open  = !$item.hasClass('expanded');
            if (!this.isMobile()) {
                this.$sidebar.find('.ultraguard-app-sidebar-item.has-children.expanded')
                    .not($item).each((_, el) => this.collapseItem($(el)));
            }
            if (open) {
                $item.addClass('expanded');
                $ch.addClass('expanded').hide().slideDown(220);
                $arr.removeClass('dashicons-arrow-right').addClass('dashicons-arrow-down');
                $item.find('> .ultraguard-app-sidebar-link').attr('aria-expanded', 'true');
            } else {
                this.collapseItem($item);
            }
        }

        collapseItem($item) {
            const $ch  = $item.find('> .ultraguard-app-sidebar-children');
            const $arr = $item.find('> .ultraguard-app-sidebar-link .ultraguard-app-sidebar-arrow');
            $item.removeClass('expanded');
            $ch.removeClass('expanded').slideUp(180);
            $arr.removeClass('dashicons-arrow-down').addClass('dashicons-arrow-right');
            $item.find('> .ultraguard-app-sidebar-link').attr('aria-expanded', 'false');
        }

        setInitialActiveStates() {
            this.$sidebar.find('.ultraguard-app-sidebar-child-link.active').each((_, el) => {
                const $p = $(el).closest('.ultraguard-app-sidebar-item.has-children');
                if ($p.length) {
                    $p.addClass('expanded');
                    $p.find('> .ultraguard-app-sidebar-children').addClass('expanded');
                    $p.find('> .ultraguard-app-sidebar-link .ultraguard-app-sidebar-arrow')
                      .removeClass('dashicons-arrow-right').addClass('dashicons-arrow-down');
                    $p.find('> .ultraguard-app-sidebar-link').attr('aria-expanded', 'true');
                }
            });
        }

        setActiveChild($link) {
            this.$sidebar.find('.ultraguard-app-sidebar-child-link').removeClass('active');
            this.$sidebar.find('.ultraguard-app-sidebar-link').removeClass('active');
            $link.addClass('active');
            $link.closest('.ultraguard-app-sidebar-item')
                 .find('> .ultraguard-app-sidebar-link').addClass('active');
        }

        isMobile() { return window.innerWidth <= 1024; }

        // Legacy compat
        refresh() { this.setInitialActiveStates(); }
        toggleMobileMenu(state) { typeof state === 'boolean' ? (state ? this.open() : this.close()) : this.toggle(); }
    };

    // ==================== Public API ====================
    
    // Initialize modals
    window.UltraGuardModals.initializeModals = function() {
        modalManager.init();
    };

    // Generic modal methods
    window.UltraGuardModals.open = (modalId, data, $trigger) => modalManager.open(modalId, data, $trigger);
    window.UltraGuardModals.close = (modalId) => modalManager.close(modalId);
    window.UltraGuardModals.closeAll = () => modalManager.closeAll();
    window.UltraGuardModals.isOpen = (modalId) => modalManager.isOpen(modalId);
    window.UltraGuardModals.setContent = (modalId, content, target) => modalManager.setContent(modalId, content, target);
    window.UltraGuardModals.showLoading = (modalId, message) => modalManager.showLoading(modalId, message);
    window.UltraGuardModals.getModal = (modalId) => modalManager.getModal(modalId);
    window.UltraGuardModals.getAllModals = () => modalManager.getAllModals();
    window.UltraGuardModals.refresh = () => modalManager.refresh();

    // Auto-initialize on document ready
    $(document).ready(() => {
        window.UltraGuardModals.initializeModals();
    });

})(jQuery);
