jQuery(document).ready(function ($) {
    // Global variable for snippet CodeMirror instance
    var snippetCodeMirrorInstance = null;

    // ===== Toast & Feedback Popover Globals =====
    let currentDisablingCheckbox = null;
    let currentDisablingCard = null;

    // ===== View Mode Management =====
    function setViewMode(mode) {
        // Set data-view attribute on unified container
        $('.switchboard-modules').attr('data-view', mode);

        // Handle grid-4col class
        if (mode === 'grid-4col') {
            $('.switchboard-modules').addClass('grid-4col');
        } else {
            $('.switchboard-modules').removeClass('grid-4col');
        }

        // Remove all view classes from body
        $('body').removeClass('switchboard-view-grid switchboard-view-grid-4col switchboard-view-list-2col switchboard-view-list-3col');

        // Add current view class to body (for controlling sidebar visibility)
        $('body').addClass('switchboard-view-' + mode);

        // Show/hide filter elements based on view
        if (mode === 'grid' || mode === 'grid-4col' || mode === 'list-3col') {
            $('.filter-container').show();
            $('.switchboard-filters').show();
        } else if (mode === 'list-2col') {
            $('.filter-container').show();
            $('.switchboard-filters').hide(); // Hide category filters in 2-col view (sidebar provides navigation)
        }

        // Enable/disable description filter based on view
        // Disable in grid views, enable in list views
        if (mode === 'grid' || mode === 'grid-4col') {
            $('#desc-toggle-btn').prop('disabled', true).css('opacity', '0.5').css('cursor', 'not-allowed');
            $('#desc-toggle-btn').attr('title', 'Description filter not available in grid view');

            // Force show descriptions in grid views (remove hidden/truncated states)
            $('.module-description, .module-list-desc').removeClass('desc-truncated desc-hidden');
            $('.module-description-icon').hide();
        } else {
            $('#desc-toggle-btn').prop('disabled', false).css('opacity', '1').css('cursor', 'pointer');

            // Restore description state in list views
            const descState = $('#desc-toggle-btn').data('state');
            $('.module-description, .module-list-desc').removeClass('desc-truncated desc-hidden');

            if (descState === 'truncated') {
                $('.module-description, .module-list-desc').addClass('desc-truncated');
                $('#desc-toggle-btn').attr('title', 'Show full description');
                $('.module-description-icon').show();
            } else if (descState === 'hidden') {
                $('.module-description, .module-list-desc').addClass('desc-hidden');
                $('#desc-toggle-btn').attr('title', 'Show description');
                $('.module-description-icon').show();
            } else {
                $('#desc-toggle-btn').attr('title', 'Truncate description');
                $('.module-description-icon').hide();
            }
        }

        // Sync sidebar with current filter for 2-col view
        if (mode === 'list-2col') {
            const currentCategory = $('.filter-btn.active').data('category') || 'all';
            $('.category-item').removeClass('active');
            $(`.category-item[data-category="${currentCategory}"]`).addClass('active');
        }

        // Update button states
        $('.view-btn').removeClass('active');
        $(`.view-btn[data-view="${mode}"]`).addClass('active');

        // Save to localStorage
        localStorage.setItem('switchboard-view-mode', mode);

        // Update URL
        updateUrlParams({ view: mode });

        // Reapply filters for current view
        applyFilters();
    }

    function initViewMode() {
        const urlParams = getUrlParams();
        const savedMode = urlParams.view || localStorage.getItem('switchboard-view-mode') || 'list-2col';
        setViewMode(savedMode);
    }

    // Helper function to serialize form data from the unified view
    // Since we now have a single HTML structure, this is simpler
    function serializeVisibleViewCheckboxes() {
        // Get all checkboxes from the unified modules container
        const checkboxes = $('.switchboard-modules .module-checkbox');

        // Get the nonce from the form
        const nonce = $('#switchboard-form input[name="nonce"]').val();

        // Build the data string with only checked boxes
        let data = 'nonce=' + encodeURIComponent(nonce);
        checkboxes.filter(':checked').each(function() {
            data += '&active_modules[]=' + encodeURIComponent($(this).val());
        });

        return data;
    }

    // View toggle click handler
    $('.view-btn').on('click', function() {
        const mode = $(this).data('view');
        setViewMode(mode);
    });

    // Category sidebar click handler (for 2-col list view)
    // Exclude category items inside settings panels (#categories-list)
    $(document).on('click', '.category-item:not(#categories-list .category-item)', function() {
        const category = $(this).data('category');
        $('.category-item:not(#categories-list .category-item)').removeClass('active');
        $(this).addClass('active');

        // Update filter button state to match
        $('.filter-btn').removeClass('active');
        $(`.filter-btn[data-category="${category}"]`).addClass('active');

        // Apply filters
        updateUrlParams({ category: category === 'all' ? '' : category });
        applyFilters();
    });

    function showToast(message, type = 'success', duration = 3000) {
        const toast = $('#sb-toast');
        const toastIcon = $('#sb-toast-icon');
        const toastMessage = $('#sb-toast-message');

        // Tailwind-style: light bg, border, dark text
        if (type === 'enabled') {
            toastIcon.html('<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="16" height="16"><path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5" /></svg>');
            toastMessage.text(message + ' enabled');
            // Emerald: light bg (primary-50), border (primary-200), text (primary-800)
            toast.css({
                'background': 'var(--primary-50)',
                'color': 'var(--primary-800)',
                'border': '1px solid var(--primary-200)'
            });
        } else if (type === 'disabled') {
            toastIcon.html('<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="16" height="16"><circle cx="12" cy="12" r="9" /></svg>');
            toastMessage.text(message + ' disabled');
            // Gray: light bg (gray-50), border (gray-300), text (gray-700)
            toast.css({
                'background': 'var(--gray-50)',
                'color': 'var(--gray-700)',
                'border': '1px solid var(--gray-300)'
            });
        } else {
            toastIcon.html('<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="16" height="16"><path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5" /></svg>');
            toastMessage.text(message);
            // Default to Emerald
            toast.css({
                'background': 'var(--primary-50)',
                'color': 'var(--primary-800)',
                'border': '1px solid var(--primary-200)'
            });
        }

        toast.css('display', 'block');

        setTimeout(function() {
            toast.fadeOut(250);
        }, duration);
    }

    function showFeedbackPopover(checkbox, card, moduleName) {
        const popover = $('#sb-feedback-popover');
        const moduleNameSpan = $('#sb-feedback-module-name');

        // Store reference
        currentDisablingCheckbox = checkbox;
        currentDisablingCard = card;

        // Set module name
        moduleNameSpan.text(moduleName);

        // Show popover first to get its dimensions
        popover.css('display', 'block');

        // Use getBoundingClientRect() for viewport-relative coordinates (required for position: fixed)
        const cardRect = card[0].getBoundingClientRect();
        const popoverWidth = popover.outerWidth();
        const popoverHeight = popover.outerHeight();
        const windowHeight = $(window).height();
        const windowWidth = $(window).width();

        // Calculate center position (viewport-relative for position: fixed)
        let top = cardRect.top + (cardRect.height / 2) - (popoverHeight / 2);
        let left = cardRect.left + (cardRect.width / 2) - (popoverWidth / 2);

        // Adjust if popover goes off-screen vertically
        const minTop = 20;
        const maxTop = windowHeight - popoverHeight - 20;

        if (top < minTop) {
            top = minTop;
        } else if (top > maxTop) {
            top = maxTop;
        }

        // Adjust if popover goes off-screen horizontally
        const minLeft = 20;
        const maxLeft = windowWidth - popoverWidth - 20;

        if (left < minLeft) {
            left = minLeft;
        } else if (left > maxLeft) {
            left = maxLeft;
        }

        // Apply position
        popover.css({
            'top': top + 'px',
            'left': left + 'px'
        });
    }

    function hideFeedbackPopover() {
        $('#sb-feedback-popover').fadeOut(200);
        // Hide helper link badge
        $('#sb-helper-link-badge').fadeOut(200);
    }

    function showHelperLinkBadge(reason, card) {
        // Remove any existing helper link wrapper in this card
        card.find('.sb-toggle-link-wrapper').each(function() {
            const toggle = $(this).find('.module-toggle');
            $(this).replaceWith(toggle);
        });
        card.find('.sb-inline-helper-link').remove();

        let linkHref = '';
        let linkText = '';

        // Set link based on reason - only show for bug, missing-feature, other
        if (reason === 'bug') {
            linkHref = 'mailto:support@wpswitchboard.com?subject=Bug/Error Report';
            linkText = 'Report issue';
        } else if (reason === 'missing-feature') {
            linkHref = 'https://wpswitchboard.com/ideas';
            linkText = 'Request feature';
        } else if (reason === 'other') {
            linkHref = 'mailto:support@wpswitchboard.com?subject=Feedback';
            linkText = 'Contact us';
        } else {
            return; // No link needed for done and testing
        }

        // Find the toggle label
        const toggleLabel = card.find('.module-toggle');
        if (toggleLabel.length) {
            // Create wrapper to keep toggle + link together on left side
            const wrapper = $('<div>', {
                'class': 'sb-toggle-link-wrapper',
                'style': 'display: flex; align-items: center; gap: 12px;'
            });

            // Create the helper link
            const helperLink = $('<a>', {
                'class': 'sb-inline-helper-link',
                'href': linkHref,
                'target': linkHref.startsWith('http') ? '_blank' : '',
                'style': 'color: hsl(217, 91%, 50%); text-decoration: none; font-size: 11px; font-weight: 500; white-space: nowrap;',
                'text': linkText
            });

            // Wrap toggle and add link
            toggleLabel.wrap(wrapper);
            toggleLabel.after(helperLink);

            // Fade in animation
            helperLink.css('opacity', '0').animate({'opacity': '1'}, 300);

            // Auto-remove after 8 seconds
            setTimeout(function() {
                helperLink.fadeOut(300, function() {
                    // Unwrap and remove
                    const currentWrapper = card.find('.sb-toggle-link-wrapper');
                    if (currentWrapper.length) {
                        const toggle = currentWrapper.find('.module-toggle');
                        currentWrapper.replaceWith(toggle);
                    }
                });
            }, 8000);
        }
    }

    function confirmDisable(reason, moduleName, reason_details) {
        if (!currentDisablingCheckbox || !currentDisablingCard) return;

        const checkbox = currentDisablingCheckbox;
        const card = currentDisablingCard;
        const settingsBtn = card.find('.module-settings');
        const hasSettings = card.data('has-settings');

        // UNCHECK the checkbox first!
        checkbox.prop('checked', false);

        // Update UI
        card.removeClass('enabled');
        card.attr('data-status', 'inactive');
        card.data('status', 'inactive');
        settingsBtn.hide();

        // No need to sync views anymore - we have unified HTML structure

        // Update counts
        updateStatusCounts();
        updateWhereToFindTooltip(card, false);

        // Save via AJAX - only serialize visible view to prevent duplicates
        const formData = serializeVisibleViewCheckboxes();
        let ajaxData = formData + '&action=switchboard_save_modules&disable_reason=' + encodeURIComponent(reason) + '&module_name=' + encodeURIComponent(moduleName);

        // Add reason_details if provided
        if (reason_details) {
            ajaxData += '&disable_reason_details=' + encodeURIComponent(reason_details);
        }

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: ajaxData,
            success: function(response) {
                if (response.success) {
                    card.css('box-shadow', '0 0 0 3px rgba(var(--primary-600-rgb), 0.3)');
                    setTimeout(function() {
                        card.css('box-shadow', '');
                    }, 500);

                    // Show toast
                    showToast(moduleName, 'disabled');
                }
            },
            error: function() {
                // Revert on error
                checkbox.prop('checked', true);
                card.addClass('enabled');
                card.attr('data-status', 'active');
                if (hasSettings) {
                    settingsBtn.show();
                }
                alert('Failed to save. Please try again.');
            }
        });

        // Hide popover
        hideFeedbackPopover();

        // Clear references
        currentDisablingCheckbox = null;
        currentDisablingCard = null;
    }

    function cancelDisable() {
        if (currentDisablingCheckbox) {
            currentDisablingCheckbox.prop('checked', true);
        }
        hideFeedbackPopover();
        currentDisablingCheckbox = null;
        currentDisablingCard = null;
    }

    // URL Parameter Management
    function getUrlParams() {
        const params = new URLSearchParams(window.location.search);
        return {
            search: params.get('search') || '',
            category: params.get('category') || 'all',
            status: params.get('status') || 'all',
            mode: params.get('mode') || 'all',
            sort: params.get('sort') || 'default'
        };
    }

    function updateUrlParams(updates) {
        const params = new URLSearchParams(window.location.search);

        Object.keys(updates).forEach(key => {
            if (updates[key] && updates[key] !== 'all' && updates[key] !== 'default' && updates[key] !== '') {
                params.set(key, updates[key]);
            } else {
                params.delete(key);
            }
        });

        const newUrl = window.location.pathname + (params.toString() ? '?' + params.toString() : '');
        window.history.replaceState({}, '', newUrl);
    }

    // Search functionality
    const searchInput = $('#switchboard-search');
    const searchClear = $('#search-clear');
    const resultsInfo = $('#results-info');
    const moduleCards = $('.module-card');

    // Restore state from URL
    const urlParams = getUrlParams();

    // Keyboard shortcut: Cmd+K (Mac) or Ctrl+K (Windows)
    $(document).on('keydown', function (e) {
        // Check for Cmd+K (Mac) or Ctrl+K (Windows)
        if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
            e.preventDefault();
            searchInput.addClass('highlight-pulse');
            searchInput.focus().select();

            // Remove the class after animation completes
            setTimeout(function () {
                searchInput.removeClass('highlight-pulse');
            }, 600);
        }
    });

    searchInput.on('input', function () {
        const query = $(this).val().toLowerCase();

        // Update URL
        updateUrlParams({ search: query });

        if (query.length > 0) {
            searchClear.show();
            // Keep category filter active during search (searching within current category)
        } else {
            searchClear.hide();
            // Don't hide resultsInfo here - let applyFilters() handle it
        }

        // Always apply all filters together
        applyFilters();
    });

    searchClear.on('click', function () {
        searchInput.val('');
        updateUrlParams({ search: '' });
        searchInput.trigger('input');
    });

    // Clear all filters button (in empty state)
    $(document).on('click', '#clear-all-filters', function () {
        // Clear search
        searchInput.val('');
        searchClear.hide();

        // Reset to "All" category
        $('.filter-btn').removeClass('active');
        $('.filter-btn[data-category="all"]').addClass('active');

        // Reset status filter to "all"
        $('#status-filter').val('all');

        // Reset beta mode to "all"
        $('#beta-mode-filter').val('all');

        // Update URL
        updateUrlParams({
            search: '',
            category: 'all',
            status: 'all',
            beta: 'all'
        });

        // Apply filters to show all modules
        applyFilters();
    });

    // Restore filters from URL
    if (urlParams.category && urlParams.category !== 'featured') {
        $('.filter-btn[data-category="' + urlParams.category + '"]').addClass('active');
        $('.filter-btn[data-category="featured"]').removeClass('active');
        $('.category-item[data-category="' + urlParams.category + '"]').addClass('active');
        $('.category-item[data-category="featured"]').removeClass('active');
    }
    if (urlParams.status && urlParams.status !== 'all') {
        // Update status button group active state from URL
        $('.status-filter-btn').removeClass('active');
        $('.status-filter-btn[data-status="' + urlParams.status + '"]').addClass('active');
        $('.status-clear-btn').show();
    }
    if (urlParams.mode && urlParams.mode === 'beta') {
        $('#beta-mode-toggle').addClass('active');
        $('.status-clear-btn').show();
    }
    // Set description state - default to 'truncated' if not in URL
    const descState = urlParams.desc || 'truncated';
    if (descState === 'truncated' || descState === 'hidden') {
        $('#desc-toggle-btn').data('state', descState);
        $('#desc-toggle-btn').attr('data-state', descState);

        $('.module-description, .module-list-desc').removeClass('desc-truncated desc-hidden');
        if (descState === 'truncated') {
            $('.module-description, .module-list-desc').addClass('desc-truncated');
            $('#desc-toggle-btn').attr('title', 'Hide description');
            // Update icon to 2 lines
            $('#desc-toggle-btn').html('<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="4" width="12" height="2" rx="1" fill="currentColor"/><rect x="2" y="10" width="8" height="2" rx="1" fill="currentColor"/></svg>');
        } else if (descState === 'hidden') {
            $('.module-description, .module-list-desc').addClass('desc-hidden');
            $('#desc-toggle-btn').attr('title', 'Show description');
            // Update icon to 1 line
            $('#desc-toggle-btn').html('<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="7" width="12" height="2" rx="1" fill="currentColor"/></svg>');
        }

        // Show description icon when descriptions are truncated or hidden
        $('.module-description-icon').show();

        // Update URL with default state
        if (!urlParams.desc) {
            updateUrlParams({ desc: descState });
        }
    } else {
        // Hide description icon when showing full descriptions
        $('.module-description-icon').hide();
    }

    // Set use cases state - prioritize URL, then localStorage, default to 'visible'
    const usecasesState = urlParams.usecases || localStorage.getItem('switchboard-usecases') || 'visible';
    $('#usecases-toggle-btn').data('state', usecasesState);
    $('#usecases-toggle-btn').attr('data-state', usecasesState);
    if (usecasesState === 'hidden') {
        $('.module-usecases').hide();
        $('#usecases-toggle-btn').attr('title', 'Show use cases');
    } else {
        $('#usecases-toggle-btn').attr('title', 'Hide use cases');
    }

    // Save to localStorage if not in URL
    if (!urlParams.usecases) {
        localStorage.setItem('switchboard-usecases', usecasesState);
    }

    // Update sort options based on initial status (must be before updateSortOptions is defined)
    // Will be called after function definition below

    // Apply filters on load (default to featured category) - only on modules page
    if (searchInput.length > 0) {
        applyFilters();

        // Restore search from URL AFTER filters are applied
        if (urlParams.search) {
            searchInput.val(urlParams.search);
            searchInput.trigger('input');
        }
    }

    // Category filters
    $('.filter-btn').on('click', function () {
        const category = $(this).data('category');

        $('.filter-btn').removeClass('active');
        $(this).addClass('active');

        // Sync with sidebar categories (for 2-col list view)
        $('.category-item').removeClass('active');
        $(`.category-item[data-category="${category}"]`).addClass('active');

        // Clear search when changing category
        searchInput.val('');
        searchClear.hide();
        resultsInfo.hide();

        // Update URL (clear search)
        updateUrlParams({ category: category, search: '' });

        applyFilters();
    });

    // Favorite heart button click handler
    $('.favorite-heart-btn').on('click', function(e) {
        e.preventDefault();
        e.stopPropagation();

        const $btn = $(this);
        const $card = $btn.closest('.module-card');
        const moduleKey = $btn.data('module');

        // Disable button during request
        $btn.prop('disabled', true);

        $.ajax({
            url: switchboardSettings.ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_toggle_favorite',
                nonce: switchboardSettings.nonce,
                module: moduleKey
            },
            success: function(response) {
                if (response.success) {
                    // Update data attribute
                    $card.attr('data-favorited', response.data.favorited ? '1' : '0');

                    // Update favorites count in filter buttons
                    $('#favorites-filter-btn .sb-filter-count').text('(' + response.data.count + ')');
                    $('#favorites-sidebar-btn .category-count').text('(' + response.data.count + ')');

                    // Update button title
                    $btn.attr('title', response.data.favorited ? 'Remove from favorites' : 'Add to favorites');

                    // If we're viewing favorites category, reapply filters to hide/show items
                    const currentCategory = $('.filter-btn.active').data('category');
                    if (currentCategory === 'favorites') {
                        applyFilters();
                    }
                }
            },
            error: function() {
                alert('Failed to update favorite. Please try again.');
            },
            complete: function() {
                $btn.prop('disabled', false);
            }
        });
    });

    // Function to update sort options visibility based on status filter
    function updateSortOptions(status) {
        const $activeFirstBtn = $('.sort-filter-btn[data-sort="active-first"]');
        const $inactiveFirstBtn = $('.sort-filter-btn[data-sort="inactive-first"]');
        const currentSort = $('.sort-filter-btn.active').data('sort');

        if (status === 'active') {
            // Hide both status sorts (all modules shown are active)
            $activeFirstBtn.hide();
            $inactiveFirstBtn.hide();
            // If currently sorted by status, switch to A-Z
            if (currentSort === 'active-first' || currentSort === 'inactive-first') {
                $('.sort-filter-btn').removeClass('active');
                $('.sort-filter-btn[data-sort="name-asc"]').addClass('active');
                sortModules('name-asc');
            }
        } else if (status === 'inactive') {
            // Hide both status sorts (all modules shown are inactive)
            $activeFirstBtn.hide();
            $inactiveFirstBtn.hide();
            // If currently sorted by status, switch to A-Z
            if (currentSort === 'active-first' || currentSort === 'inactive-first') {
                $('.sort-filter-btn').removeClass('active');
                $('.sort-filter-btn[data-sort="name-asc"]').addClass('active');
                sortModules('name-asc');
            }
        } else {
            // Show both options for "All" view (status sorting is meaningful)
            $activeFirstBtn.show();
            $inactiveFirstBtn.show();
        }
    }

    // Status filter button group (mutually exclusive with beta)
    $('.status-filter-btn').on('click', function () {
        const selectedStatus = $(this).data('status');

        // Update active state - clear all filters including beta
        $('.status-filter-btn').removeClass('active');
        $('#beta-mode-toggle').removeClass('active');
        $(this).addClass('active');

        // Show clear button
        $('.status-clear-btn').show();

        // Update sort options based on new status
        updateSortOptions(selectedStatus);

        // Update URL
        updateUrlParams({ status: selectedStatus, mode: 'all' });

        applyFilters();
    });

    // Status clear button
    $('.status-clear-btn').on('click', function () {
        // Clear all status filters including beta
        $('.status-filter-btn').removeClass('active');
        $('#beta-mode-toggle').removeClass('active');
        $(this).hide();

        // Reset to showing all
        updateSortOptions('all');

        // Update URL
        updateUrlParams({ status: 'all', mode: 'all' });

        applyFilters();
    });

    // Description toggle button - cycles through 3 states
    $('#desc-toggle-btn').on('click', function () {
        const currentState = $(this).data('state');
        let nextState;
        let nextTitle;

        // Cycle through: full → truncated → hidden → full
        if (currentState === 'full') {
            nextState = 'truncated';
            nextTitle = 'Truncate description';
        } else if (currentState === 'truncated') {
            nextState = 'hidden';
            nextTitle = 'Hide description';
        } else {
            nextState = 'full';
            nextTitle = 'Show description';
        }

        // Update button state
        $(this).data('state', nextState);
        $(this).attr('data-state', nextState);
        $(this).attr('title', nextTitle);

        // Update icon based on state
        if (nextState === 'full') {
            // 3 lines - full description
            $(this).html('<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="3" width="12" height="2" rx="1" fill="currentColor"/><rect x="2" y="7" width="12" height="2" rx="1" fill="currentColor"/><rect x="2" y="11" width="8" height="2" rx="1" fill="currentColor"/></svg>');
        } else if (nextState === 'truncated') {
            // 2 lines - truncated description
            $(this).html('<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="4" width="12" height="2" rx="1" fill="currentColor"/><rect x="2" y="10" width="8" height="2" rx="1" fill="currentColor"/></svg>');
        } else {
            // 1 line - hidden description
            $(this).html('<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="7" width="12" height="2" rx="1" fill="currentColor"/></svg>');
        }

        // Apply description state to all module descriptions
        $('.module-description, .module-list-desc').removeClass('desc-truncated desc-hidden');

        if (nextState === 'truncated') {
            $('.module-description, .module-list-desc').addClass('desc-truncated');
        } else if (nextState === 'hidden') {
            $('.module-description, .module-list-desc').addClass('desc-hidden');
        }

        // Show/hide description icon based on state
        if (nextState === 'full') {
            // Hide description icon when showing full descriptions
            $('.module-description-icon').hide();
        } else {
            // Show description icon when descriptions are truncated or hidden
            $('.module-description-icon').show();
        }

        // Update URL
        updateUrlParams({ desc: nextState });
    });

    // Use cases toggle button - toggle visibility
    $('#usecases-toggle-btn').on('click', function () {
        const currentState = $(this).data('state');
        let nextState;
        let nextTitle;

        // Toggle: visible ↔ hidden
        if (currentState === 'visible') {
            nextState = 'hidden';
            nextTitle = 'Show use cases';
        } else {
            nextState = 'visible';
            nextTitle = 'Hide use cases';
        }

        // Update button state
        $(this).data('state', nextState);
        $(this).attr('data-state', nextState);
        $(this).attr('title', nextTitle);

        // Toggle use cases visibility
        if (nextState === 'hidden') {
            $('.module-usecases').hide();
        } else {
            $('.module-usecases').show();
        }

        // Save to localStorage
        localStorage.setItem('switchboard-usecases', nextState);

        // Update URL
        updateUrlParams({ usecases: nextState });
    });

    // Beta mode toggle (mutually exclusive with active/inactive)
    $('#beta-mode-toggle').on('click', function () {
        const wasActive = $(this).hasClass('active');

        // Clear all status filters
        $('.status-filter-btn').removeClass('active');

        // Toggle beta
        if (wasActive) {
            $(this).removeClass('active');
            $('.status-clear-btn').hide();
            updateUrlParams({ mode: 'all', status: 'all' });
        } else {
            $(this).addClass('active');
            $('.status-clear-btn').show();
            updateUrlParams({ mode: 'beta', status: 'all' });
        }

        applyFilters();
    });

    // Initialize sort options visibility based on current status filter
    const initialStatus = $('.status-filter-btn.active').data('status') || 'all';
    updateSortOptions(initialStatus);

    function applyFilters() {
        // Only run on modules page where searchInput exists
        if (searchInput.length === 0) {
            return;
        }

        const category = $('.filter-btn.active').data('category') || 'featured';
        const status = $('.status-filter-btn.active').data('status') || 'all';
        const betaMode = $('#beta-mode-toggle').hasClass('active') ? 'beta' : 'all';
        const searchQuery = searchInput.val().toLowerCase().trim().replace(/-/g, ' ');
        let visibleCount = 0;

        // Collect cards with their relevance scores
        const cardData = [];

        // Get all module cards from the unified view
        const items = $('.switchboard-modules .module-card');

        items.each(function () {
            const item = $(this);
            const itemCategory = item.data('category');
            const itemStatus = item.data('status');
            const itemBeta = item.data('beta');
            const itemFeatured = item.data('featured');
            const searchData = item.data('search');

            // Check all filters
            // Always respect category filter (search within current category)
            let showCategory = true;
            if (category === 'all') {
                // Show all modules (search globally)
                showCategory = true;
            } else if (category === 'featured') {
                showCategory = (itemFeatured === 1);
            } else if (category === 'favorites') {
                // Show only favorited modules
                showCategory = (item.data('favorited') == 1);
            } else {
                // Show only modules in current category
                showCategory = (itemCategory === category);
            }

            // Handle status filters (all, active, inactive)
            let showStatus = (status === 'all' || itemStatus === status);

            let showBeta = (betaMode === 'all' || itemBeta === 1);

            // Check if all words in search query exist in searchData
            let showSearch = true;
            let relevanceScore = 0;

            if (searchQuery.length > 0) {
                const queryWords = searchQuery.split(' ').filter(word => word.length > 0);
                showSearch = queryWords.every(word => searchData.includes(word));

                // Calculate relevance score for matched results
                if (showSearch) {
                    const moduleName = (item.find('.module-name').text() || '').toLowerCase().replace(/-/g, ' ');
                    const moduleDesc = (item.find('.module-description').text() || '').toLowerCase().replace(/-/g, ' ');

                    // Exact match in name (100 points)
                    if (moduleName === searchQuery) {
                        relevanceScore += 100;
                    }
                    // Name starts with query (90 points)
                    else if (moduleName.indexOf(searchQuery) === 0) {
                        relevanceScore += 90;
                    }
                    // Exact phrase in name (80 points)
                    else if (moduleName.indexOf(searchQuery) !== -1) {
                        relevanceScore += 80;
                    }

                    // All words in name (70 points)
                    if (queryWords.length > 1 && queryWords.every(word => moduleName.includes(word))) {
                        relevanceScore += 70;
                    }

                    // Exact phrase in description (60 points)
                    if (moduleDesc.indexOf(searchQuery) !== -1) {
                        relevanceScore += 60;
                    }

                    // Exact phrase in tags (50 points)
                    if (searchData.indexOf(searchQuery) !== -1) {
                        relevanceScore += 50;
                    }

                    // All words in description (30 points)
                    if (queryWords.length > 1 && queryWords.every(word => moduleDesc.includes(word))) {
                        relevanceScore += 30;
                    }

                    // Word count bonus (5 points per matching word)
                    queryWords.forEach(word => {
                        if (searchData.includes(word)) {
                            relevanceScore += 5;
                        }
                    });
                }
            }

            const visible = showCategory && showStatus && showBeta && showSearch;

            cardData.push({
                card: item,
                visible: visible,
                relevanceScore: relevanceScore
            });
        });

        // Sort by relevance score (highest first) when searching
        if (searchQuery.length > 0) {
            cardData.sort((a, b) => b.relevanceScore - a.relevanceScore);
        }

        // Reorder items in DOM and show/hide based on filters
        const container = $('.switchboard-modules');
        cardData.forEach(item => {
            item.card.detach();
            container.append(item.card);

            if (item.visible) {
                item.card.show();
                if (switchboardSettings.is_pro || item.card.data('pro-locked') !== 1) {
                    visibleCount++;
                }
            } else {
                item.card.hide();
            }
        });

        // Update results info and empty state
        const emptyState = $('#empty-state');
        const modulesGrid = $('#modules-grid');

        if (visibleCount === 0) {
            // Show empty state, hide modules grid
            emptyState.show();
            modulesGrid.hide();
        } else {
            // Hide empty state, show modules grid
            emptyState.hide();
            modulesGrid.show();
        }

        // Always update and show results info
        if (searchQuery.length > 0) {
            // Build context-aware search results message
            let categoryContext = '';
            if (category !== 'all' && category !== 'featured' && category !== 'favorites') {
                // Show category name with capital first letter
                categoryContext = ' in ' + category.charAt(0).toUpperCase() + category.slice(1);
            } else if (category === 'favorites') {
                categoryContext = ' in Favorites';
            } else if (category === 'featured') {
                categoryContext = ' in Featured';
            }
            resultsInfo.text('Showing ' + visibleCount + ' results for "' + searchQuery + '"' + categoryContext).show();
        } else {
            // Show count with filter context
            const totalModules = switchboardSettings.is_pro ? $('.switchboard-modules .module-card').length : $('.switchboard-modules .module-card:not([data-pro-locked="1"])').length;
            let filterText = '';

            // Determine filter context
            if (betaMode === 'beta') {
                filterText = ' beta';
            } else if (status === 'active') {
                filterText = ' active';
            } else if (status === 'inactive') {
                filterText = ' inactive';
            }

            resultsInfo.text('Showing ' + visibleCount + ' of ' + totalModules + filterText + ' modules').show();
        }

        // Hide bulk action buttons (removed for safety - needs more validation)
        $('#enable-all-visible').hide();
        $('#disable-all-visible').hide();
    }

    // Enable All Visible functionality (disabled - needs more validation)
    $('#enable-all-visible').on('click', function () {
        alert('Bulk actions are temporarily disabled for safety. Enable modules individually.');
    });

    // Disable All Visible functionality (disabled - needs more validation)
    $('#disable-all-visible').on('click', function () {
        alert('Bulk actions are temporarily disabled for safety. Disable modules individually.');
    });

    // Function to update status counts in real-time (client-side, no server query)
    function updateStatusCounts() {
        // Exclude pro-locked modules from counts in free version
        const excludeLocked = !switchboardSettings.is_pro ? ':not([data-pro-locked="1"])' : '';
        const activeCount = $('.switchboard-modules .module-card[data-status="active"]' + excludeLocked).length;
        const inactiveCount = $('.switchboard-modules .module-card[data-status="inactive"]' + excludeLocked).length;
        const totalCount = activeCount + inactiveCount;

        // Update counts in each status filter button
        $('.status-filter-btn[data-status="all"] .status-count').text('(' + totalCount + ')');
        $('.status-filter-btn[data-status="active"] .status-count').text('(' + activeCount + ')');
        $('.status-filter-btn[data-status="inactive"] .status-count').text('(' + inactiveCount + ')');
    }

    // Function to update WhereToFind tooltip when module is toggled
    function updateWhereToFindTooltip(card, isEnabled) {
        const wtfButton = card.find('.module-wheretofind');
        if (!wtfButton.length) return; // No WhereToFind button on this card

        // Get WhereToFind data from button attributes
        const wtfUrl = wtfButton.attr('data-wtf-url');
        const wtfLocation = wtfButton.attr('data-wtf-location');
        const wtfNewTab = wtfButton.attr('data-wtf-newtab') === '1';

        // Only proceed if there's a URL (not empty and not just homepage)
        if (!wtfUrl || wtfUrl === '' || wtfUrl === '/') return;

        // Get the current tooltip HTML
        let tooltipHtml = wtfButton.attr('data-tooltip-html');
        if (!tooltipHtml) return;

        // Parse the tooltip HTML
        const tempDiv = $('<div>').html(tooltipHtml);
        const linkBtn = tempDiv.find('.wtf-link-btn');
        const disabledMsg = tempDiv.find('span').filter(function() {
            return $(this).text().includes('Enable module to access');
        });
        // Find the content div (the second div, which contains the actual content)
        const wtfContent = tempDiv.find('.tooltip-item');

        if (isEnabled) {
            // Module just enabled - rebuild and show the link, remove "Enable module" message
            disabledMsg.remove();

            // If link doesn't exist, rebuild it from data attributes
            if (linkBtn.length === 0 && wtfContent.length) {
                // Build the full URL
                let fullUrl = wtfUrl;
                if (wtfUrl.indexOf('admin.php') === 0) {
                    // Admin URL - prepend admin_url
                    fullUrl = ajaxurl.replace('/admin-ajax.php', '/' + wtfUrl);
                } else if (wtfUrl.indexOf('/') === 0) {
                    // Relative URL - prepend home URL (extract from current page)
                    const homeUrl = window.location.origin;
                    fullUrl = homeUrl + wtfUrl;
                }

                // Create the link
                const target = wtfNewTab ? '_blank' : '_self';
                const linkText = 'Go to ' + wtfLocation;
                const linkHtml = '<a href="' + fullUrl + '" target="' + target + '" class="wtf-link-btn" style="color:var(--primary-500);text-decoration:none;font-size:13px;font-weight:500;margin-top:8px;display:inline-block;border-bottom:1px solid transparent;transition:all 0.2s ease;">' + linkText + '</a>';
                wtfContent.append(linkHtml);
            }
        } else {
            // Module just disabled - remove the link, add "Enable module" message
            linkBtn.remove();

            // Add disabled message if it doesn't exist
            if (disabledMsg.length === 0 && wtfContent.length) {
                wtfContent.append('<span style="display:block;margin-top:8px;font-size:12px;color:var(--gray-400);font-style:italic;">Enable module to access this page</span>');
            }
        }

        // Update the tooltip HTML
        wtfButton.attr('data-tooltip-html', tempDiv.html());

        // If tooltip is currently visible for this button, refresh it
        const $globalTooltip = $('.switchboard-tooltip');
        if ($globalTooltip.hasClass('visible') && $globalTooltip.is(':hover, :focus-within')) {
            // Re-trigger the tooltip to update position and content
            $globalTooltip.html(tempDiv.html());

            // Recalculate position
            const btnRect = wtfButton[0].getBoundingClientRect();
            const tooltipRect = $globalTooltip[0].getBoundingClientRect();

            let left = btnRect.left + (btnRect.width / 2) - (tooltipRect.width / 2);
            let top = btnRect.top - tooltipRect.height - 10;

            // Keep tooltip on screen
            if (left < 10) left = 10;
            if (left + tooltipRect.width > window.innerWidth - 10) {
                left = window.innerWidth - tooltipRect.width - 10;
            }
            if (top < 10) {
                top = btnRect.bottom + 10;
            }

            $globalTooltip.css({
                left: left + 'px',
                top: top + 'px'
            });
        }
    }

    // Toggle functionality with AJAX auto-save
    $('.module-checkbox').on('change', function () {
        const checkbox = $(this);
        const card = checkbox.closest('.module-card');
        const settingsBtn = card.find('.module-settings');
        const hasSettings = card.data('has-settings');
        const hasAdminPage = card.data('has-admin-page');
        const isChecked = checkbox.is(':checked');
        const moduleName = card.find('.module-name').text().trim();

        // If DISABLING, show feedback popover (unless feedback collection is disabled)
        if (!isChecked) {
            // Check if user has disabled feedback collection
            if (!switchboardSettings.collect_feedback) {
                // Just disable without feedback - proceed with normal disable flow below
            } else {
                // Prevent default disable, show popover
                checkbox.prop('checked', true);
                showFeedbackPopover(checkbox, card, moduleName);
                return;
            }
        }

        // If ENABLING, proceed normally
        card.addClass('enabled');
        card.attr('data-status', 'active');
        card.data('status', 'active');
        // Show settings button if module has settings OR has a dedicated admin page
        if (hasSettings || hasAdminPage) {
            settingsBtn.show();
        }

        // No need to sync views anymore - we have unified HTML structure

        // Update counts in real-time
        updateStatusCounts();

        // Update WhereToFind tooltip if it exists
        updateWhereToFindTooltip(card, isChecked);

        // Save via AJAX - only serialize visible view to prevent duplicates
        const formData = serializeVisibleViewCheckboxes();

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: formData + '&action=switchboard_save_modules',
            success: function (response) {
                if (response.success) {
                    // Show brief success indicator
                    card.css('box-shadow', '0 0 0 3px rgba(var(--primary-600-rgb), 0.3)');
                    setTimeout(function () {
                        card.css('box-shadow', '');
                    }, 500);

                    // Show toast
                    showToast(moduleName, 'enabled');
                }
            },
            error: function () {
                // Revert on error
                checkbox.prop('checked', false);
                card.removeClass('enabled');
                card.attr('data-status', 'inactive');
                settingsBtn.hide();
                alert('Failed to save. Please try again.');
            }
        });
    });

    // Modal functionality
    $('#switchboard-save-preset').on('click', function () {
        $('#save-preset-modal').fadeIn();
    });

    $('#switchboard-load-preset').on('click', function () {
        $('#load-preset-modal').fadeIn();
    });

    $('#switchboard-export-preset').on('click', function () {
        const $btn = $(this);
        const originalText = $btn.text();
        $btn.prop('disabled', true).text('Exporting...');

        exportCurrentConfiguration(function() {
            $btn.prop('disabled', false).text(originalText);
        });
    });

    $('#switchboard-import-preset').on('click', function () {
        // Reset import modal state before showing
        $('#import-file-input').val('');
        $('#import-preview').hide();
        $('#confirm-import').prop('disabled', true).text('Import & Apply').removeData('encoded');
        $('#import-apply-immediately').prop('checked', true);
        $('#import-preset-modal').fadeIn();
    });

    // Settings modal
    $('#switchboard-settings').on('click', function () {
        $('#settings-modal').fadeIn();
    });

    // Privacy toggle handler
    $('#toggle-privacy-options').on('click', function () {
        const $advancedOptions = $('#privacy-advanced-options');
        const $chevron = $('#privacy-chevron');

        if ($advancedOptions.is(':visible')) {
            $advancedOptions.slideUp(200);
            $chevron.css('transform', 'rotate(0deg)');
        } else {
            $advancedOptions.slideDown(200);
            $chevron.css('transform', 'rotate(180deg)');
        }
    });

    // Save settings
    $('#save-settings').on('click', function () {
        const $btn = $(this);
        const betaEnabled = $('#beta-mode-settings-toggle').is(':checked');
        const optOutTelemetry = $('#opt-out-telemetry-toggle').is(':checked');
        const disableFeedback = $('#disable-feedback-toggle').is(':checked');

        $btn.prop('disabled', true).text('Saving...');

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_save_settings',
                nonce: switchboardSettings.nonce,
                beta_enabled: betaEnabled,
                opt_out_telemetry: optOutTelemetry,
                disable_feedback: disableFeedback
            },
            success: function (response) {
                if (response.success) {
                    // Show success message
                    $btn.text('Saved!');

                    // Wait a moment to show the success message, then reload
                    setTimeout(function() {
                        location.reload();
                    }, 600);
                } else {
                    alert('Failed to save settings: ' + (response.data?.message || 'Unknown error'));
                    $btn.prop('disabled', false).text('Save Changes');
                }
            },
            error: function () {
                alert('Failed to save settings. Please try again.');
                $btn.prop('disabled', false).text('Save Changes');
            }
        });
    });

    // Clear module cache
    $('#clear-module-cache').on('click', function () {
        const $btn = $(this);
        const originalText = $btn.text();

        if (!confirm('Clear module cache and refresh? This will reload the page.')) {
            return;
        }

        $btn.prop('disabled', true).text('Clearing...');

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_clear_cache',
                nonce: switchboardSettings.nonce
            },
            success: function (response) {
                if (response.success) {
                    // Clear localStorage (view mode, sort preferences, etc.)
                    localStorage.removeItem('switchboard-view-mode');
                    localStorage.removeItem('switchboard_sort_by');
                    localStorage.removeItem('switchboard_desc_state');
                    localStorage.removeItem('switchboard_usecases_state');

                    // Show success message
                    $btn.css('background', 'var(--primary-500)').css('color', 'white').text('Cache Cleared!');

                    // Wait a moment to show the success message, then reload
                    setTimeout(function() {
                        location.reload();
                    }, 800);
                } else {
                    alert('Failed to clear cache: ' + (response.data?.message || 'Unknown error'));
                    $btn.prop('disabled', false).text(originalText);
                }
            },
            error: function () {
                alert('Failed to clear cache. Please try again.');
                $btn.prop('disabled', false).text(originalText);
            }
        });
    });

    // Clear Inactive Module Data Handler
    $('#clear-inactive-data-btn').on('click', function () {
        const $btn = $(this);
        const originalText = $btn.text();

        // First confirmation
        if (!confirm('Clear Inactive Module Data?\n\nThis will delete data from modules you have DISABLED:\n- Database tables from inactive modules\n- Settings and configurations\n- Analytics and logs\n\nYour ACTIVE modules will NOT be affected.\n\nThis action cannot be undone. Continue?')) {
            return;
        }

        // Second confirmation with typing
        const confirmation = prompt('To confirm, please type: CLEAR INACTIVE');
        if (confirmation !== 'CLEAR INACTIVE') {
            alert('Confirmation failed. Data was not deleted.');
            return;
        }

        $btn.prop('disabled', true).text('Cleaning...');

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_clear_inactive_data',
                nonce: switchboardSettings.nonce
            },
            success: function (response) {
                if (response.success) {
                    $btn.css('background', 'var(--primary-500)').css('color', 'white').text('Cleaned!');

                    alert('Inactive module data has been successfully deleted. Active modules are safe.');

                    setTimeout(function() {
                        location.reload();
                    }, 1000);
                } else {
                    alert('Failed to clear data: ' + (response.data?.message || 'Unknown error'));
                    $btn.prop('disabled', false).text(originalText);
                }
            },
            error: function () {
                alert('Failed to clear data. Please try again.');
                $btn.prop('disabled', false).text(originalText);
            }
        });
    });

    // Clear All Data Handler
    $('#clear-all-data-btn').on('click', function () {
        const $btn = $(this);
        const originalText = $btn.text();

        // First confirmation
        if (!confirm('WARNING: This will permanently delete ALL plugin data!\n\nThis includes:\n- All module settings and configurations\n- Analytics data (if Lean Analytics is enabled)\n- Custom content (redirects, 404 logs, etc.)\n- All cached data\n\nThis action CANNOT be undone!\n\nAre you absolutely sure you want to continue?')) {
            return;
        }

        // Second confirmation with typing
        const confirmation = prompt('To confirm, please type: DELETE ALL DATA');
        if (confirmation !== 'DELETE ALL DATA') {
            alert('Confirmation failed. Data was not deleted.');
            return;
        }

        $btn.prop('disabled', true).text('Deleting...');

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_clear_all_data',
                nonce: switchboardSettings.nonce
            },
            success: function (response) {
                if (response.success) {
                    $btn.css('background', 'var(--primary-500)').css('color', 'white').text('Data Cleared!');

                    alert('All plugin data has been successfully deleted. The page will now reload.');

                    setTimeout(function() {
                        location.reload();
                    }, 1000);
                } else {
                    alert('Failed to clear data: ' + (response.data?.message || 'Unknown error'));
                    $btn.prop('disabled', false).text(originalText);
                }
            },
            error: function () {
                alert('Failed to clear data. Please try again.');
                $btn.prop('disabled', false).text(originalText);
            }
        });
    });

    $('.modal-close, .modal-cancel').on('click', function () {
        $(this).closest('.switchboard-modal').fadeOut();
        $('#import-preview').hide();
        $('#import-file-input').val('');
        $('#confirm-import').prop('disabled', true);
    });

    $(document).on('click', '.switchboard-modal', function (e) {
        if ($(e.target).hasClass('switchboard-modal')) {
            $(this).fadeOut();
        }
    });

    // Settings panel functionality
    $('.module-settings').on('click', function (e) {
        e.preventDefault();
        const card = $(this).closest('.module-card, .module-list-item');
        const moduleName = card.data('module');
        const moduleTitle = card.find('.module-name, .module-list-name').text();
        const hasSettings = card.data('has-settings') === '1' || card.data('has-settings') === 1;
        const hasAdminPage = card.data('has-admin-page');
        const adminPageUrl = card.data('admin-page-url');

        // If module has settings panel, show it (settings take priority)
        // Only redirect to dedicated page if module has NO settings panel
        if (hasSettings) {
            openSettingsPanel(moduleName, moduleTitle);
            return;
        }

        // If module has a dedicated admin page but no settings, navigate to it
        if (hasAdminPage && adminPageUrl) {
            window.location.href = adminPageUrl;
            return;
        }

        // Fallback: try to open settings panel anyway
        openSettingsPanel(moduleName, moduleTitle);
    });

    // Module to category mapping for documentation URLs
    const moduleCategories = {
        // Admin modules
        'active-plugins-first': 'admin', 'admin-color-schemes': 'admin', 'admin-columns-manager': 'admin',
        'admin-logo': 'admin', 'admin-menu-organizer': 'admin', 'admin-menu-separator': 'admin',
        'clean-admin-bar': 'admin', 'clean-dashboard': 'admin', 'compact-tables': 'admin',
        'content-report-widget': 'admin', 'custom-admin-css': 'admin', 'custom-admin-footer': 'admin',
        'custom-dashboard-welcome': 'admin', 'dashboard-columns-settings': 'admin',
        'disable-admin-bar-frontend': 'admin', 'disable-dashboard-widgets-select': 'admin',
        'enhance-list-tables': 'admin', 'featured-image-column': 'admin', 'footer-timezone': 'admin',
        'gutenberg-block-control': 'admin', 'hide-admin-bar-roles': 'admin', 'hide-admin-menu-items': 'admin',
        'hide-admin-notices': 'admin', 'login-page-customizer': 'admin', 'move-switchboard-to-tools': 'admin',
        'options-page-builder': 'admin', 'plugin-role-control': 'admin', 'show-ids': 'admin',
        'site-identity-login': 'admin', 'storage-monitor': 'admin', 'wider-admin-menu': 'admin',
        // Content modules
        'accessibility-widget': 'content', 'auto-featured-image': 'content', 'auto-publish-missed-schedule': 'content',
        'breadcrumbs': 'content', 'bulk-page-creator': 'content', 'change-post-type': 'content',
        'content-expiration': 'content', 'content-exporter': 'content', 'cpt-builder': 'content',
        'custom-body-class': 'content', 'custom-field-groups': 'content', 'custom-frontend-css': 'content',
        'custom-post-meta-display': 'content', 'custom-post-order': 'content', 'custom-taxonomy-builder': 'content',
        'custom-taxonomy-order': 'content', 'default-og-image': 'content', 'disable-comments': 'content',
        'duplicate-post-button': 'content', 'email-obfuscator': 'content', 'estimated-publish-date': 'content',
        'external-links-new-tab': 'content', 'external-permalinks': 'content', 'post-views-counter': 'content',
        'public-preview-drafts': 'content', 'reading-time': 'content', 'related-posts': 'content',
        'social-share-buttons': 'content', 'table-of-contents': 'content', 'user-role-body-class': 'content',
        'username-body-class': 'content',
        // Media modules
        'avif-conversion': 'media', 'avif-support': 'media', 'block-video-uploads': 'media', 'custom-image-sizes': 'media',
        'default-featured-image': 'media', 'image-sizes-panel': 'media', 'image-upload-rename': 'media',
        'media-categories': 'media', 'media-infinite-scroll': 'media', 'media-rename': 'media',
        'media-replacement': 'media', 'regenerate-thumbnails': 'media', 'resize-images-on-upload': 'media',
        'svg-support': 'media', 'unused-media-finder': 'media', 'webp-conversion': 'media',
        // Optimization modules
        'database-optimizer': 'optimization', 'disable-dashicons-frontend': 'optimization',
        'disable-embeds': 'optimization', 'disable-emoji': 'optimization', 'disable-feeds': 'optimization',
        'disable-gutenberg': 'optimization', 'heartbeat-control': 'optimization',
        'revisions-control': 'optimization', 'transients-cleaner': 'optimization',
        // Security modules
        'activity-log': 'security', 'disable-all-updates': 'security', 'disable-application-passwords': 'security',
        'disable-author-archives': 'security', 'disable-file-editing': 'security', 'disable-rest-api': 'security',
        'disable-xmlrpc': 'security', 'force-ssl-admin': 'security', 'hide-wp-version': 'security',
        'ip-whitelist-blacklist': 'security', 'limit-login-attempts': 'security', 'login-id-type': 'security',
        'obfuscate-author-slugs': 'security', 'password-protection': 'security', 'security-headers': 'security',
        'username-blacklist': 'security',
        // User Management modules
        'alphabet-avatars': 'user-management', 'last-login-column': 'user-management',
        'local-user-avatar': 'user-management', 'login-as-user': 'user-management',
        'login-logout-menu': 'user-management', 'multiple-user-roles': 'user-management',
        'redirect-after-login': 'user-management', 'registration-date-column': 'user-management',
        'simple-role-editor': 'user-management', 'simplified-profiles': 'user-management',
        'temporary-login': 'user-management', 'user-exporter': 'user-management',
        'user-meta-display': 'user-management', 'username-changer': 'user-management',
        'view-admin-as-role': 'user-management',
        // Utilities modules
        '404-redirect': 'utilities', 'ads-txt': 'utilities', 'alpine-js-enqueue': 'utilities',
        'auto-alt-text': 'utilities', 'auto-dark-mode': 'utilities', 'broken-link-checker': 'utilities',
        'code-snippets-manager': 'utilities', 'coming-soon': 'utilities', 'conditional-redirects': 'utilities',
        'custom-excerpt-length': 'utilities', 'custom-fonts-manager': 'utilities',
        'customize-wp-mail-defaults': 'utilities', 'download-plugin-zip': 'utilities',
        'download-theme-zip': 'utilities', 'email-smtp': 'utilities', 'header-footer-code': 'utilities',
        'lean-analytics': 'utilities', 'link-shortener': 'utilities', 'maintenance-mode-enhanced': 'utilities',
        'performance-monitor': 'utilities', 'quick-debug-toggle': 'utilities', 'redirects-manager': 'utilities',
        'remove-unused-themes-plugins': 'utilities', 'robots-txt': 'utilities',
        'search-visibility-status': 'utilities', 'simple-forms': 'utilities', 'system-summary': 'utilities',
        'track-404s': 'utilities', 'tracking-codes-manager': 'utilities', 'wp-mail-logging': 'utilities'
    };

    function openSettingsPanel(moduleName, moduleTitle) {
        // Set title and add help button
        const category = moduleCategories[moduleName] || 'utilities';
        const helpUrl = 'https://docs.wpswitchboard.com/modules/' + category + '/' + moduleName;
        const titleHtml = moduleTitle + ' Settings <a href="' + helpUrl + '" target="_blank" rel="noopener noreferrer" class="sb-sp-help-btn" title="View documentation"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="14" height="14"><path fill-rule="evenodd" d="M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0ZM8.94 6.94a.75.75 0 1 1-1.061-1.061 3 3 0 1 1 2.871 5.026v.345a.75.75 0 0 1-1.5 0v-.5c0-.72.57-1.172 1.081-1.287A1.5 1.5 0 1 0 8.94 6.94ZM10 15a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z" clip-rule="evenodd" /></svg><span>HELP</span></a>';
        $('#settings-panel-title').html(titleHtml);
        $('#settings-panel').fadeIn(200);

        // Disable save buttons while loading
        $('.settings-panel-save').prop('disabled', true).css('opacity', '0.5');

        // Apply width class based on module needs
        // Wide panel (900px) for modules with tables, complex forms, or side-by-side layouts
        const widePanelModules = [
            // Currently wide panels
            'track-404s',                    // Has tracking settings with use cases and stats
            'redirects-manager',             // Has redirect table with multiple columns
            'remove-unused-themes-plugins',  // Has side-by-side plugin/theme lists
            'code-snippets-manager',         // Has snippets table with code editor
            'admin-columns-manager',         // Has column reordering interface
            'temporary-login',               // Has active links table with multiple columns
            'unused-media-finder',           // Has media table with file listings
            'custom-field-groups',           // Has two-column layout: field types sidebar + field builder
            'options-page-builder',          // Has modal with field builder and complex forms
            'admin-menu-organizer',          // Has menu reordering interface with nested structure
            'coming-soon',                   // Has background image preview, logo upload, and social links

            // High priority additions
            'simple-role-editor',            // Complex capabilities table with role selector + search
            'activity-log',                  // 6-column table (Date, User, Role, Action, Details, IP)
            'custom-post-order',             // Drag-and-drop post ordering with thumbnails
            'custom-taxonomy-order',         // Hierarchical term display with drag-and-drop
            'cpt-builder',                   // Extensive CPT configuration options
            'custom-taxonomy-builder',       // Custom taxonomy builder with many settings
            'plugin-role-control',           // Matrix-style plugin permissions layout         // Analytics dashboard with charts and data tables
            'broken-link-checker',           // Results table with multiple action columns
            'wp-mail-logging',               // Email log table with preview functionality
            'conditional-redirects',         // Redirect rules table with conditions and hit tracking
            'magic-login',                   // Magic login with activity table and shortcode builder
            'two-factor-authentication',     // 2FA with user stats table and role settings
            'otp-login',                     // OTP login with stats and Twilio configuration
            'hide-my-login'                  // Hide login with stats, IP whitelist, and security options
        ];

        $('.settings-panel-content').removeClass('panel-wide panel-extra-wide');

        if (widePanelModules.includes(moduleName)) {
            $('.settings-panel-content').addClass('panel-wide');
        }
        // Note: Extra-wide (1200px) panel class available but not currently used

        $('.settings-panel-content').addClass('open');

        // Load settings via AJAX
        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_get_module_settings',
                module: moduleName,
                nonce: switchboardSettings.settings_nonce
            },
            success: function (response) {
                if (response.success) {
                    $('#settings-panel-body').html(response.data.html);

                    // Re-enable save buttons after content loads
                    $('.settings-panel-save').prop('disabled', false).css('opacity', '1');

                    // Initialize snippets manager if this is the code-snippets-manager module
                    if (moduleName === 'code-snippets-manager' && $('#snippets-data-holder').length) {
                        loadSnippetsData();
                        refreshSnippetsList();
                    }

                    // Initialize font preview if this is the custom-fonts-manager module
                    if (moduleName === 'custom-fonts-manager' && $('#font-css-preview').length) {
                        updateFontPreview();
                    }
                } else {
                    $('#settings-panel-body').html('<p>No settings available for this module.</p>');
                    // Re-enable save buttons even if no settings
                    $('.settings-panel-save').prop('disabled', false).css('opacity', '1');
                }
            },
            error: function () {
                $('#settings-panel-body').html('<p>Error loading settings. Please try again.</p>');
                // Re-enable save buttons on error
                $('.settings-panel-save').prop('disabled', false).css('opacity', '1');
            }
        });
    }

    // Auto-reopen settings panel after page reload (for refresh blocks functionality)
    $(document).ready(function() {
        const reopenModule = sessionStorage.getItem('switchboard_reopen_panel');
        if (reopenModule) {
            sessionStorage.removeItem('switchboard_reopen_panel');
            
            // Find the module card and get its title
            const $moduleCard = $('.module-card[data-module="' + reopenModule + '"], .module-list-item[data-module="' + reopenModule + '"]');
            if ($moduleCard.length) {
                const moduleTitle = $moduleCard.find('.module-name, .module-list-name').text();
                
                // Small delay to ensure page is fully loaded
                setTimeout(function() {
                    openSettingsPanel(reopenModule, moduleTitle);
                }, 300);
            }
        }
    });

    $('.settings-panel-close, .settings-panel-cancel, .settings-panel-overlay').on('click', function () {
        closeSettingsPanel();
    });

    // ESC key to close settings panel (but not if snippet modal is open)
    $(document).on('keydown', function (e) {
        if (e.key === 'Escape' && $('#settings-panel').is(':visible')) {
            // Don't close settings panel if snippet modal is open
            if ($('#snippet-modal').is(':visible')) {
                return;
            }
            closeSettingsPanel();
        }
    });

    function closeSettingsPanel() {
        // Check if regeneration is running (global variable set by regenerate-thumbnails module)
        if (window.switchboardRegenerationRunning === true) {
            if (!confirm('Thumbnail regeneration is in progress. Closing this panel will stop the process. Are you sure you want to close?')) {
                return false; // Cancel closing
            }
        }

        $('.settings-panel-content').removeClass('open');
        setTimeout(function () {
            $('#settings-panel').fadeOut(200);
        }, 300);
    }

    $('.settings-panel-save').on('click', function () {
        // Get the action from the button's data attribute
        const saveAction = $(this).data('action'); // 'save' or 'save-refresh'

        // Check if module is present - if not, settings panel hasn't loaded yet
        const module = $('#settings-panel-body').find('input[name="module"]').val();

        if (!module) {
            alert('Settings panel is still loading. Please wait a moment and try again.');
            return;
        }

        if (module === 'admin-columns-manager') {
            // For columns manager, auto-save handles everything
            // Only close panel if "Save & Close" was clicked
            if (saveAction === 'save-refresh') {
                closeSettingsPanel();
                $('<div class="notice notice-success is-dismissible"><p>Column configuration saved!</p></div>')
                    .insertAfter('.switchboard-header')
                    .delay(3000)
                    .fadeOut();
            } else {
                // Just show success message without closing
                $('.auto-save-label').fadeIn(200).delay(1500).fadeOut(200);
            }
            return;
        }

        let formData = $('#settings-panel-body').find('input, select, textarea').serialize();

        // Handle unchecked checkboxes - add them with value 0
        // Process ALL checkboxes that are setting fields (name starts with 'setting_')
        // This ensures unchecked checkboxes are properly saved across all modules
        $('#settings-panel-body').find('input[type="checkbox"]:not(:checked)').each(function () {
            const name = $(this).attr('name');
            // Check if it's a setting field OR has the specific classes (for role editor compatibility)
            if (name && (name.startsWith('setting_') || $(this).hasClass('switchboard-checkbox') || $(this).hasClass('modern-checkbox-input'))) {
                formData += '&' + encodeURIComponent(name) + '=0';
            }
        });

        // Save settings via AJAX
        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: formData + '&action=switchboard_save_module_settings&nonce=' + switchboardSettings.settings_nonce,
            success: function (response) {
                if (response.success) {
                    // Check if this is the role editor - if so, keep panel open
                    const isRoleEditor = formData.includes('module=simple-role-editor') ||
                                        formData.includes('switchboard_role_editor_update=1');

                    if (isRoleEditor) {
                        // Check if this is Save & Close (save-refresh) or just Save
                        if (saveAction === 'save-refresh') {
                            // Close panel and reload WITHOUT reopening
                            closeSettingsPanel();
                            const url = new URL(window.location.href);
                            url.searchParams.delete('open_settings');
                            window.location.href = url.toString();
                        } else {
                            // Show success message inside the panel with role name (Save only)
                            let successMsg = 'Role capabilities updated successfully';
                            if (response.data && response.data.role_name) {
                                successMsg = '<strong>' + response.data.role_name + '</strong> capabilities updated successfully';
                            } else if (response.data && response.data.message) {
                                successMsg = response.data.message;
                            }

                            // Remove any existing toast messages
                            $('.role-editor-toast').remove();

                            // Create toast notification - position it beside the Cancel button
                            // Find the Cancel button to position relative to it
                            const $cancelBtn = $('.settings-panel-footer .cancel-settings-btn');
                            let toastStyle = 'position: fixed; bottom: 30px; right: 420px;'; // Default position

                            if ($cancelBtn.length) {
                                const btnOffset = $cancelBtn.offset();
                                const btnLeft = btnOffset.left;
                                // Position toast to the left of Cancel button with 15px gap
                                toastStyle = 'position: fixed; top: ' + btnOffset.top + 'px; right: ' + ($(window).width() - btnLeft + 15) + 'px;';
                            }

                            const $toast = $('<div class="role-editor-toast" style="' + toastStyle + ' background: var(--primary-100); border: 1px solid var(--primary-500); color: var(--primary-800); padding: 8px 12px; border-radius: 3px; display: flex; align-items: center; gap: 6px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); z-index: 999999; font-size: 12px; white-space: nowrap; animation: slideInRight 0.3s ease-out;">' +
                                '<svg width="16" height="16" viewBox="0 0 20 20" fill="currentColor" style="flex-shrink: 0;"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/></svg>' +
                                '<span>' + successMsg + '</span>' +
                            '</div>');

                            $('body').append($toast);

                            // Update the capability count in the UI
                            if (response.data.added_count !== undefined) {
                                const currentRole = $('#role-select').val();
                                const totalCaps = $('.capability-row').length;
                                $('.capabilities-count').text(response.data.added_count + ' of ' + totalCaps + ' capabilities enabled');
                            }

                            // Auto-remove after 3 seconds
                            setTimeout(function() {
                                $toast.fadeOut(300, function() { $(this).remove(); });
                            }, 3000);
                        }
                    } else {
                        // For all other modules: handle based on button clicked
                        if (saveAction === 'save-refresh') {
                            // Save & Refresh: close panel and reload page
                            closeSettingsPanel();

                            // Show brief success message then reload
                            const $toast = $('<div class="settings-saved-toast" style="position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: var(--primary-100); border: 1px solid var(--primary-500); color: var(--primary-800); padding: 12px 20px; border-radius: 6px; display: flex; align-items: center; gap: 10px; box-shadow: 0 4px 12px rgba(0,0,0,0.2); z-index: 999999; font-size: 14px; font-weight: 500;">' +
                                '<svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/></svg>' +
                                '<span>Settings saved! Refreshing...</span>' +
                            '</div>');

                            $('body').append($toast);

                            // Reload page after brief delay
                            setTimeout(function() {
                                location.reload();
                            }, 600);
                        } else {
                            // Save only: keep panel open and show success toast
                            // Remove any existing toast messages
                            $('.settings-saved-toast').remove();

                            // Create toast notification
                            const $toast = $('<div class="settings-saved-toast" style="position: fixed; bottom: 30px; right: 30px; background: var(--primary-100); border: 1px solid var(--primary-500); color: var(--primary-800); padding: 10px 15px; border-radius: 6px; display: flex; align-items: center; gap: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 999999; font-size: 13px; font-weight: 500; animation: slideInRight 0.3s ease-out;">' +
                                '<svg width="18" height="18" viewBox="0 0 20 20" fill="currentColor" style="flex-shrink: 0;"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/></svg>' +
                                '<span>Settings saved successfully!</span>' +
                            '</div>');

                            $('body').append($toast);

                            // Auto-remove after 3 seconds
                            setTimeout(function() {
                                $toast.fadeOut(300, function() { $(this).remove(); });
                            }, 3000);
                        }
                    }
                } else {
                    alert('Error: ' + (response.data && response.data.message ? response.data.message : 'Failed to save settings'));
                }
            },
            error: function(xhr, status, error) {
                alert('Failed to save settings. Please try again.');
            }
        });
    });

    // Tag selector functionality (for settings with multiple selections)
    $(document).on('click', '.switchboard-tag-option:not(.selected)', function () {
        const tag = $(this);
        const value = tag.data('value');
        const label = tag.text();
        const container = tag.closest('.switchboard-tag-selector');
        const selectedContainer = container.find('.switchboard-selected-tags');
        const hiddenInput = container.prev('input[type="hidden"]');

        // Add to selected
        const tagHtml = '<span class="switchboard-tag" data-value="' + value + '">' + label + ' <span class="remove-tag">&times;</span></span>';
        selectedContainer.append(tagHtml);

        // Mark as selected
        tag.addClass('selected');

        // Update hidden input
        updateHiddenInput(container);
    });

    $(document).on('click', '.remove-tag', function () {
        const tagSpan = $(this).parent();
        const value = tagSpan.data('value');
        const container = tagSpan.closest('.switchboard-tag-selector');

        // Remove from selected
        tagSpan.remove();

        // Unmark in available
        container.find('.switchboard-tag-option[data-value="' + value + '"]').removeClass('selected');

        // Update hidden input
        updateHiddenInput(container);
    });

    function updateHiddenInput(container) {
        const values = [];

        container.find('.switchboard-tag').each(function () {
            values.push($(this).data('value'));
        });

        const valueString = values.join(',');

        // Try to find hidden input using data attribute first
        let hiddenInput;
        const inputId = container.data('input-id');

        if (inputId) {
            hiddenInput = $('#' + inputId);
        }

        // Fallback methods
        if (!hiddenInput || !hiddenInput.length) {
            hiddenInput = container.prev('input[type="hidden"][id]');
        }

        if (!hiddenInput.length) {
            hiddenInput = container.prev('input[type="hidden"]');
        }

        if (!hiddenInput.length) {
            hiddenInput = container.parent().find('input[type="hidden"][id]').first();
        }

        if (hiddenInput.length) {
            hiddenInput.val(valueString);
            hiddenInput.trigger('change');
        }
    }

    // Logo uploader for maintenance mode
    var maintenanceMediaUploader;

    $(document).on('click', '#upload-maintenance-logo', function (e) {
        e.preventDefault();

        if (maintenanceMediaUploader) {
            maintenanceMediaUploader.open();
            return;
        }

        maintenanceMediaUploader = wp.media({
            title: 'Select Logo',
            button: { text: 'Use this image' },
            multiple: false,
            library: { type: 'image' }
        });

        maintenanceMediaUploader.on('select', function () {
            var attachment = maintenanceMediaUploader.state().get('selection').first().toJSON();
            $('#setting_logo').val(attachment.id);
            $('#maintenance-logo-preview').html('<img src="' + attachment.url + '" style="max-width: 200px; height: auto; border-radius: 8px; display: block; margin-bottom: 10px;">');
            $('#remove-maintenance-logo').show();
        });

        maintenanceMediaUploader.open();
    });

    $(document).on('click', '#remove-maintenance-logo', function (e) {
        e.preventDefault();
        $('#setting_logo').val('');
        $('#maintenance-logo-preview').html('');
        $(this).hide();
    });

    // Font uploader for custom fonts manager
    var fontMediaUploader;
    var currentFontTarget;

    $(document).on('click', '.upload-font-btn', function (e) {
        e.preventDefault();
        currentFontTarget = $(this).data('target');

        if (fontMediaUploader) {
            fontMediaUploader.open();
            return;
        }

        fontMediaUploader = wp.media({
            title: 'Select Font File',
            button: { text: 'Use this font' },
            multiple: false,
            library: {
                type: ['font/woff', 'font/woff2', 'font/ttf', 'font/otf', 'application/x-font-woff', 'application/x-font-ttf', 'application/x-font-otf']
            }
        });

        fontMediaUploader.on('select', function () {
            var attachment = fontMediaUploader.state().get('selection').first().toJSON();
            var fileUrl = attachment.url;
            var fileExt = fileUrl.split('.').pop().toLowerCase();

            // Determine expected extension from target field
            var expectedExt = '';
            if (currentFontTarget.includes('woff2')) {
                expectedExt = 'woff2';
            } else if (currentFontTarget.includes('woff')) {
                expectedExt = 'woff';
            } else if (currentFontTarget.includes('ttf')) {
                expectedExt = 'ttf';
            } else if (currentFontTarget.includes('otf')) {
                expectedExt = 'otf';
            }

            // Validate file extension matches expected field
            if (expectedExt && fileExt !== expectedExt) {
                alert('Warning: You selected a .' + fileExt.toUpperCase() + ' file for the ' + expectedExt.toUpperCase() + ' field.\n\nPlease upload a .' + expectedExt.toUpperCase() + ' file instead for proper font loading.');
                return;
            }

            $('#' + currentFontTarget).val(fileUrl);
            updateFontPreview();
        });

        fontMediaUploader.open();
    });

    // Update font CSS preview
    function updateFontPreview() {
        var bodyName = $('#setting_body_name').val();
        var bodyWoff2 = $('#setting_body_woff2').val();
        var bodyWoff = $('#setting_body_woff').val();
        var bodyTtf = $('#setting_body_ttf').val();
        var bodyEnabled = $('#setting_body_enabled').is(':checked');

        var headingName = $('#setting_heading_name').val();
        var headingWoff2 = $('#setting_heading_woff2').val();
        var headingWoff = $('#setting_heading_woff').val();
        var headingTtf = $('#setting_heading_ttf').val();
        var headingEnabled = $('#setting_heading_enabled').is(':checked');

        var css = '';

        if (bodyName && (bodyWoff2 || bodyWoff || bodyTtf)) {
            css += '@font-face {\n';
            css += '    font-family: \'' + bodyName + '\';\n';
            css += '    src: ';

            var sources = [];
            if (bodyWoff2) sources.push('url(\'' + bodyWoff2 + '\') format(\'woff2\')');
            if (bodyWoff) sources.push('url(\'' + bodyWoff + '\') format(\'woff\')');
            if (bodyTtf) sources.push('url(\'' + bodyTtf + '\') format(\'truetype\')');

            css += sources.join(',\n         ') + ';\n';
            css += '    font-weight: normal;\n';
            css += '    font-style: normal;\n';
            css += '    font-display: swap;\n';
            css += '}\n';

            if (bodyEnabled) {
                css += '\nbody, p, div, span, li, td, th {\n';
                css += '    font-family: \'' + bodyName + '\', sans-serif !important;\n';
                css += '}\n';
            }
        }

        if (headingName && (headingWoff2 || headingWoff || headingTtf)) {
            if (css) css += '\n';
            css += '@font-face {\n';
            css += '    font-family: \'' + headingName + '\';\n';
            css += '    src: ';

            var sources = [];
            if (headingWoff2) sources.push('url(\'' + headingWoff2 + '\') format(\'woff2\')');
            if (headingWoff) sources.push('url(\'' + headingWoff + '\') format(\'woff\')');
            if (headingTtf) sources.push('url(\'' + headingTtf + '\') format(\'truetype\')');

            css += sources.join(',\n         ') + ';\n';
            css += '    font-weight: normal;\n';
            css += '    font-style: normal;\n';
            css += '    font-display: swap;\n';
            css += '}\n';

            if (headingEnabled) {
                css += '\nh1, h2, h3, h4, h5, h6 {\n';
                css += '    font-family: \'' + headingName + '\', sans-serif !important;\n';
                css += '}\n';
            }
        }

        if (!css) {
            css = '/* CSS will appear here after saving */';
        }

        $('#font-css-preview').text(css);
    }

    // Update preview when inputs change
    $(document).on('input change', '#setting_body_name, #setting_body_woff2, #setting_body_woff, #setting_body_ttf, #setting_body_enabled, #setting_heading_name, #setting_heading_woff2, #setting_heading_woff, #setting_heading_ttf, #setting_heading_enabled', function () {
        updateFontPreview();
        updateFontToggleStates();
    });

    // Enable/disable font apply toggles based on whether font name and files are set
    function updateFontToggleStates() {
        var bodyName = $('#setting_body_name').val();
        var bodyHasFiles = $('#setting_body_woff2').val() || $('#setting_body_woff').val() || $('#setting_body_ttf').val();
        var $bodyToggle = $('#setting_body_enabled');
        var $bodyToggleLabel = $bodyToggle.closest('.sb-module-toggle');

        if (bodyName && bodyHasFiles) {
            $bodyToggle.prop('disabled', false);
            $bodyToggleLabel.removeClass('sb-toggle-disabled');
        } else {
            $bodyToggle.prop('disabled', true).prop('checked', false);
            $bodyToggleLabel.addClass('sb-toggle-disabled');
        }

        var headingName = $('#setting_heading_name').val();
        var headingHasFiles = $('#setting_heading_woff2').val() || $('#setting_heading_woff').val() || $('#setting_heading_ttf').val();
        var $headingToggle = $('#setting_heading_enabled');
        var $headingToggleLabel = $headingToggle.closest('.sb-module-toggle');

        if (headingName && headingHasFiles) {
            $headingToggle.prop('disabled', false);
            $headingToggleLabel.removeClass('sb-toggle-disabled');
        } else {
            $headingToggle.prop('disabled', true).prop('checked', false);
            $headingToggleLabel.addClass('sb-toggle-disabled');
        }
    }

    // Grid is now automatically responsive - no manual column selection needed

    // Store original order
    const originalOrder = $('#modules-grid .module-card').map(function () {
        return $(this).data('module');
    }).get();

    // Sort functionality
    function sortModules(sortBy) {
        // Detect current view mode
        const isGridView = $('.switchboard-grid').is(':visible');

        if (isGridView) {
            // Grid view sorting
            const grid = $('#modules-grid');
            const cards = grid.find('.module-card').get();

            cards.sort(function (a, b) {
                const cardA = $(a);
                const cardB = $(b);

                switch (sortBy) {
                    case 'name-asc':
                        return cardA.find('.module-name').text().localeCompare(cardB.find('.module-name').text());
                    case 'name-desc':
                        return cardB.find('.module-name').text().localeCompare(cardA.find('.module-name').text());
                    case 'active-first':
                        const statusA = cardA.hasClass('enabled') ? 0 : 1;
                        const statusB = cardB.hasClass('enabled') ? 0 : 1;
                        return statusA - statusB;
                    case 'inactive-first':
                        const statusC = cardA.hasClass('enabled') ? 1 : 0;
                        const statusD = cardB.hasClass('enabled') ? 1 : 0;
                        return statusC - statusD;
                    case 'newest-first':
                        const dateA = new Date(cardA.data('added') || '1970-01-01');
                        const dateB = new Date(cardB.data('added') || '1970-01-01');
                        return dateB - dateA;
                    case 'oldest-first':
                        const dateC = new Date(cardA.data('added') || '1970-01-01');
                        const dateD = new Date(cardB.data('added') || '1970-01-01');
                        return dateC - dateD;
                    default:
                        return 0;
                }
            });

            $.each(cards, function (idx, card) {
                grid.append(card);
            });
        }
        // Note: With unified HTML structure, we no longer have separate list view sorting
        // All sorting is now handled by the grid section above

        // Save preference
        localStorage.setItem('switchboard_sort_by', sortBy);
    }

    // Sort select handler
    // Sort filter button click handler - always toggle between two states
    // Sort dropdown handler
    $('#sort-select').on('change', function () {
        const sortBy = $(this).val();
        updateUrlParams({ sort: sortBy });
        sortModules(sortBy);
    });

    // More Options Button - Toggle popover
    $('#more-options-btn').on('click', function (e) {
        e.stopPropagation();
        $('#more-options-popover').toggle();
    });

    // Close popover when clicking outside
    $(document).on('click', function (e) {
        if (!$(e.target).closest('#more-options-btn, #more-options-popover').length) {
            $('#more-options-popover').hide();
        }
    });

    // Description options in popover
    $('.popover-option[data-desc-action]').on('click', function () {
        const action = $(this).data('desc-action');
        const $descBtn = $('#desc-toggle-btn');

        // Update state
        $descBtn.data('state', action);
        $descBtn.attr('data-state', action);

        // Apply classes
        $('.module-description, .module-list-desc').removeClass('desc-truncated desc-hidden');

        if (action === 'truncated') {
            $('.module-description, .module-list-desc').addClass('desc-truncated');
            $descBtn.attr('title', 'Hide description');
            $descBtn.html('<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="4" width="12" height="2" rx="1" fill="currentColor"/><rect x="2" y="10" width="8" height="2" rx="1" fill="currentColor"/></svg>');
            $('.module-description-icon').show();
        } else if (action === 'hidden') {
            $('.module-description, .module-list-desc').addClass('desc-hidden');
            $descBtn.attr('title', 'Show description');
            $descBtn.html('<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="7" width="12" height="2" rx="1" fill="currentColor"/></svg>');
            $('.module-description-icon').show();
        } else {
            $descBtn.attr('title', 'Truncate description');
            $descBtn.html('<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="3" width="12" height="2" rx="1" fill="currentColor"/><rect x="2" y="7" width="12" height="2" rx="1" fill="currentColor"/><rect x="2" y="11" width="8" height="2" rx="1" fill="currentColor"/></svg>');
            $('.module-description-icon').hide();
        }

        // Update URL
        updateUrlParams({ desc: action });

        // Close popover
        $('#more-options-popover').hide();
    });

    // Load sort preference from URL or localStorage (default: active-first)
    let sortBy = urlParams.sort;
    if (!sortBy || sortBy === 'default') {
        sortBy = localStorage.getItem('switchboard_sort_by') || 'active-first';
    }
    $('#sort-select').val(sortBy);
    // Always sort if not name-asc (the natural order)
    if (sortBy !== 'name-asc') {
        sortModules(sortBy);
    }

    // Export/Import functionality
    function exportCurrentConfiguration(callback) {
        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_export_current',
                nonce: switchboardSettings.settings_nonce
            },
            success: function (response) {
                if (response.success) {
                    downloadBase64File(response.data.encoded, response.data.filename);
                } else {
                    alert('Export failed. Please try again.');
                }
                if (callback) callback();
            },
            error: function() {
                alert('Export failed. Please try again.');
                if (callback) callback();
            }
        });
    }

    // Export single preset
    $(document).on('click', '.export-single-preset', function () {
        const $btn = $(this);
        const presetId = $btn.data('preset-id');
        const originalText = $btn.text();

        $btn.prop('disabled', true).text('Exporting...');

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_export_preset',
                preset_id: presetId,
                nonce: switchboardSettings.settings_nonce
            },
            success: function (response) {
                if (response.success) {
                    downloadBase64File(response.data.encoded, response.data.filename);
                } else {
                    alert('Export failed. Please try again.');
                }
                $btn.prop('disabled', false).text(originalText);
            },
            error: function() {
                alert('Export failed. Please try again.');
                $btn.prop('disabled', false).text(originalText);
            }
        });
    });

    function downloadBase64File(encodedData, filename) {
        const blob = new Blob([encodedData], { type: 'text/plain' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = filename;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
    }

    // Import file handling
    $('#import-file-input').on('change', function (e) {
        const file = e.target.files[0];
        if (!file) return;

        const reader = new FileReader();
        reader.onload = function (event) {
            try {
                // Decode base64
                const encodedData = event.target.result.trim();
                const decodedData = atob(encodedData);
                const preset = JSON.parse(decodedData);

                if (!preset.modules) {
                    alert('Invalid preset file format.');
                    return;
                }

                // Count actual modules (handle v2.0 format with nested meta/modules structure)
                let moduleCount;
                if (preset.modules.meta && preset.modules.modules) {
                    // v2.0 format: modules contains {meta, modules}
                    moduleCount = Object.keys(preset.modules.modules).length;
                } else {
                    // v1.0 format: modules directly contains module configs
                    moduleCount = Object.keys(preset.modules).length;
                }

                // Show preview
                $('#preview-name').text(preset.name || 'Unnamed Preset');
                $('#preview-description').text(preset.description || 'No description');
                $('#preview-modules').text(moduleCount + ' modules');
                $('#import-preview').show();
                $('#confirm-import').prop('disabled', false).data('encoded', encodedData);

            } catch (error) {
                alert('Error reading file. Please ensure it\'s a valid Switchboard preset file.');
            }
        };
        reader.readAsText(file);
    });

    // Update button text based on checkbox state
    $('#import-apply-immediately').on('change', function () {
        const applyImmediately = $(this).is(':checked');
        $('#confirm-import').text(applyImmediately ? 'Import & Apply' : 'Import Preset');
    });

    // Confirm import
    $('#confirm-import').on('click', function () {
        const $btn = $(this);
        const encodedData = $btn.data('encoded');
        const applyImmediately = $('#import-apply-immediately').is(':checked');
        const originalText = $btn.text();

        $btn.prop('disabled', true).text('Importing...');

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_import_preset',
                preset_data: encodedData,
                apply_immediately: applyImmediately ? 'true' : 'false',
                nonce: switchboardSettings.settings_nonce
            },
            success: function (response) {
                if (response.success) {
                    let message = response.data.message + ' Reloading page...';
                    if (response.data.skipped_modules && response.data.skipped_modules.length > 0) {
                        message += '\n\nSkipped modules: ' + response.data.skipped_modules.join(', ');
                    }
                    alert(message);
                    location.reload();
                } else {
                    alert('Import failed: ' + response.data.message);
                    $btn.prop('disabled', false).text(originalText);
                }
            },
            error: function () {
                alert('Import failed. Please try again.');
                $btn.prop('disabled', false).text(originalText);
            }
        });
    });

    // Code Snippets Manager
    var snippetsData = [];
    var editingIndex = -1;

    function loadSnippetsData() {
        var json = $('#snippets-data-holder').val();
        try {
            snippetsData = JSON.parse(json);
            if (!Array.isArray(snippetsData)) {
                snippetsData = [];
            }
        } catch (e) {
            snippetsData = [];
        }
    }

    function saveSnippetsData() {
        // Save directly to database via AJAX
        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_save_snippets',
                nonce: switchboardSettings.settings_nonce,
                snippets: JSON.stringify(snippetsData)
            },
            success: function (response) {
                if (response.success) {
                    // Update holder for next load
                    $('#snippets-data-holder').val(JSON.stringify(snippetsData));
                }
            }
        });
    }

    function refreshSnippetsList() {
        var $list = $('#snippets-list');
        $list.empty();

        if (snippetsData.length === 0) {
            $list.html('<p class="description">No snippets yet. Click "Add New Snippet" to create one.</p>');
            return;
        }

        // Create table wrapper
        var $wrapper = $('<div class="snippets-table-wrapper"></div>');
        var $table = $('<table class="snippets-table"></table>');
        var $thead = $('<thead><tr>' +
            '<th></th>' +
            '<th>Name</th>' +
            '<th>Type</th>' +
            '<th>Location</th>' +
            '<th style="text-align: right;">Actions</th>' +
            '</tr></thead>');
        var $tbody = $('<tbody></tbody>');

        snippetsData.forEach(function (snippet, index) {
            var isEnabled = snippet.enabled === 'yes';
            var $row = $('<tr class="snippet-row' + (isEnabled ? '' : ' disabled') + '" data-index="' + index + '"></tr>');
            
            // Toggle column
            var $toggleCell = $('<td class="toggle-cell"></td>');
            var $toggle = $('<label class="toggle-switch"></label>');
            var $toggleInput = $('<input type="checkbox" class="toggle-snippet-enabled" data-index="' + index + '">');
            $toggleInput.prop('checked', isEnabled);
            var $toggleSlider = $('<span class="toggle-slider"></span>');
            $toggle.append($toggleInput).append($toggleSlider);
            $toggleCell.append($toggle);
            
            // Name column
            var $nameCell = $('<td class="name-cell"></td>');
            $nameCell.text(snippet.name);
            
            // Type column
            var $typeCell = $('<td class="type-cell"></td>');
            var badgeClass = 'badge-' + snippet.type;
            $typeCell.html('<span class="snippet-badge ' + badgeClass + '">' + snippet.type.toUpperCase() + '</span>');
            
            // Location column
            var $locationCell = $('<td class="location-cell"></td>');
            var locationLabel = snippet.location.replace(/-/g, ' ').replace(/\b\w/g, function (l) { return l.toUpperCase(); });
            $locationCell.text(locationLabel);
            
            // Actions column with icon buttons
            var $actionsCell = $('<td class="actions-cell"></td>');
            $actionsCell.append('<button type="button" class="snippet-action-btn edit-snippet-btn" data-index="' + index + '" title="Edit"><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="14" height="14"><path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /></svg></button>');
            $actionsCell.append('<button type="button" class="snippet-action-btn delete delete-snippet-btn" data-index="' + index + '" title="Delete"><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="14" height="14"><path stroke-linecap="round" stroke-linejoin="round" d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" /></svg></button>');
            
            $row.append($toggleCell).append($nameCell).append($typeCell).append($locationCell).append($actionsCell);
            $tbody.append($row);
        });

        $table.append($thead).append($tbody);
        $wrapper.append($table);
        $list.append($wrapper);
    }

    // Initialize CodeMirror for CSS/code editors
    function initCodeMirror() {
        if (typeof wp !== 'undefined' && typeof wp.codeEditor !== 'undefined') {
            // Initialize for CSS textareas
            var cssEditors = $('#setting_css, textarea[name="setting_css"], textarea[id*="css"]');

            cssEditors.each(function() {
                var textarea = $(this);
                if (textarea.length && !textarea.next('.CodeMirror').length) {
                    var editorSettings = wp.codeEditor.defaultSettings ? _.clone(wp.codeEditor.defaultSettings) : {};
                    editorSettings.codemirror = _.extend(
                        {},
                        editorSettings.codemirror || {},
                        {
                            mode: 'css',
                            lineNumbers: true,
                            lineWrapping: true,
                            theme: 'default',
                            autoRefresh: true,
                            indentUnit: 2,
                            tabSize: 2,
                            indentWithTabs: false,
                            matchBrackets: true,
                            autoCloseBrackets: true,
                            extraKeys: {
                                "Ctrl-Space": "autocomplete"
                            }
                        }
                    );

                    var editor = wp.codeEditor.initialize(textarea[0], editorSettings);

                    // Ensure CodeMirror updates the textarea on changes
                    if (editor && editor.codemirror) {
                        editor.codemirror.on('change', function() {
                            editor.codemirror.save();
                        });
                    }
                }
            });

            // Initialize for code snippets
            var snippetEditor = $('#snippet-code');
            if (snippetEditor.length) {
                // Destroy existing CodeMirror instance if it exists
                if (snippetCodeMirrorInstance && snippetCodeMirrorInstance.codemirror) {
                    snippetCodeMirrorInstance.codemirror.toTextArea();
                    snippetCodeMirrorInstance = null;
                }

                // Create fresh CodeMirror instance
                var snippetType = $('#snippet-type').val() || 'css';
                var mode = snippetType === 'css' ? 'css' : 'javascript';

                var editorSettings = wp.codeEditor.defaultSettings ? _.clone(wp.codeEditor.defaultSettings) : {};
                editorSettings.codemirror = _.extend(
                    {},
                    editorSettings.codemirror || {},
                    {
                        mode: mode,
                        lineNumbers: true,
                        lineWrapping: true,
                        theme: 'default',
                        autoRefresh: true,
                        indentUnit: 2,
                        tabSize: 2,
                        indentWithTabs: false,
                        matchBrackets: true,
                        autoCloseBrackets: true,
                        extraKeys: {
                            "Ctrl-Space": "autocomplete"
                        }
                    }
                );

                snippetCodeMirrorInstance = wp.codeEditor.initialize(snippetEditor[0], editorSettings);

                // Update mode when snippet type changes
                $('#snippet-type').off('change.codemirror').on('change.codemirror', function() {
                    var newType = $(this).val();
                    var newMode = newType === 'css' ? 'css' : 'javascript';
                    if (snippetCodeMirrorInstance && snippetCodeMirrorInstance.codemirror) {
                        snippetCodeMirrorInstance.codemirror.setOption('mode', newMode);
                    }
                });

                // Ensure CodeMirror updates the textarea on changes
                if (snippetCodeMirrorInstance && snippetCodeMirrorInstance.codemirror) {
                    snippetCodeMirrorInstance.codemirror.on('change', function() {
                        snippetCodeMirrorInstance.codemirror.save();
                    });
                }
            }
        }
    }

    $(document).on('click', '#add-snippet-btn', function () {
        editingIndex = -1;
        $('#modal-title').text('Add Snippet');
        $('#snippet-name').val('');
        $('#snippet-type').val('css');
        $('#snippet-location').val('frontend-head');
        $('#snippet-code').val('');
        $('#snippet-enabled').prop('checked', true);

        // Clear CodeMirror instance if it exists
        if (snippetCodeMirrorInstance && snippetCodeMirrorInstance.codemirror) {
            snippetCodeMirrorInstance.codemirror.setValue('');
            snippetCodeMirrorInstance.codemirror.setOption('mode', 'css');
        }

        $('#snippet-modal').fadeIn(200);

        // Initialize CodeMirror for snippet editor
        setTimeout(function() {
            initCodeMirror();
            // Ensure it's empty after init
            if (snippetCodeMirrorInstance && snippetCodeMirrorInstance.codemirror) {
                snippetCodeMirrorInstance.codemirror.setValue('');
            }
        }, 100);
    });

    $(document).on('click', '.edit-snippet-btn', function () {
        loadSnippetsData();
        editingIndex = parseInt($(this).data('index'));
        var snippet = snippetsData[editingIndex];

        $('#modal-title').text('Edit Snippet');
        $('#snippet-name').val(snippet.name);
        $('#snippet-type').val(snippet.type);
        $('#snippet-location').val(snippet.location);
        $('#snippet-code').val(snippet.code);
        $('#snippet-enabled').prop('checked', snippet.enabled === 'yes');

        // Set CodeMirror content if it exists
        if (snippetCodeMirrorInstance && snippetCodeMirrorInstance.codemirror) {
            var mode = snippet.type === 'css' ? 'css' : 'javascript';
            snippetCodeMirrorInstance.codemirror.setOption('mode', mode);
            snippetCodeMirrorInstance.codemirror.setValue(snippet.code || '');
        }

        $('#snippet-modal').fadeIn(200);

        // Initialize CodeMirror for snippet editor and load content
        setTimeout(function() {
            initCodeMirror();
            // Set content after init
            if (snippetCodeMirrorInstance && snippetCodeMirrorInstance.codemirror) {
                var mode = snippet.type === 'css' ? 'css' : 'javascript';
                snippetCodeMirrorInstance.codemirror.setOption('mode', mode);
                snippetCodeMirrorInstance.codemirror.setValue(snippet.code || '');
            }
        }, 100);
    });

    $(document).on('click', '.delete-snippet-btn', function () {
        if (!confirm('Are you sure you want to delete this snippet?')) {
            return;
        }

        loadSnippetsData();
        var index = parseInt($(this).data('index'));
        snippetsData.splice(index, 1);
        saveSnippetsData();
        refreshSnippetsList();

        // Mark form as changed to enable save button
        $('#switchboard-settings-form').data('changed', true);
    });

    $(document).on('click', '#save-snippet-btn', function () {
        var name = $('#snippet-name').val().trim();
        var type = $('#snippet-type').val();
        var location = $('#snippet-location').val();
        var code = $('#snippet-code').val();
        var enabled = $('#snippet-enabled').is(':checked') ? 'yes' : 'no';

        if (!name) {
            alert('Please enter a snippet name.');
            return;
        }

        if (!code) {
            alert('Please enter some code.');
            return;
        }

        loadSnippetsData();

        var snippet = {
            name: name,
            type: type,
            location: location,
            code: code,
            enabled: enabled
        };

        if (editingIndex >= 0) {
            snippetsData[editingIndex] = snippet;
        } else {
            snippetsData.push(snippet);
        }

        saveSnippetsData();
        refreshSnippetsList();
        $('#snippet-modal').fadeOut(200);

        // Mark form as changed to enable save button
        $('#switchboard-settings-form').data('changed', true);
    });

    $(document).on('click', '#cancel-snippet-btn', function () {
        $('#snippet-modal').fadeOut(200);
    });

    // Close modal on background click
    $(document).on('click', '#snippet-modal', function (e) {
        if (e.target.id === 'snippet-modal') {
            $(this).fadeOut(200);
        }
    });

    // Prevent ESC from closing snippet modal (CodeMirror might use ESC)
    $(document).on('keydown', function (e) {
        if (e.key === 'Escape' && $('#snippet-modal').is(':visible')) {
            e.stopPropagation();
            return false;
        }
    });

    // Toggle snippet enabled/disabled
    $(document).on('change', '.toggle-snippet-enabled', function () {
        loadSnippetsData();
        var index = parseInt($(this).data('index'));
        var isEnabled = $(this).is(':checked');

        snippetsData[index].enabled = isEnabled ? 'yes' : 'no';
        saveSnippetsData();
        refreshSnippetsList();

        // Mark form as changed
        $('#switchboard-settings-form').data('changed', true);
    });

    // Note: Snippets initialization moved to AJAX success handler above
    // since settings panel is loaded dynamically

    // Initialize CodeMirror when settings panel opens
    $(document).on('click', '.module-settings', function(e) {
        // Wait for panel animation AND ajax to complete
        setTimeout(function() {
            initCodeMirror();
        }, 600); // Increased timeout to ensure HTML is loaded
    });

    // Re-init CodeMirror after settings are loaded via AJAX
    $(document).ajaxComplete(function(event, xhr, settings) {
        if (settings.data && settings.data.indexOf('switchboard_get_module_settings') !== -1) {
            setTimeout(function() {
                initCodeMirror();
            }, 100);
        }
    });

    // Also init on page load if any textareas exist
    initCodeMirror();

    // ===== Color Picker Reset Functionality =====
    // Initialize reset buttons for color inputs that have data-default attribute
    function initColorPickerResets() {
        // Only target color inputs with data-default attribute
        $('.settings-panel-body input[type="color"][data-default]').each(function() {
            var $input = $(this);

            // Skip if already has a reset button
            if ($input.data('has-reset-btn')) {
                return;
            }

            var defaultValue = $input.data('default');

            // Create reset button with icon and text
            var $resetBtn = $('<button type="button" class="sb-color-reset-btn" title="Reset to ' + defaultValue + '">Reset</button>');

            // Store references
            $resetBtn.data('target-input', $input);
            $resetBtn.data('default-value', defaultValue);
            $input.data('has-reset-btn', true);

            // Find appropriate place to insert - after hex input if exists, otherwise after color input
            var inputId = $input.attr('id');
            var $hexInput = inputId ? $('#' + inputId + '_hex, #' + inputId.replace('setting_', '') + '-color-text, #custom-color-text').first() : $();

            if ($hexInput.length) {
                $hexInput.after($resetBtn);
            } else {
                $input.after($resetBtn);
            }
        });
    }

    // Handle reset button clicks
    $(document).on('click', '.sb-color-reset-btn', function(e) {
        e.preventDefault();
        e.stopPropagation();

        var $btn = $(this);
        var $input = $btn.data('target-input');
        var defaultValue = $btn.data('default-value');

        if ($input && $input.length && defaultValue) {
            $input.val(defaultValue);

            // Also update any associated hex text display
            var inputId = $input.attr('id');
            if (inputId) {
                $('#' + inputId + '_hex').val(defaultValue);
                $('#' + inputId.replace('setting_', '').replace(/_/g, '-') + '-color-text').val(defaultValue);
                $('#custom-color-text').val(defaultValue);
            }

            // Trigger change event
            $input.trigger('change').trigger('input');
        }
    });

    // Initialize on settings panel open
    $(document).on('click', '.module-settings', function() {
        setTimeout(initColorPickerResets, 600);
    });

    // Re-init after AJAX loads settings
    $(document).ajaxComplete(function(event, xhr, settings) {
        if (settings.data && settings.data.indexOf('switchboard_get_module_settings') !== -1) {
            setTimeout(initColorPickerResets, 150);
        }
    });

    // ===== Feedback Popover Event Handlers =====
    // Feedback reason button clicks - Simple & instant
    $(document).on('click', '.sb-feedback-reason', function() {
        const $btn = $(this);
        const reason = $btn.data('reason');
        const needsDetails = $btn.data('needs-details');
        const moduleName = $('#sb-feedback-module-name').text();

        // Save card reference before confirmDisable clears it
        const cardRef = currentDisablingCard;

        if (needsDetails) {
            // Show details section and store reason
            $('#sb-feedback-details')
                .data('selected-reason', reason)
                .data('card-ref', cardRef)
                .slideDown(200);
            $('#sb-feedback-details-input').val('').focus();
            $('#sb-details-char-count').text('0');
        } else {
            // Instant disable - no forms needed
            confirmDisable(reason, moduleName, null);

            // Show helper link badge beside toggle AFTER disable
            if (reason === 'bug' || reason === 'other' || reason === 'missing-feature') {
                setTimeout(function() {
                    showHelperLinkBadge(reason, cardRef);
                }, 250);
            }
        }
    });

    // Submit button with optional details
    $(document).on('click', '#sb-feedback-submit', function() {
        const reason = $('#sb-feedback-details').data('selected-reason');
        const cardRef = $('#sb-feedback-details').data('card-ref');
        const moduleName = $('#sb-feedback-module-name').text();
        const reasonDetails = $('#sb-feedback-details-input').val().trim();

        // Disable with optional details
        confirmDisable(reason, moduleName, reasonDetails || null);

        // Show helper link badge beside toggle AFTER disable
        setTimeout(function() {
            showHelperLinkBadge(reason, cardRef);
        }, 250);

        // Hide details section
        $('#sb-feedback-details').slideUp(200);
    });

    // Character counter for details textarea
    $(document).on('input', '#sb-feedback-details-input', function() {
        const length = $(this).val().length;
        $('#sb-details-char-count').text(length);
    });

    // Main cancel button
    $(document).on('click', '#sb-feedback-cancel', function() {
        cancelDisable();
    });

    // Click outside popover to cancel
    $(document).on('click', function(e) {
        const popover = $('#sb-feedback-popover');
        if (popover.is(':visible') && !popover.is(e.target) && popover.has(e.target).length === 0 && !$(e.target).closest('.module-checkbox').length) {
            cancelDisable();
        }
    });

    // ===== Quick Launcher - Handle URL parameters =====
    const quickLauncherParams = new URLSearchParams(window.location.search);

    // Handle open_settings parameter
    const openSettings = quickLauncherParams.get('open_settings');
    if (openSettings) {
        // Find and click the settings button for this module
        setTimeout(function () {
            const $settingsBtn = $('.module-card[data-module="' + openSettings + '"] .module-settings');
            if ($settingsBtn.length) {
                $settingsBtn.click();
            }
        }, 500);

        // Clean URL
        quickLauncherParams.delete('open_settings');
        const newUrl = window.location.pathname + (quickLauncherParams.toString() ? '?' + quickLauncherParams.toString() : '');
        window.history.replaceState({}, '', newUrl);
    }

    // Handle highlight parameter
    const highlight = quickLauncherParams.get('highlight');
    if (highlight) {
        setTimeout(function () {
            const $card = $('.module-card[data-module="' + highlight + '"]');
            if ($card.length) {
                // Scroll to card
                $('html, body').animate({
                    scrollTop: $card.offset().top - 100
                }, 500);

                // Highlight effect - Emerald 600 with lighter opacity
                $card.css({
                    'box-shadow': '0 0 0 4px rgba(var(--primary-600-rgb), 0.3)',
                    'transform': 'scale(1.02)'
                });

                setTimeout(function () {
                    $card.css({
                        'box-shadow': '',
                        'transform': ''
                    });
                }, 2000);
            }
        }, 500);

        // Clean URL
        quickLauncherParams.delete('highlight');
        const newUrl2 = window.location.pathname + (quickLauncherParams.toString() ? '?' + quickLauncherParams.toString() : '');
        window.history.replaceState({}, '', newUrl2);
    }

    // Generic media uploader for login customizer and other modules
    var currentUploadTarget;

    $(document).on('click', '.upload-logo-btn', function (e) {
        e.preventDefault();
        currentUploadTarget = $(this).data('target');

        // Always create a fresh uploader to avoid event handler conflicts
        var logoUploader = wp.media({
            title: 'Select Logo',
            button: { text: 'Use this image' },
            multiple: false,
            library: { type: 'image' }
        });

        logoUploader.on('select', function () {
            var attachment = logoUploader.state().get('selection').first().toJSON();

            // Map target to correct field ID
            var fieldId = 'setting_logo';

            // Special handling for login customizer and admin logo
            if (currentUploadTarget === 'login-logo' || currentUploadTarget === 'admin-logo') {
                fieldId = 'setting_logo_url';
            } else if (currentUploadTarget === 'login-bg') {
                fieldId = 'setting_bg_image';
            } else if (currentUploadTarget === 'coming-soon' || currentUploadTarget === 'maintenance-enhanced') {
                fieldId = 'setting_logo';
            }

            // Determine if we should save ID or URL
            // Coming Soon and Maintenance Mode modules need IDs, others need URLs
            var saveValue = attachment.url;
            if (currentUploadTarget === 'coming-soon' || currentUploadTarget === 'maintenance-enhanced') {
                saveValue = attachment.id;
            }

            $('#' + fieldId).val(saveValue);
            // Handle preview container ID - admin-logo and login-logo use '-preview', login-bg uses '-bg-preview', others use '-logo-preview'
            var previewId;
            if (currentUploadTarget === 'admin-logo' || currentUploadTarget === 'login-logo') {
                previewId = currentUploadTarget + '-preview';
            } else if (currentUploadTarget === 'login-bg') {
                previewId = 'login-bg-preview';
            } else {
                previewId = currentUploadTarget + '-logo-preview';
            }
            $('#' + previewId).html('<img src="' + attachment.url + '" class="sb-sp-upload-image">');
            $('.remove-logo-btn[data-target="' + currentUploadTarget + '"]').show();
        });

        logoUploader.open();
    });

    // Background image uploader (same as logo but for background)
    $(document).on('click', '.upload-bg-btn', function (e) {
        e.preventDefault();
        currentUploadTarget = $(this).data('target');

        // Always create a fresh uploader to avoid event handler conflicts
        var bgUploader = wp.media({
            title: 'Select Background Image',
            button: { text: 'Use this image' },
            multiple: false,
            library: { type: 'image' }
        });

        bgUploader.on('select', function () {
            var attachment = bgUploader.state().get('selection').first().toJSON();

            // For coming-soon, save ID instead of URL
            var saveValue = attachment.id;
            $('#setting_bg_image').val(saveValue);
            $('#' + currentUploadTarget + '-bg-preview').html('<img src="' + attachment.url + '" style="max-width: 200px; height: auto; border-radius: 8px; display: block; margin-bottom: 10px;">');
            $('.remove-bg-btn[data-target="' + currentUploadTarget + '"]').show();
        });

        bgUploader.open();
    });

    $(document).on('click', '.remove-logo-btn', function (e) {
        e.preventDefault();
        var target = $(this).data('target');

        // Map target to correct field ID
        var fieldId = 'setting_logo';

        // Special handling for login customizer and admin logo
        if (target === 'login-logo' || target === 'admin-logo') {
            fieldId = 'setting_logo_url';
        } else if (target === 'login-bg') {
            fieldId = 'setting_bg_image';
        } else if (target === 'coming-soon' || target === 'maintenance-enhanced') {
            fieldId = 'setting_logo';
        }

        // Clear hidden input
        $('#' + fieldId).val('');

        // Clear preview - handle both ID formats
        var previewId;
        if (target === 'admin-logo' || target === 'login-logo') {
            previewId = target + '-preview';
        } else {
            previewId = target + '-logo-preview';
        }
        $('#' + previewId).empty();

        // For login customizer, also clear these specific IDs
        if (target === 'login-logo') {
            $('#login-logo-preview').empty();
        } else if (target === 'login-bg') {
            $('#login-bg-preview').empty();
        }

        // Hide remove button
        $(this).hide();
    });

    $(document).on('click', '.remove-bg-btn', function (e) {
        e.preventDefault();
        var target = $(this).data('target');

        $('#setting_bg_image').val('');

        // Show placeholder for modules that use it
        if (target === 'maintenance-enhanced' || target === 'coming-soon') {
            $('#' + target + '-bg-preview').html('<div class="switchboard-image-placeholder"><span class="dashicons dashicons-format-image" style="font-size: 48px; opacity: 0.3;"></span><p>No image selected</p></div>');
        } else {
            $('#' + target + '-bg-preview').html('');
        }
        $(this).hide();
    });

    // ===========================
    // Login Customizer Source Toggle (Upload/URL)
    // ===========================

    // Handle source toggle button clicks (for 'bg' target - logo has its own handler)
    $(document).on('click', '.sb-source-toggle:not([data-target="logo"]) .sb-source-btn', function(e) {
        e.preventDefault();
        var $btn = $(this);
        var $toggle = $btn.closest('.sb-source-toggle');
        var target = $toggle.data('target'); // 'bg' etc.
        var source = $btn.data('source'); // 'upload' or 'url'

        // Update active state on buttons
        $toggle.find('.sb-source-btn').removeClass('active');
        $btn.addClass('active');

        // Update hidden input
        $('#setting_' + target + '_source').val(source);

        // Show/hide content areas - find container within the same content area
        var $container = $toggle.closest('.sb-bg-type-content, .sb-sp-field-horizontal-right, .sb-sp-group');
        $container.find('.sb-source-content[data-target="' + target + '"]').hide();
        $container.find('.sb-source-' + source + '[data-target="' + target + '"]').show();
    });

    // Handle URL input for live preview with loading/success/error states
    var urlInputDebounce = null;

    function validateAndPreviewUrl($input, $preview, $status, maxWidth) {
        var url = $input.val().trim();

        // Clear if empty
        if (!url) {
            $preview.empty();
            $status.removeClass('loading success error').empty();
            return;
        }

        // Basic URL validation
        if (!url.match(/^https?:\/\/.+/i)) {
            $status.removeClass('loading success').addClass('error').html('&#10005;');
            $preview.html('<div class="sb-url-preview-error">Please enter a valid URL starting with http:// or https://</div>');
            return;
        }

        // Show loading
        $status.removeClass('success error').addClass('loading').html('&#8987;');
        $preview.empty();

        // Test image loading
        var img = new Image();
        img.onload = function() {
            $status.removeClass('loading error').addClass('success').html('&#10003;');
            var style = maxWidth ? ' style="max-width: ' + maxWidth + '; height: auto;"' : '';
            $preview.html('<img src="' + url + '" alt="Preview" class="sb-sp-upload-image"' + style + '>');
        };
        img.onerror = function() {
            $status.removeClass('loading success').addClass('error').html('&#10005;');
            $preview.html('<div class="sb-url-preview-error">Could not load image. Check the URL and ensure the server allows external access.</div>');
        };
        img.src = url;
    }

    $(document).on('input', '#setting_logo_external_url', function() {
        var $input = $(this);
        var $preview = $('#login-logo-url-preview');
        var $status = $('#logo-url-status');

        clearTimeout(urlInputDebounce);
        urlInputDebounce = setTimeout(function() {
            validateAndPreviewUrl($input, $preview, $status, null);
        }, 500);
    });

    $(document).on('input', '#setting_bg_external_url', function() {
        var $input = $(this);
        var $preview = $('#login-bg-url-preview');
        var $status = $('#bg-url-status');

        clearTimeout(urlInputDebounce);
        urlInputDebounce = setTimeout(function() {
            validateAndPreviewUrl($input, $preview, $status, '200px');
        }, 500);
    });

    // ===========================
    // Login Customizer Form Position Selector
    // ===========================

    $(document).on('click', '.sb-position-option', function(e) {
        e.preventDefault();
        var $option = $(this);
        var position = $option.data('position');

        // Update active state
        $('.sb-position-option').removeClass('active');
        $option.addClass('active');

        // Update hidden input
        $('#setting_form_position').val(position);

        // Check the radio (for form submission)
        $option.find('input[type="radio"]').prop('checked', true);
    });

    // ===========================
    // Login Customizer Form Theme Selector
    // ===========================

    $(document).on('click', '.sb-theme-option', function(e) {
        e.preventDefault();
        var $option = $(this);
        var theme = $option.data('theme');

        // Update active state
        $('.sb-theme-option').removeClass('active');
        $option.addClass('active');

        // Update hidden input
        $('#setting_form_theme').val(theme);

        // Check the radio (for form submission)
        $option.find('input[type="radio"]').prop('checked', true);

        // Show/hide custom theme options
        if (theme === 'custom') {
            $('#custom-theme-options').removeClass('hidden');
        } else {
            $('#custom-theme-options').addClass('hidden');
        }
    });

    // ===========================
    // Login Customizer Background Type Selector
    // ===========================

    $(document).on('click', '.sb-source-toggle[data-target="bg-type"] .sb-source-btn', function(e) {
        e.preventDefault();
        var $btn = $(this);
        var $toggle = $btn.closest('.sb-source-toggle');
        var bgType = $btn.data('type');

        // Update active state
        $toggle.find('.sb-source-btn').removeClass('active');
        $btn.addClass('active');

        // Update hidden input
        $('#setting_bg_type').val(bgType);

        // Show/hide type-specific content
        $('.sb-bg-type-content').hide();
        $('#bg-type-' + bgType).show();
    });

    // ===========================
    // Login Customizer Range Slider Value Display
    // ===========================

    $(document).on('input', '#setting_form_bg_opacity', function() {
        $('#opacity-value').text($(this).val() + '%');
    });

    $(document).on('input', '#setting_bg_overlay_opacity', function() {
        $('#overlay-opacity-value').text($(this).val() + '%');
    });

    // ===========================
    // Login Customizer Overlay Visibility Toggle
    // ===========================

    $(document).on('change', '#setting_bg_overlay', function() {
        var overlay = $(this).val();
        if (overlay === 'none') {
            $('#overlay-opacity-field').addClass('hidden');
        } else {
            $('#overlay-opacity-field').removeClass('hidden');
        }
    });

    // ===========================
    // Login Customizer Logo Source with Site Icon
    // ===========================

    // Update the source toggle to handle site-icon option
    $(document).on('click', '.sb-source-toggle[data-target="logo"] .sb-source-btn', function(e) {
        e.preventDefault();
        var $btn = $(this);
        var $toggle = $btn.closest('.sb-source-toggle');
        var source = $btn.data('source'); // 'site-icon', 'upload', or 'url'

        // Update active state on buttons
        $toggle.find('.sb-source-btn').removeClass('active');
        $btn.addClass('active');

        // Update hidden input
        $('#setting_logo_source').val(source);

        // Show/hide content areas - find all source contents within the parent group
        var $container = $toggle.closest('.sb-sp-group');
        $container.find('.sb-source-content[data-target="logo"]').hide();
        $container.find('.sb-source-' + source + '[data-target="logo"]').show();
    });

    // Sync background color pickers (color tab and pattern tab)
    $(document).on('change input', '.sb-sync-bg-color', function() {
        var newValue = $(this).val();
        $('.sb-sync-bg-color').not(this).val(newValue);
    });

    // Coming Soon - Copy subscribers to clipboard
    $(document).on('click', '#copy-subscribers-btn', function (e) {
        e.preventDefault();
        var textarea = document.getElementById('coming-soon-subscribers');
        var button = $(this);

        if (!textarea) return;

        // Select and copy
        textarea.select();
        textarea.setSelectionRange(0, 99999); // For mobile

        try {
            document.execCommand('copy');

            // Visual feedback
            var originalText = button.text();
            button.text('Copied!').css('background', '#46b450');

            setTimeout(function() {
                button.text(originalText).css('background', '');
            }, 2000);
        } catch (err) {
            button.text('Failed');
            setTimeout(function() {
                button.text('Copy');
            }, 2000);
        }

        // Deselect
        window.getSelection().removeAllRanges();
    });

    // ===========================
    // Use Cases Tooltip
    // ===========================

    // Create tooltip element
    const $tooltip = $('<div class="switchboard-tooltip"></div>').appendTo('body');
    let tooltipHideTimeout;
    let tooltipShowTimeout;

    // Handle tooltip on mouseenter
    $(document).on('mouseenter', '.has-tooltip', function() {
        const $btn = $(this);
        const html = $btn.attr('data-tooltip-html');

        if (!html) return;

        // Clear any pending hide timeout
        clearTimeout(tooltipHideTimeout);

        // Add delay before showing tooltip
        tooltipShowTimeout = setTimeout(function() {
            // Set content and show
            $tooltip.html(html).addClass('visible');

            // Position tooltip
            const btnRect = $btn[0].getBoundingClientRect();
            const tooltipRect = $tooltip[0].getBoundingClientRect();

            // Center above button
            let left = btnRect.left + (btnRect.width / 2) - (tooltipRect.width / 2);
            let top = btnRect.top - tooltipRect.height - 10;

            // Keep tooltip on screen
            if (left < 10) left = 10;
            if (left + tooltipRect.width > window.innerWidth - 10) {
                left = window.innerWidth - tooltipRect.width - 10;
            }
            if (top < 10) {
                // Show below if not enough space above
                top = btnRect.bottom + 10;
            }

            $tooltip.css({
                left: left + 'px',
                top: top + 'px'
            });
        }, 500); // 500ms delay before showing tooltip
    });

    // Handle tooltip on mouseleave (with delay)
    $(document).on('mouseleave', '.has-tooltip', function() {
        // Clear any pending show timeout to prevent tooltip from appearing after mouse leaves
        clearTimeout(tooltipShowTimeout);

        // Delay hiding to allow moving cursor to tooltip
        tooltipHideTimeout = setTimeout(function() {
            if (!$tooltip.is(':hover')) {
                $tooltip.removeClass('visible');
            }
        }, 500); // 500ms delay - enough time to move cursor
    });

    // Keep tooltip visible when hovering over it
    $tooltip.on('mouseenter', function() {
        clearTimeout(tooltipHideTimeout);
    });

    // Hide tooltip when leaving the tooltip itself
    $tooltip.on('mouseleave', function() {
        $tooltip.removeClass('visible');
    });

    // Hide tooltip on scroll
    $(window).on('scroll', function() {
        clearTimeout(tooltipHideTimeout);
        $tooltip.removeClass('visible');
    });

    // Initialize view mode on page load
    initViewMode();

    // Update status counts after view is initialized
    // Use setTimeout to ensure DOM is ready and view is visible
    setTimeout(function() {
        updateStatusCounts();
    }, 100);

    // First-Time Popup - Step by Step Tour
    var currentTourStep = 1;
    var totalTourSteps = 3;

    // Check if we should show the tour (multiple fallback methods)
    var showTourFromUrl = window.location.search.indexOf('show_tour=1') > -1;
    var showTourFromSession = false;

    // Try sessionStorage, with fallback
    try {
        showTourFromSession = sessionStorage.getItem('switchboard_show_welcome_tour') === '1';
    } catch (e) {
        // SessionStorage not available, rely on URL parameter
    }

    var shouldShowTour = switchboardSettings.show_first_time_popup || showTourFromSession || showTourFromUrl;

    if (shouldShowTour) {
        // Clear the session storage flag if it was set
        try {
            sessionStorage.removeItem('switchboard_show_welcome_tour');
        } catch (e) {
            // Ignore if sessionStorage not available
        }

        // Clean up URL parameter if it was used
        if (showTourFromUrl) {
            var cleanUrl = window.location.href.replace(/([?&])show_tour=1(&|$)/, '$1').replace(/[?&]$/, '');
            window.history.replaceState({}, document.title, cleanUrl);
        }

        // Show popup after a short delay for better UX
        setTimeout(function() {
            $('#first-time-popup').fadeIn(300);
        }, 500);
    }

    // Function to update tour step
    function updateTourStep(step) {
        currentTourStep = step;

        // Update step indicator
        $('#step-indicator').text(step + '/' + totalTourSteps);

        // Hide all steps
        $('.tour-step').removeClass('active');

        // Show current step with animation
        $('.tour-step[data-step="' + step + '"]').addClass('active');

        // Update buttons visibility and text
        if (step === 1) {
            $('#tour-back').hide();
        } else {
            $('#tour-back').show();
        }

        if (step === totalTourSteps) {
            $('#tour-next').text('Done');
        } else {
            $('#tour-next').text('Next');
        }
    }

    // Handle Next button
    $('#tour-next').on('click', function() {
        if (currentTourStep < totalTourSteps) {
            updateTourStep(currentTourStep + 1);
        } else {
            // Last step - close tour
            closeTour();
        }
    });

    // Handle Back button
    $('#tour-back').on('click', function() {
        if (currentTourStep > 1) {
            updateTourStep(currentTourStep - 1);
        }
    });

    // Function to close tour
    function closeTour() {
        $('#first-time-popup').fadeOut(300);

        // Save dismissed state via AJAX
        $.ajax({
            url: switchboardSettings.ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_dismiss_first_time_popup',
                nonce: switchboardSettings.nonce
            }
        });
    }

    // Handle Skip and Close buttons
    $('#tour-skip, #close-first-time-popup').on('click', function() {
        closeTour();
    });

    // Close popup when clicking outside the modal content
    $('#first-time-popup').on('click', function(e) {
        if (e.target === this) {
            closeTour();
        }
    });

    // =========================================================================
    // CONFIGURATIONS PAGE HANDLERS
    // =========================================================================

    // Toggle save preset form - use event delegation for reliability
    $(document).on('click', '#toggle-save-preset', function(e) {
        e.preventDefault();
        e.stopPropagation();

        const $form = $('#save-preset-form-inline');
        const $header = $(this);

        if ($form.is(':visible')) {
            $form.slideUp(200);
            $header.removeClass('open');
        } else {
            $form.slideDown(200);
            $header.addClass('open');
            // Focus the name input
            setTimeout(function() {
                $('#preset_name_inline').focus();
            }, 250);
        }
    });

    // Export current configuration button (Configurations page)
    $('#export-current-config').on('click', function() {
        const $btn = $(this);
        const originalText = $btn.text();

        $btn.prop('disabled', true).text('Exporting...');

        exportCurrentConfiguration(function() {
            $btn.prop('disabled', false).text(originalText);
        });
    });

    // Import dropzone handling
    const $dropzone = $('#import-dropzone');
    const $fileInput = $('#import-file-input-page');
    const $browseBtn = $('#browse-file-btn');
    const $preview = $('#import-preview-page');
    const $clearBtn = $('#clear-import-file');

    // Stored import data
    let pendingImportData = null;

    // Browse button clicks trigger file input
    $browseBtn.on('click', function(e) {
        e.preventDefault();
        e.stopPropagation();
        $fileInput[0].click();
    });

    // Clicking dropzone also triggers file input
    $dropzone.on('click', function(e) {
        if (!$(e.target).is('button')) {
            e.preventDefault();
            $fileInput[0].click();
        }
    });

    // Drag and drop events
    $dropzone.on('dragover dragenter', function(e) {
        e.preventDefault();
        e.stopPropagation();
        $(this).addClass('dragover');
    });

    $dropzone.on('dragleave dragend drop', function(e) {
        e.preventDefault();
        e.stopPropagation();
        $(this).removeClass('dragover');
    });

    $dropzone.on('drop', function(e) {
        const files = e.originalEvent.dataTransfer.files;
        if (files.length > 0 && files[0].name.endsWith('.switchboard')) {
            processImportFile(files[0]);
        } else {
            alert('Please drop a valid .switchboard file.');
        }
    });

    // File input change
    $fileInput.on('change', function(e) {
        const file = e.target.files[0];
        if (file) {
            processImportFile(file);
        }
    });

    // Process import file and show preview
    function processImportFile(file) {
        const reader = new FileReader();
        reader.onload = function(event) {
            try {
                const encodedData = event.target.result.trim();
                const decodedData = atob(encodedData);
                const preset = JSON.parse(decodedData);

                if (!preset.modules) {
                    alert('Invalid preset file format.');
                    return;
                }

                // Count actual modules (handle v2.0 format)
                let moduleCount;
                if (preset.modules.meta && preset.modules.modules) {
                    moduleCount = Object.keys(preset.modules.modules).length;
                } else {
                    moduleCount = Object.keys(preset.modules).length;
                }

                // Store the data for import
                pendingImportData = encodedData;

                // Show preview
                $('#preview-name-page').text(preset.name || 'Unnamed');
                $('#preview-description-page').text(preset.description || 'No description');
                $('#preview-modules-page').text(moduleCount + ' modules');

                // Hide dropzone, show preview
                $dropzone.hide();
                $preview.show();

            } catch (e) {
                console.error('Import error:', e);
                alert('Failed to read the preset file. It may be corrupted or in an invalid format.');
            }
        };
        reader.readAsText(file);
    }

    // Clear import file
    $clearBtn.on('click', function() {
        pendingImportData = null;
        $fileInput.val('');
        $preview.hide();
        $dropzone.show();
    });

    // Confirm import button
    $('#confirm-import-page').on('click', function() {
        if (!pendingImportData) {
            alert('No file selected for import.');
            return;
        }

        const $btn = $(this);
        const originalText = $btn.text();
        const applyImmediately = $('#import-apply-immediately-page').is(':checked');

        $btn.prop('disabled', true).text('Importing...');

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_import_preset',
                preset_data: pendingImportData,
                apply_immediately: applyImmediately ? 'true' : 'false',
                nonce: switchboardSettings.settings_nonce
            },
            success: function(response) {
                if (response.success) {
                    let message = 'Configuration imported successfully!';
                    if (response.data && response.data.message) {
                        message = response.data.message;
                    }
                    alert(message);
                    location.reload();
                } else {
                    alert('Import failed: ' + (response.data?.message || 'Unknown error'));
                    $btn.prop('disabled', false).text(originalText);
                }
            },
            error: function() {
                alert('Import failed. Please try again.');
                $btn.prop('disabled', false).text(originalText);
            }
        });
    });

    // =========================================================================
    // SETTINGS PAGE HANDLERS
    // =========================================================================

    // Beta mode toggle (Settings page)
    $('#beta-mode-toggle-page').on('change', function() {
        const isChecked = $(this).is(':checked');
        const $toggle = $(this);
        const $card = $toggle.closest('.settings-toggle-card');

        // Toggle card active state
        $card.toggleClass('active', isChecked);

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_toggle_beta_mode',
                enabled: isChecked ? 'yes' : 'no',
                nonce: switchboardSettings.nonce
            },
            success: function(response) {
                if (response.success) {
                    // Reload to refresh module list
                    location.reload();
                } else {
                    // Revert toggle and card state on failure
                    $toggle.prop('checked', !isChecked);
                    $card.toggleClass('active', !isChecked);
                    alert('Failed to update beta mode: ' + (response.data?.message || 'Unknown error'));
                }
            },
            error: function() {
                $toggle.prop('checked', !isChecked);
                $card.toggleClass('active', !isChecked);
                alert('Failed to update beta mode. Please try again.');
            }
        });
    });

    // Telemetry toggle (Settings page)
    $('#telemetry-toggle-page').on('change', function() {
        const isEnabled = $(this).is(':checked');
        const $toggle = $(this);
        const $card = $toggle.closest('.settings-toggle-card');

        // Toggle card active state
        $card.toggleClass('active', isEnabled);

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_toggle_telemetry',
                enabled: isEnabled ? 'yes' : 'no',
                nonce: switchboardSettings.nonce
            },
            success: function(response) {
                if (response.success) {
                    showToast('Usage Analytics', isEnabled ? 'enabled' : 'disabled');
                } else {
                    // Revert toggle and card state on failure
                    $toggle.prop('checked', !isEnabled);
                    $card.toggleClass('active', !isEnabled);
                    alert('Failed to update telemetry settings: ' + (response.data?.message || 'Unknown error'));
                }
            },
            error: function() {
                $toggle.prop('checked', !isEnabled);
                $card.toggleClass('active', !isEnabled);
                alert('Failed to update telemetry settings. Please try again.');
            }
        });
    });

    // Feedback toggle (Settings page)
    $('#feedback-toggle-page').on('change', function() {
        const isEnabled = $(this).is(':checked');
        const $toggle = $(this);
        const $card = $toggle.closest('.settings-toggle-card');

        // Toggle card active state
        $card.toggleClass('active', isEnabled);

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_toggle_feedback',
                enabled: isEnabled ? 'yes' : 'no',
                nonce: switchboardSettings.nonce
            },
            success: function(response) {
                if (response.success) {
                    showToast('Feedback Prompts', isEnabled ? 'enabled' : 'disabled');
                } else {
                    // Revert toggle and card state on failure
                    $toggle.prop('checked', !isEnabled);
                    $card.toggleClass('active', !isEnabled);
                    alert('Failed to update feedback settings: ' + (response.data?.message || 'Unknown error'));
                }
            },
            error: function() {
                $toggle.prop('checked', !isEnabled);
                $card.toggleClass('active', !isEnabled);
                alert('Failed to update feedback settings. Please try again.');
            }
        });
    });

    // Clear module cache (Settings page)
    $('#clear-module-cache-page').on('click', function() {
        const $btn = $(this);
        const originalText = $btn.text();

        if (!confirm('Clear module cache and refresh? This will reload the page.')) {
            return;
        }

        $btn.prop('disabled', true).text('Clearing...');

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_clear_cache',
                nonce: switchboardSettings.nonce
            },
            success: function(response) {
                if (response.success) {
                    localStorage.removeItem('switchboard-view-mode');
                    localStorage.removeItem('switchboard_sort_by');
                    localStorage.removeItem('switchboard_desc_state');
                    localStorage.removeItem('switchboard_usecases_state');

                    $btn.css('background', 'var(--primary-500)').css('color', 'white').text('Cache Cleared!');

                    setTimeout(function() {
                        location.reload();
                    }, 800);
                } else {
                    alert('Failed to clear cache: ' + (response.data?.message || 'Unknown error'));
                    $btn.prop('disabled', false).text(originalText);
                }
            },
            error: function() {
                alert('Failed to clear cache. Please try again.');
                $btn.prop('disabled', false).text(originalText);
            }
        });
    });

    // Clear inactive data (Settings page)
    $('#clear-inactive-data-page').on('click', function() {
        const $btn = $(this);
        const originalText = $btn.text();

        if (!confirm('Clear Inactive Module Data?\n\nThis will delete data from modules you have DISABLED:\n- Database tables from inactive modules\n- Settings and configurations\n- Analytics and logs\n\nYour ACTIVE modules will NOT be affected.\n\nThis action cannot be undone. Continue?')) {
            return;
        }

        const confirmation = prompt('To confirm, please type: CLEAR INACTIVE');
        if (confirmation !== 'CLEAR INACTIVE') {
            alert('Confirmation failed. Data was not deleted.');
            return;
        }

        $btn.prop('disabled', true).text('Cleaning...');

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_clear_inactive_data',
                nonce: switchboardSettings.nonce
            },
            success: function(response) {
                if (response.success) {
                    $btn.css('background', 'var(--primary-500)').css('color', 'white').text('Cleaned!');
                    alert('Inactive module data has been successfully deleted. Active modules are safe.');
                    setTimeout(function() {
                        location.reload();
                    }, 1000);
                } else {
                    alert('Failed to clear data: ' + (response.data?.message || 'Unknown error'));
                    $btn.prop('disabled', false).text(originalText);
                }
            },
            error: function() {
                alert('Failed to clear data. Please try again.');
                $btn.prop('disabled', false).text(originalText);
            }
        });
    });

    // Clear all data (Settings page)
    $('#clear-all-data-page').on('click', function() {
        const $btn = $(this);
        const originalText = $btn.text();

        if (!confirm('PERMANENTLY DELETE ALL SWITCHBOARD DATA?\n\nThis will delete:\n- ALL module settings and data\n- ALL database tables created by modules\n- ALL presets and configurations\n- License information\n\nThis action CANNOT be undone!\n\nAre you absolutely sure?')) {
            return;
        }

        const confirmation = prompt('This is irreversible! Type: DELETE ALL DATA');
        if (confirmation !== 'DELETE ALL DATA') {
            alert('Confirmation failed. Data was not deleted.');
            return;
        }

        $btn.prop('disabled', true).text('Deleting...');

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_clear_all_data',
                nonce: switchboardSettings.nonce
            },
            success: function(response) {
                if (response.success) {
                    $btn.css('background', '#dc2626').css('color', 'white').text('All Data Deleted');
                    alert('All Switchboard data has been permanently deleted.');
                    setTimeout(function() {
                        location.reload();
                    }, 1000);
                } else {
                    alert('Failed to delete data: ' + (response.data?.message || 'Unknown error'));
                    $btn.prop('disabled', false).text(originalText);
                }
            },
            error: function() {
                alert('Failed to delete data. Please try again.');
                $btn.prop('disabled', false).text(originalText);
            }
        });
    });
});
