/**
 * VMPFence Tools JavaScript
 *
 * @package VMPFence
 * @subpackage Tools
 * @since 2.1.0
 * @since 2.2.0 Redesigned Diagnostics Tools UI and Import / Export functionality
 * @since 2.2.2 Added live focus, dynamic update intervals
 */

(function($) {
    'use strict';

    /**
     * VMPFence Tools Manager
     */
    const VMPFenceTools = {
        currentTab: 'live-traffic',
        currentPage: 1,
        perPage: 25,
        currentFilter: 'all',
        loading: false,

        // Advanced Filter Properties
        filters: [],
        groupBy: null,
        startDate: null,
        endDate: null,
        filterParams: [],
        groupByOptions: [],
        lastPollTime: 0,
        pollingEnabled: false,
        pollingInterval: null,
        pollingPaused: false,

        /**
         * Initialize
         */
        init: function() {
            this.bindEvents();
            this.loadTab(this.currentTab);
            this.initFilters();
            this.loadOptions();
            this.bindEventsStep2();
            // Auto-start polling
            this.startPolling();
            // Bind Whois modal events
            this.bindWhoisModalEvents();
            // Bind Recent Traffic modal events
            this.bindRecentTrafficModalEvents();
            // Initialize diagnostics accordion
            this.initDiagnosticsAccordion();
        },

        /**
         * Bind events
         */
        bindEvents: function() {
            const self = this;

            // Tab switching
            $(document).on('click', '.vmpfence-tabs-nav button', function(e) {
                e.preventDefault();
                const tabId = $(this).data('tab');
                self.switchTab(tabId);
            });

            // Live Traffic Options toggle
            $(document).on('click', '#live-traffic-options-toggle', function() {
                const content = $('#live-traffic-options-content');
                const header = $(this);
                const icon = header.find('.vmpfence-toggle-icon');
                
                if (content.is(':visible')) {
                    content.slideUp(300);
                    header.removeClass('expanded');
                    icon.text('▶');
                } else {
                    content.slideDown(300);
                    header.addClass('expanded');
                }
            });

            // Traffic logging mode buttons
            $(document).on('click', '.vmpfence-mode-btn', function() {
                $('.vmpfence-mode-btn').removeClass('active');
                $(this).addClass('active');
                $('#traffic_logging_mode').val($(this).data('value'));
            });

            // Save changes button
            $(document).on('click', '#save-changes', function(e) {
                e.preventDefault();
                self.saveOptions();
            });

            // Cancel changes button
            $(document).on('click', '#cancel-changes', function(e) {
                e.preventDefault();
                self.loadOptions();
            });

            // Restore defaults button
            $(document).on('click', '#restore-defaults', function(e) {
                e.preventDefault();
                VMPFenceNotifications.showConfirmModal({
                    title: 'Restore Defaults',
                    message: 'Are you sure you want to restore default settings?',
                    confirmText: 'Yes, Restore',
                    cancelText: 'Cancel'
                }).then(function(confirmed) {
                    if (confirmed) {
                        self.restoreDefaults();
                    }
                });
            });

            // WHOIS Lookup button
            $(document).on('click', '#whois-lookup-btn', function(e) {
                e.preventDefault();
                self.performWhoisLookup();
            });

            // Allow Enter key in WHOIS input
            $(document).on('keypress', '#whois-input', function(e) {
                if (e.which === 13) {
                    e.preventDefault();
                    self.performWhoisLookup();
                }
            });
        },

        /**
         * Bind Whois Modal Events
         */
        bindWhoisModalEvents: function() {
            const self = this;
            
            // Unbind all modal events first to prevent duplicates if init() is called multiple times
            $(document).off('click', '.vmpfence-whois-modal-close');
            $(document).off('click', '.vmpfence-whois-modal-close-btn');
            $(document).off('click', '#vmpfence-whois-modal .vmpfence-notification-modal-overlay');
            $(document).off('click', '.vmpfence-whois-modal-content');
            $(document).off('keydown.vmpfenceWhoisModal');
            
            // Close button (X)
            $(document).on('click', '.vmpfence-whois-modal-close', function() {
                self.hideWhoisModal();
            });
            
            // Close button (footer)
            $(document).on('click', '.vmpfence-whois-modal-close-btn', function() {
                self.hideWhoisModal();
            });
            
            // Click overlay to close
            $(document).on('click', '#vmpfence-whois-modal .vmpfence-notification-modal-overlay', function() {
                self.hideWhoisModal();
            });
            
            // Prevent clicks inside modal content from closing (but allow event bubbling for buttons)
            $(document).on('click', '.vmpfence-whois-modal-content', function(e) {
                // Only stop propagation if clicking the content itself, not children (buttons)
                if (e.target === this) {
                    e.stopPropagation();
                }
            });
            
            // ESC key to close (namespaced event to prevent leaks)
            $(document).on('keydown.vmpfenceWhoisModal', function(e) {
                if (e.key === 'Escape' && $('#vmpfence-whois-modal').hasClass('show')) {
                    self.hideWhoisModal();
                }
            });
        },

        /**
         * Bind Recent Traffic Modal Events
         */
        bindRecentTrafficModalEvents: function() {
            const self = this;
            
            // Unbind all modal events first to prevent duplicates
            $(document).off('click', '.vmpfence-recent-traffic-modal-close');
            $(document).off('click', '.vmpfence-recent-traffic-modal-close-btn');
            $(document).off('click', '#vmpfence-recent-traffic-modal .vmpfence-notification-modal-overlay');
            $(document).off('click', '.vmpfence-recent-traffic-modal-content');
            $(document).off('keydown.vmpfenceRecentTrafficModal');
            
            // Close button (X)
            $(document).on('click', '.vmpfence-recent-traffic-modal-close', function() {
                self.hideRecentTrafficModal();
            });
            
            // Close button (footer)
            $(document).on('click', '.vmpfence-recent-traffic-modal-close-btn', function() {
                self.hideRecentTrafficModal();
            });
            
            // Click overlay to close
            $(document).on('click', '#vmpfence-recent-traffic-modal .vmpfence-notification-modal-overlay', function() {
                self.hideRecentTrafficModal();
            });
            
            // Prevent clicks inside modal content from closing
            $(document).on('click', '.vmpfence-recent-traffic-modal-content', function(e) {
                if (e.target === this) {
                    e.stopPropagation();
                }
            });
            
            // ESC key to close
            $(document).on('keydown.vmpfenceRecentTrafficModal', function(e) {
                if (e.key === 'Escape' && $('#vmpfence-recent-traffic-modal').hasClass('show')) {
                    self.hideRecentTrafficModal();
                }
            });
        },

        /**
         * Bind events (continued)
         */
        bindEventsStep2: function() {
            const self = this;

            // Filter change
            $(document).on('change', '#vmpfence-traffic-filter', function() {
                self.currentFilter = $(this).val();
                self.currentPage = 1;
                self.loadLiveTraffic();
            });

            // Custom filter dropdown toggle
            $(document).on('click', '#vmpfence-filter-toggle', function(e) {
                e.stopPropagation();
                const list = $('#vmpfence-filter-list');
                const button = $(this);
                
                if (list.is(':visible')) {
                    list.hide();
                    button.removeClass('active');
                } else {
                    list.show();
                    button.addClass('active');
                    // Focus search input when opening
                    $('#vmpfence-filter-search').focus();
                }
            });

            // Filter list item selection
            $(document).on('click', '.vmpfence-filter-list-items li', function() {
                const value = $(this).data('value');
                const text = $(this).text();
                
                // Update selected display
                $('.vmpfence-filter-text').text(text);
                
                // Update selected state
                $('.vmpfence-filter-list-items li').removeClass('selected');
                $(this).addClass('selected');
                
                // Close dropdown
                $('#vmpfence-filter-list').hide();
                $('#vmpfence-filter-toggle').removeClass('active');
                
                // Clear search
                $('#vmpfence-filter-search').val('');
                $('.vmpfence-filter-list-items li').show();
                
                // Update filter and reload data
                self.currentFilter = value;
                self.currentPage = 1;
                self.loadLiveTraffic();
            });

            // Filter search functionality
            $(document).on('keyup', '#vmpfence-filter-search', function() {
                const searchTerm = $(this).val().toLowerCase();
                
                $('.vmpfence-filter-list-items li').each(function() {
                    const text = $(this).text().toLowerCase();
                    if (text.indexOf(searchTerm) > -1) {
                        $(this).show();
                    } else {
                        $(this).hide();
                    }
                });
            });

            // Prevent dropdown close when clicking inside
            $(document).on('click', '.vmpfence-filter-list-wrapper', function(e) {
                e.stopPropagation();
            });

            // Close dropdown when clicking outside
            $(document).on('click', function(e) {
                if (!$(e.target).closest('.vmpfence-filter-dropdown').length) {
                    $('#vmpfence-filter-list').hide();
                    $('#vmpfence-filter-toggle').removeClass('active');
                    // Clear search
                    $('#vmpfence-filter-search').val('');
                    $('.vmpfence-filter-list-items li').show();
                }
            });

            // Expand results toggle
            $(document).on('change', '#vmpfence-expand-results', function() {
                const isChecked = $(this).is(':checked');
                
                if (isChecked) {
                    // Expand all rows that have a View button
                    $('#live-traffic-table-container tbody tr').each(function() {
                        const $row = $(this);
                        const $viewBtn = $row.find('.vmpfence-view-details');
                        
                        // Only process rows with a view button (not detail rows)
                        if ($viewBtn.length > 0) {
                            const $nextRow = $row.next('.vmpfence-detail-row');
                            
                            // Only expand if not already expanded
                            if ($nextRow.length === 0) {
                                self.showDetails($row);
                            }
                        }
                    });
                } else {
                    // Collapse all detail rows
                    $('#live-traffic-table-container .vmpfence-detail-row').slideUp(200, function() {
                        $(this).remove();
                    });
                    
                    // Reset all icons back to non-expanded state
                    $('#live-traffic-table-container tbody tr .vmpfence-view-details .dashicons')
                        .removeClass('dashicons-hidden')
                        .addClass('dashicons-visibility');
                }
            });

            // Pagination
            $(document).on('click', '.vmpfence-pagination-btn', function(e) {
                e.preventDefault();
                const action = $(this).data('action');
                
                if (action === 'prev' && self.currentPage > 1) {
                    self.currentPage--;
                } else if (action === 'next') {
                    self.currentPage++;
                }

                if (self.currentTab === 'live-traffic') {
                    self.loadLiveTraffic();
                } else if (self.currentTab === 'audit-log') {
                    self.loadAuditLog();
                }
            });

            // View details
            $(document).on('click', '.vmpfence-view-details', function(e) {
                e.preventDefault();
                const row = $(this).closest('tr');
                self.showDetails(row);
            });

            //Advanced Filter Events
            // Toggle advanced filters
            $(document).on('change', '#vmpfence-show-advanced-filters', function() {
                const isChecked = $(this).is(':checked');
                $('#vmpfence-advanced-filters').toggle(isChecked);
                if (!isChecked) {
                    self.clearFilters();
                } else {
                    // Stop polling when advanced filters are enabled
                    if (self.pollingEnabled) {
                        self.stopPolling();
                    }
                    // Auto-add first filter when toggling on
                    if ($('#vmpfence-filter-items .vmpfence-filter-item:visible').length === 0) {
                        self.addFilter();
                    }
                }
            });

            // Add filter button
            $(document).on('click', '#vmpfence-add-filter', function(e) {
                e.preventDefault();
                self.addFilter();
            });

            // Remove filter button
            $(document).on('click', '.vmpfence-filter-remove', function(e) {
                e.preventDefault();
                self.removeFilter($(this).closest('.vmpfence-filter-item'));
            });

            // Param dropdown change - update operators and show operator/value fields
            $(document).on('change', '.vmpfence-filter-param', function() {
                const filterItem = $(this).closest('.vmpfence-filter-item');
                const paramValue = $(this).val();
                
                if (paramValue && paramValue !== '') {
                    // Show operator and value fields (progressive disclosure)
                    filterItem.find('.vmpfence-filter-operator').show();
                    filterItem.find('.vmpfence-filter-value').show();
                    
                    // Update operator dropdown options
                    self.updateOperatorDropdown($(this));
                    
                    // Only apply if the value field has content
                    const valueField = filterItem.find('.vmpfence-filter-value');
                    if (valueField.val() && valueField.val().trim() !== '') {
                        self.applyFilters();
                    }
                } else {
                    // Hide operator and value fields if param is cleared
                    filterItem.find('.vmpfence-filter-operator').hide();
                    filterItem.find('.vmpfence-filter-value').hide();
                }
            });

            // Operator dropdown change - auto-apply only if value exists
            $(document).on('change', '.vmpfence-filter-operator', function() {
                // Only apply if the value field has content
                const valueField = $(this).closest('.vmpfence-filter-item').find('.vmpfence-filter-value');
                if (valueField.val() && valueField.val().trim() !== '') {
                    self.applyFilters();
                }
            });

            // Filter value input - auto-apply on blur
            $(document).on('blur', '.vmpfence-filter-value', function() {
                self.applyFilters();
            });

            // Filter value input - auto-apply on Enter key
            $(document).on('keypress', '.vmpfence-filter-value', function(e) {
                if (e.which === 13) {
                    e.preventDefault();
                    self.applyFilters();
                }
            });

            // Clear filters button
            $(document).on('click', '#vmpfence-clear-filters', function(e) {
                e.preventDefault();
                self.clearFilters();
            });

            // Group by change - auto-apply
            $(document).on('change', '#vmpfence-filter-groupby', function() {
                self.toggleGroupBy();
            });

            // Date input change - auto-apply
            $(document).on('change', '#vmpfence-filter-start-date, #vmpfence-filter-end-date', function() {
                self.applyFilters();
            });

            // Clear date buttons
            $(document).on('click', '#vmpfence-clear-start-date', function(e) {
                e.preventDefault();
                $('#vmpfence-filter-start-date').val('');
                self.applyFilters();
            });

            $(document).on('click', '#vmpfence-clear-end-date', function(e) {
                e.preventDefault();
                $('#vmpfence-filter-end-date').val('');
                self.applyFilters();
            });

            // Block IP from Live Traffic detail view
            $(document).on('click', '.vmpfence-block-ip', function(e) {
                e.preventDefault();
                const ip = $(this).data('ip');
                
                if (!ip) {
                    VMPFenceNotifications.showError('Invalid IP address', 3000);
                    return;
                }
                
                // Navigate to Firewall > Blocking with prefill parameter and source
                const blockingUrl = 'admin.php?page=vmpfence-firewall&tab=blocking&prefill_ip=' + encodeURIComponent(ip) + '&source=live-traffic';
                window.location.href = blockingUrl;
            });

            // Run Whois from Live Traffic detail view
            $(document).on('click', '.vmpfence-run-whois', function(e) {
                e.preventDefault();
                const $button = $(this);
                const ip = $button.data('ip');
                
                if (!ip) {
                    VMPFenceNotifications.showError('Invalid IP address', 3000);
                    return;
                }
                
                // Prevent multiple clicks
                if ($button.prop('disabled')) {
                    return;
                }
                
                // Disable button during lookup
                $button.prop('disabled', true).css('opacity', '0.6');
                
                // Show modal and perform lookup
                self.showWhoisModal(ip);
                
                // Re-enable button after modal opens
                setTimeout(function() {
                    $button.prop('disabled', false).css('opacity', '1');
                }, 500);
            });
            
            // See Recent Traffic button
            $(document).on('click', '.vmpfence-see-recent', function(e) {
                e.preventDefault();
                const $button = $(this);
                const ip = $button.data('ip');
                
                if (!ip) {
                    VMPFenceNotifications.showError('Invalid IP address', 3000);
                    return;
                }
                
                if ($button.prop('disabled')) return;
                
                $button.prop('disabled', true).css('opacity', '0.6');
                self.showRecentTrafficModal(ip);
                
                setTimeout(function() {
                    $button.prop('disabled', false).css('opacity', '1');
                }, 500);
            });
        },

        /**
         * Switch tab
         */
        switchTab: function(tabId) {
            // Update navigation
            $('.vmpfence-tabs-nav button').removeClass('active');
            $('.vmpfence-tabs-nav button[data-tab="' + tabId + '"]').addClass('active');

            // Update content
            $('.vmpfence-tab-content').removeClass('active');
            $('#' + tabId).addClass('active');

            // Update current tab
            this.currentTab = tabId;
            this.currentPage = 1;

            // Load tab data
            this.loadTab(tabId);
        },

        /**
         * Load tab content
         */
        loadTab: function(tabId) {
            switch(tabId) {
                case 'live-traffic':
                    this.loadLiveTraffic();
                    break;
                case 'audit-log':
                    this.loadAuditLog();
                    break;
                case 'whois-lookup':
                case 'import-export':
                case 'diagnostics':
                    // Coming soon - no action needed
                    break;
            }
        },

        /**
         * Load live traffic data
         */
        loadLiveTraffic: function() {
            const self = this;

            if (this.loading) {
                return;
            }

            this.loading = true;
            
            // Use seamless loading if table already has content
            const hasContent = $('#live-traffic-table-container').find('table').length > 0;
            this.showLoading('#live-traffic-table-container', hasContent);

            // Build AJAX data with filters
            const ajaxData = {
                action: 'vmpfence_get_live_traffic',
                nonce: vmpfenceToolsData.nonce,
                page: this.currentPage,
                per_page: this.perPage,
                filter: this.currentFilter
            };

            // Add advanced filter data if advanced filters are visible
            if ($('#vmpfence-advanced-filters').is(':visible')) {
                const filterData = this.serializeFilters();
                $.extend(ajaxData, filterData);
            }

            $.ajax({
                url: ajaxurl,
                type: 'POST',
                data: ajaxData,
                success: function(response) {
                    if (response.success) {
                        self.renderLiveTraffic(response.data);
                    } else {
                        self.showError('#live-traffic-table-container', response.data.message || 'Error loading data');
                    }
                },
                error: function(xhr, status, error) {
                    self.showError('#live-traffic-table-container', 'Failed to load live traffic data');
                },
                complete: function() {
                    self.loading = false;
                }
            });
        },

        /**
         * Render live traffic table
         */
        renderLiveTraffic: function(data) {
            const self = this;
            const container = $('#live-traffic-table-container');
            
            if (!data.data || data.data.length === 0) {
                this.showEmpty(container, 'No traffic data available');
                return;
            }

            let html = '<table class="vmpfence-traffic-table">';
            html += '<thead><tr>';
            html += '<th>Type</th>';
            html += '<th>Location</th>';
            html += '<th>Page Visited</th>';
            html += '<th>Time</th>';
            html += '<th>IP Address</th>';
            html += '<th>Hostname</th>';
            html += '<th>Response</th>';
            html += '<th>View</th>';
            html += '</tr></thead>';
            html += '<tbody>';

            data.data.forEach(function(row) {
                const typeClass = row.type || 'unspecified';
                const typeLabel = self.getTypeLabel(row.type);
                
                html += '<tr>';
                html += '<td><span class="vmpfence-traffic-type">';
                html += '<span class="vmpfence-traffic-icon ' + typeClass + '"></span>';
                html += typeLabel;
                html += '</span></td>';
                html += '<td>' + self.getLocationLabel(row) + '</td>';
                html += '<td class="vmpfence-page-visited" title="' + self.escapeHtml(row.URL || '') + '">' + self.escapeHtml(row.URL || '') + '</td>';
                html += '<td>' + self.escapeHtml(row.formatted_time) + '</td>';
                html += '<td class="vmpfence-ip-cell" title="' + self.escapeHtml(row.IP) + '">' + self.escapeHtml(row.IP) + '</td>';
                html += '<td class="vmpfence-hostname-cell" title="' + self.escapeHtml(row.hostname || '-') + '">' + self.escapeHtml(row.hostname || '-') + '</td>';
                html += '<td><span class="vmpfence-response-badge response-' + row.response + '">' + row.response + '</span></td>';
                html += '<td><button class="vmpfence-action-btn view vmpfence-view-details" data-id="' + row.id + '"><span class="dashicons dashicons-visibility"></span></button></td>';
                html += '</tr>';
            });

            html += '</tbody></table>';

            // Add pagination
            html += this.renderPagination(data);

            container.html(html);
        },

        /**
         * Load audit log data
         */
        loadAuditLog: function() {
            const self = this;

            if (this.loading) return;

            this.loading = true;
            this.showLoading('#audit-log-table-container');

            $.ajax({
                url: ajaxurl,
                type: 'POST',
                data: {
                    action: 'vmpfence_get_audit_log',
                    nonce: vmpfenceToolsData.nonce,
                    page: this.currentPage,
                    per_page: this.perPage
                },
                success: function(response) {
                    if (response.success) {
                        self.renderAuditLog(response.data);
                    } else {
                        self.showError('#audit-log-table-container', response.data.message || 'Error loading data');
                    }
                },
                error: function() {
                    self.showError('#audit-log-table-container', 'Failed to load audit log data');
                },
                complete: function() {
                    self.loading = false;
                }
            });
        },

        /**
         * Render audit log table
         */
        renderAuditLog: function(data) {
            const self = this;
            const container = $('#audit-log-table-container');
            
            if (!data.data || data.data.length === 0) {
                this.showEmpty(container, 'No audit log entries available');
                return;
            }

            let html = '<table class="vmpfence-traffic-table">';
            html += '<thead><tr>';
            html += '<th>Type</th>';
            html += '<th>Time</th>';
            html += '<th>Events</th>';
            html += '</tr></thead>';
            html += '<tbody>';

            data.data.forEach(function(row) {
                const eventCategory = self.getEventCategory(row.event_type);
                
                html += '<tr>';
                html += '<td><span class="vmpfence-event-badge ' + eventCategory + '">' + self.escapeHtml(row.event_type) + '</span></td>';
                html += '<td>' + self.escapeHtml(row.formatted_time) + '</td>';
                html += '<td>' + self.escapeHtml(row.message || row.action) + '</td>';
                html += '</tr>';
            });

            html += '</tbody></table>';

            // Add pagination
            html += this.renderPagination(data);

            container.html(html);
        },

        /**
         * Render pagination controls
         */
        renderPagination: function(data) {
            const start = ((data.page - 1) * data.per_page) + 1;
            const end = Math.min(data.page * data.per_page, data.total);

            let html = '<div class="vmpfence-pagination">';
            html += '<div class="vmpfence-pagination-info">';
            html += 'Showing ' + start + '-' + end + ' of ' + data.total;
            html += '</div>';
            html += '<div class="vmpfence-pagination-controls">';
            html += '<button class="vmpfence-pagination-btn" data-action="prev" ' + (data.page === 1 ? 'disabled' : '') + '>Previous</button>';
            html += '<button class="vmpfence-pagination-btn" data-action="next" ' + (data.page >= data.total_pages ? 'disabled' : '') + '>Next</button>';
            html += '</div>';
            html += '</div>';

            return html;
        },

        /**
         * Show loading state
         */
        showLoading: function(selector, seamless) {
            if (!seamless) {
                // Only show loading on first load (clear content)
                $(selector).html('<div class="vmpfence-loading"></div>');
            }
            // For seamless updates, don't show any loading indicator
        },

        /**
         * Show error message
         */
        showError: function(selector, message) {
            const html = '<div class="vmpfence-empty-state">' +
                '<div class="vmpfence-empty-state-icon">⚠️</div>' +
                '<h3>Error</h3>' +
                '<p>' + this.escapeHtml(message) + '</p>' +
                '</div>';
            $(selector).html(html);
        },

        /**
         * Show empty state
         */
        showEmpty: function(selector, message) {
            const html = '<div class="vmpfence-empty-state">' +
                '<div class="vmpfence-empty-state-icon">📭</div>' +
                '<h3>No Data</h3>' +
                '<p>' + this.escapeHtml(message) + '</p>' +
                '</div>';
            $(selector).html(html);
        },

        /**
         * Get type label
         */
        getTypeLabel: function(type) {
            const labels = {
                'human': 'Human',
                'bot': 'Bot',
                'blocked': 'Blocked',
                'warning': 'Warning',
                'unspecified': 'Unspecified'
            };
            return labels[type] || 'Unknown';
        },

        /**
         * Get action label
         */
        getActionLabel: function(action) {
            if (!action) return 'Unspecified';
            
            const labels = {
                'blocked:waf': 'Blocked WAF',
                'logged:waf': 'Logged WAF',
                'lockedOut': 'Locked Out',
                'loginOK': 'Login Success',
                'loginFailValidUsername': 'Login Failed (Valid User)',
                'loginFailInvalidUsername': 'Login Failed (Invalid User)',
                'logout': 'Logout',
                'lostPassword': 'Password Reset Request',
                'user:adminCreate': 'Admin Created',
                'user:passwordReset': 'Password Reset',
                'rate_limit_block': 'Rate Limited (Blocked)',
                'rate_limit_throttle': 'Rate Limited (Throttled)'
            };
            
            // Check for exact match first
            if (labels[action]) {
                return labels[action];
            }
            
            // Check for partial matches
            if (action.includes('rate_limit')) return 'Rate Limited';
            if (action.includes('lockedOut')) return 'Locked Out';
            if (action.includes('blocked')) return 'Blocked';
            if (action.includes('login')) return 'Login Event';
            if (action.includes('user:')) return 'User Management';
            
            return this.escapeHtml(action);
        },

        /**
         * Get location label with country flag and name
         * @since 2.2.5
         */
        getLocationLabel: function(row) {
            var flag = row.countryFlag || '';
            var name = row.countryName || '';

            if (!name || name === 'Unspecified') {
                return '<span class="vmpfence-location-unspecified">Unspecified</span>';
            }

            var flagHtml = flag ? '<img src="' + this.escapeHtml(flag) + '" alt="' + this.escapeHtml(row.countryCode || '') + '" class="country-flag" style="width:20px;height:15px;vertical-align:middle;margin-right:5px;"> ' : '';
            return '<span class="vmpfence-location">' + flagHtml + this.escapeHtml(name) + '</span>';
        },

        /**
         * Get event category
         */
        getEventCategory: function(eventType) {
            if (eventType.includes('login')) return 'login';
            if (eventType.includes('scan') || eventType.includes('threat')) return 'scan';
            if (eventType.includes('config')) return 'config';
            return 'security';
        },

        /**
         * Show details modal
         */
        showDetails: function(row) {
            const recordId = $(row).find('.vmpfence-view-details').data('id');
            const $viewBtn = $(row).find('.vmpfence-view-details');
            const $icon = $viewBtn.find('.dashicons');
            
            // Check if detail row already exists and toggle it
            const existingDetail = $(row).next('.vmpfence-detail-row');
            if (existingDetail.length) {
                existingDetail.toggle();
                // Toggle icon
                if (existingDetail.is(':visible')) {
                    $icon.removeClass('dashicons-visibility').addClass('dashicons-hidden');
                } else {
                    $icon.removeClass('dashicons-hidden').addClass('dashicons-visibility');
                }
                return;
            }
            
            // Fetch full record details via AJAX
            const self = this;
            $.ajax({
                url: ajaxurl,
                type: 'POST',
                data: {
                    action: 'vmpfence_get_traffic_detail',
                    nonce: vmpfenceToolsData.nonce,
                    id: recordId
                },
                success: function(response) {
                    if (response.success && response.data) {
                        self.renderDetailRow(row, response.data);
                        // Change icon to hidden state
                        $icon.removeClass('dashicons-visibility').addClass('dashicons-hidden');
                    } else {
                        VMPFenceNotifications.showError('Failed to load details', 5000);
                    }
                },
                error: function() {
                    VMPFenceNotifications.showError('Failed to load details', 5000);
                }
            });
        },
        
        /**
         * Render detail row after the main row
         */
        renderDetailRow: function(row, data) {
            const colspan = $(row).find('td').length;
            
            let detailHtml = '<tr class="vmpfence-detail-row">';
            detailHtml += '<td colspan="' + colspan + '" class="vmpfence-detail-cell">';
            detailHtml += '<div class="vmpfence-activity-detail">';
            
            // User icon
            detailHtml += '<div class="vmpfence-user-icon">';
            detailHtml += '<span class="dashicons dashicons-admin-users"></span>';
            detailHtml += '</div>';
            
            // Detail content
            detailHtml += '<div class="vmpfence-detail-content">';
            detailHtml += '<h3>Activity Detail</h3>';
            
            // Description
            detailHtml += '<p class="vmpfence-detail-description">';
            var locationText = (data.countryName && data.countryName !== 'Unspecified')
                ? (data.countryFlag ? '<img src="' + this.escapeHtml(data.countryFlag) + '" alt="" class="country-flag" style="width:20px;height:15px;vertical-align:middle;margin-right:5px;"> ' : '') + this.escapeHtml(data.countryName)
                : 'An unknown location';
            detailHtml += locationText + ' at IP <a href="#">' + this.escapeHtml(data.IP) + '</a> ';
            detailHtml += 'left <a href="' + this.escapeHtml(data.URL) + '" target="_blank">' + this.escapeHtml(data.URL) + '</a>';
            if (data.user_login) {
                detailHtml += ' and logged in successfully as <strong>' + this.escapeHtml(data.user_login) + '</strong>';
            }
            detailHtml += '.</p>';
            
            detailHtml += '<p class="vmpfence-detail-url">';
            detailHtml += '<a href="' + this.escapeHtml(data.URL) + '" target="_blank">' + this.escapeHtml(data.URL) + '</a>';
            detailHtml += '</p>';
            
            // Timestamp
            detailHtml += '<p class="vmpfence-detail-time">' + this.escapeHtml(data.formatted_time);
            if (data.time_ago) {
                detailHtml += ' (' + this.escapeHtml(data.time_ago) + ')';
            }
            detailHtml += '</p>';
            
            // Technical details
            detailHtml += '<p class="vmpfence-detail-tech">';
            detailHtml += '<strong>IP:</strong> ' + this.escapeHtml(data.IP) + ' ';
            detailHtml += '<strong>Hostname:</strong> ' + this.escapeHtml(data.hostname || 'Unknown') + '<br>';
            if (data.user_agent) {
                detailHtml += '<strong>User Agent:</strong> ' + this.escapeHtml(data.user_agent);
            }
            detailHtml += '</p>';
            
            // Type
            if (data.action) {
                detailHtml += '<p class="vmpfence-detail-type"><strong>Type:</strong> ' + this.escapeHtml(data.action) + '</p>';
            }
            
            // Action buttons
            detailHtml += '<div class="vmpfence-detail-actions">';
            detailHtml += '<button class="vmpfence-btn vmpfence-btn-secondary vmpfence-block-ip" data-ip="' + this.escapeHtml(data.IP) + '">BLOCK IP</button>';
            detailHtml += '<button class="vmpfence-btn vmpfence-btn-secondary vmpfence-run-whois" data-ip="' + this.escapeHtml(data.IP) + '">RUN WHOIS</button>';
            detailHtml += '<button class="vmpfence-btn vmpfence-btn-secondary vmpfence-see-recent" data-ip="' + this.escapeHtml(data.IP) + '">SEE RECENT TRAFFIC</button>';
            detailHtml += '</div>';
            
            detailHtml += '</div>'; // .vmpfence-detail-content
            detailHtml += '</div>'; // .vmpfence-activity-detail
            detailHtml += '</td>';
            detailHtml += '</tr>';
            
            $(row).after(detailHtml);
        },

        /**
         * Save options
         */
        saveOptions: function() {
            const formData = $('#vmpfence-live-traffic-options-form').serialize();
            
            $.ajax({
                url: ajaxurl,
                type: 'POST',
                data: {
                    action: 'vmpfence_save_traffic_options',
                    nonce: vmpfenceToolsData.nonce,
                    options: formData
                },
                success: function(response) {
                    if (response.success) {
                        VMPFenceNotifications.showSuccess('Settings saved successfully!', 3000);
                    } else {
                        VMPFenceNotifications.showError('Error saving settings: ' + (response.data.message || 'Unknown error'), 6000);
                    }
                },
                error: function() {
                    VMPFenceNotifications.showError('Failed to save settings. Please try again.', 6000);
                }
            });
        },

        /**
         * Load options
         */
        loadOptions: function() {
            $.ajax({
                url: ajaxurl,
                type: 'POST',
                data: {
                    action: 'vmpfence_get_traffic_options',
                    nonce: vmpfenceToolsData.nonce
                },
                success: function(response) {
                    if (response.success && response.data) {
                        // Populate form fields
                        const data = response.data;
                        
                        // Set traffic logging mode
                        if (data.traffic_logging_mode) {
                            $('.vmpfence-mode-btn').removeClass('active');
                            $('.vmpfence-mode-btn[data-value="' + data.traffic_logging_mode + '"]').addClass('active');
                            $('#traffic_logging_mode').val(data.traffic_logging_mode);
                        }
                        
                        // Set checkboxes
                        $('#ignore_publishing_users').prop('checked', data.ignore_publishing_users == '1');
                        $('#display_live_traffic_menu').prop('checked', data.display_live_traffic_menu == '1');
                        
                        // Set text fields
                        $('#ignore_usernames').val(data.ignore_usernames || '');
                        $('#ignore_ips').val(data.ignore_ips || '');
                        $('#ignore_user_agent').val(data.ignore_user_agent || '');
                        $('#max_traffic_rows').val(data.max_traffic_rows || 2000);
                        $('#max_traffic_days').val(data.max_traffic_days || 30);
                    }
                }
            });
        },

        /**
         * Restore defaults
         */
        restoreDefaults: function() {
            // Set default values
            $('.vmpfence-mode-btn').removeClass('active');
            $('.vmpfence-mode-btn[data-value="security_only"]').addClass('active');
            $('#traffic_logging_mode').val('security_only');
            
            $('#ignore_publishing_users').prop('checked', false);
            $('#display_live_traffic_menu').prop('checked', true);
            
            $('#ignore_usernames').val('');
            $('#ignore_ips').val('');
            $('#ignore_user_agent').val('');
            $('#max_traffic_rows').val(2000);
            $('#max_traffic_days').val(30);
            
            VMPFenceNotifications.showInfo('Default settings restored. Click "Save Changes" to apply.', 5000);
        },

        /**
         * Initialize Filters
         */
        initFilters: function() {
            const self = this;

            // Initialize jQuery UI Datetimepicker
            if (typeof $.fn.datetimepicker !== 'undefined') {
                $('.vmpfence-datetimepicker').datetimepicker({
                    dateFormat: 'mm/dd/yy',
                    timeFormat: 'hh:mm tt z',
                    controlType: 'slider',
                    showHour: true,
                    showMinute: true,
                    showTime: true,
                    showTimezone: true,
                    showButtonPanel: true,
                    changeMonth: true,
                    changeYear: true,
                    hourMin: 0,
                    hourMax: 23,
                    minuteMin: 0,
                    minuteMax: 59,
                    stepMinute: 1,
                    stepHour: 1,
                    onClose: function() {
                        if ($(this).val()) {
                            self.applyFilters();
                        }
                    }
                });
            }

            // Load filter param options via AJAX
            $.ajax({
                url: ajaxurl,
                type: 'POST',
                data: {
                    action: 'vmpfence_get_filter_options',
                    nonce: vmpfenceToolsData.nonce
                },
                success: function(response) {
                    if (response.success && response.data.params) {
                        self.filterParams = response.data.params;
                        self.populateFilterParams();
                    }
                },
                error: function(xhr, status, error) {
                }
            });

            // Load group by options via AJAX
            $.ajax({
                url: ajaxurl,
                type: 'POST',
                data: {
                    action: 'vmpfence_get_groupby_options',
                    nonce: vmpfenceToolsData.nonce
                },
                success: function(response) {
                    if (response.success && response.data.options) {
                        self.groupByOptions = response.data.options;
                        self.populateGroupByOptions();
                    }
                },
                error: function(xhr, status, error) {
                }
            });
        },

        /**
         * Populate filter parameter options
         */
        populateFilterParams: function() {
            const select = $('#vmpfence-filter-template .vmpfence-filter-param');
            select.empty();
            select.append('<option value="">Select parameter...</option>');

            this.filterParams.forEach(function(param) {
                select.append('<option value="' + param.value + '">' + param.label + '</option>');
            });
        },

        /**
         * Populate group by options
         */
        populateGroupByOptions: function() {
            const select = $('#vmpfence-filter-groupby');
            select.find('option:not(:first)').remove();

            this.groupByOptions.forEach(function(option) {
                select.append('<option value="' + option.value + '">' + option.label + '</option>');
            });
        },

        /**
         * Add filter
         */
        addFilter: function() {
            const self = this;
            const template = $('#vmpfence-filter-template');
            const newFilter = template.clone();
            
            newFilter.removeAttr('id');
            
            // Populate filter parameter dropdown for this new filter
            const paramSelect = newFilter.find('.vmpfence-filter-param');
            paramSelect.empty();
            paramSelect.append('<option value="">Select parameter...</option>');
            
            this.filterParams.forEach(function(param) {
                paramSelect.append('<option value="' + param.value + '">' + param.label + '</option>');
            });
            
            newFilter.show();
            
            $('#vmpfence-filter-items').append(newFilter);
        },

        /**
         * Remove filter
         */
        removeFilter: function($element) {
            $element.remove();
            
            // Reload traffic data with updated filters
            this.loadLiveTraffic();
        },

        /**
         * Update operator dropdown based on param type
         */
        updateOperatorDropdown: function($paramSelect) {
            const paramName = $paramSelect.val();
            const operatorSelect = $paramSelect.closest('.vmpfence-filter-item').find('.vmpfence-filter-operator');
            
            if (!paramName) {
                return;
            }

            // Find param definition
            const param = this.filterParams.find(p => p.value === paramName);
            if (!param) {
                return;
            }

            // Clear and rebuild operators based on type
            operatorSelect.empty();

            if (param.operators && param.operators.length > 0) {
                param.operators.forEach(function(op) {
                    let label = op;
                    switch(op) {
                        case '=': label = '='; break;
                        case '!=': label = '!='; break;
                        case 'contains': label = 'contains'; break;
                        case 'notcontains': label = 'does not contain'; break;
                        case 'regexp': label = 'matches regexp'; break;
                        case '>': label = '>'; break;
                        case '<': label = '<'; break;
                        case '>=': label = '>='; break;
                        case '<=': label = '<='; break;
                    }
                    operatorSelect.append('<option value="' + op + '">' + label + '</option>');
                });
            } else {
                // Default operators for text
                operatorSelect.append('<option value="=">=</option>');
                operatorSelect.append('<option value="!=">!=</option>');
                operatorSelect.append('<option value="contains">contains</option>');
                operatorSelect.append('<option value="notcontains">does not contain</option>');
            }

            // Handle enum and boolean values (create dropdown instead of text input)
            const valueInput = $paramSelect.closest('.vmpfence-filter-item').find('.vmpfence-filter-value');
            
            if ((param.type === 'enum' || param.type === 'boolean') && param.values && param.values.length > 0) {
                // Always rebuild the dropdown to ensure correct options are shown
                const select = $('<select class="vmpfence-filter-value"></select>');
                param.values.forEach(function(val) {
                    select.append('<option value="' + val.value + '">' + val.label + '</option>');
                });
                valueInput.replaceWith(select);
            } else if (valueInput.is('select')) {
                // Replace select with text input
                const input = $('<input type="text" class="vmpfence-filter-value" placeholder="Value">');
                valueInput.replaceWith(input);
            }
        },

        /**
         * Serialize filters for AJAX
         */
        serializeFilters: function() {
            const params = [];
            const operators = [];
            const values = [];

            const visibleFilters = $('#vmpfence-filter-items .vmpfence-filter-item:visible');

            visibleFilters.each(function(index) {
                const $item = $(this);
                const itemId = $item.attr('id');
                const param = $(this).find('.vmpfence-filter-param').val();
                const operator = $(this).find('.vmpfence-filter-operator').val();
                const value = $(this).find('.vmpfence-filter-value').val();

                if (param && operator && value) {
                    params.push(param);
                    operators.push(operator);
                    values.push(value);
                }
            });

            const filterData = {
                param: params,
                operator: operators,
                value: values,
                groupby: $('#vmpfence-filter-groupby').val(),
                startDate: this.dateToTimestamp($('#vmpfence-filter-start-date').val()),
                endDate: this.dateToTimestamp($('#vmpfence-filter-end-date').val())
            };
            
            return filterData;
        },

        /**
         * Convert datetime-local value to timestamp
         */
        dateToTimestamp: function(dateStr) {
            if (!dateStr) {
                return 0;
            }
            const date = new Date(dateStr);
            const timestamp = Math.floor(date.getTime() / 1000);
            return timestamp;
        },

        /**
         * Apply filters
         */
        applyFilters: function() {
            this.currentPage = 1;
            this.loadLiveTraffic();
        },

        /**
         * Clear all filters
         */
        clearFilters: function() {
            // Remove all filter items
            $('#vmpfence-filter-items').empty();
            
            // Clear dates
            $('#vmpfence-filter-start-date').val('');
            $('#vmpfence-filter-end-date').val('');
            
            // Clear group by
            $('#vmpfence-filter-groupby').val('');
            
            // Reload traffic without filters
            this.currentPage = 1;
            this.loadLiveTraffic();
        },

        /**
         * Toggle group by
         */
        toggleGroupBy: function() {
            // Stop polling when groupBy is activated
            if (this.groupBy && this.groupBy !== '' && this.pollingEnabled) {
                this.stopPolling();
            }
            
            this.currentPage = 1;
            this.loadLiveTraffic();
        },

        /**
         * Start real-time polling
         */
        startPolling: function() {
            // Clear any existing interval
            if (this.pollingInterval) {
                clearInterval(this.pollingInterval);
                this.pollingInterval = null;
            }

            // Set initial poll time
            this.lastPollTime = Math.floor(Date.now() / 1000);
            
            // Set polling enabled
            this.pollingEnabled = true;
            this.pollingPaused = false;
            
            // Get update interval from settings (default 10 seconds, converted to milliseconds)
            var updateInterval = (typeof vmpfence_admin !== 'undefined' && vmpfence_admin.update_interval) 
                ? parseInt(vmpfence_admin.update_interval) * 1000 
                : 10000;
            
            // console.log('[Live Traffic] Starting polling (' + (updateInterval / 1000) + ' second interval)');
            
            // Start polling interval
            const self = this;
            this.pollingInterval = setInterval(function() {
                self.pollForNewRecords();
            }, updateInterval);
        },

        /**
         * Stop real-time polling
         */
        stopPolling: function() {
            // Clear interval
            if (this.pollingInterval) {
                clearInterval(this.pollingInterval);
                this.pollingInterval = null;
            }
            
            // Set polling disabled
            this.pollingEnabled = false;
        },

        /**
         * Poll for new records
         */
        pollForNewRecords: function() {
            // Check if polling is enabled
            if (!this.pollingEnabled || this.pollingPaused) {
                return;
            }
            
            // Pause if window loses focus
            if (window.VMPFenceAdmin && window.VMPFenceAdmin.shouldPauseLiveUpdates()) {
                // console.log('[Live Traffic] Auto-refresh paused (window not focused)');
                return;
            }

            // Don't poll if grouped mode is active
            if (this.groupBy && this.groupBy !== '') {
                return;
            }

            // Don't poll if advanced filters are active
            if ($('#vmpfence-advanced-filters').is(':visible') && $('#vmpfence-filter-items .vmpfence-filter-item:visible').length > 0) {
                return;
            }

            // console.log('[Live Traffic] Checking for new records... (since: ' + this.lastPollTime + ')');

            const self = this;
            
            $.ajax({
                url: vmpfenceToolsData.ajaxurl,
                type: 'POST',
                data: {
                    action: 'vmpfence_get_live_traffic_realtime',
                    nonce: vmpfenceToolsData.nonce,
                    since: this.lastPollTime
                },
                success: function(response) {
                    if (response.success && response.data.data && response.data.data.length > 0) {
                        // console.log('[Live Traffic] Found ' + response.data.data.length + ' new records - refreshing table');
                        
                        // Update last poll time BEFORE reloading
                        if (response.data.timestamp) {
                            self.lastPollTime = Math.floor(response.data.timestamp);
                            // console.log('[Live Traffic] Updated lastPollTime to: ' + self.lastPollTime);
                        }
                        
                        // Reload the entire table
                        self.reloadLiveTrafficTable();
                    } else {
                        // console.log('[Live Traffic] No new records');
                    }
                },
                error: function(xhr, status, error) {
                    console.log('[Live Traffic] Polling failed:', error);
                }
            });
        },

        /**
         * Prepend new records to table
         */
        prependRecords: function(newRecords) {
            if (!newRecords || newRecords.length === 0) {
                return;
            }

            const tbody = $('#vmpfence-live-traffic tbody');
            const existingIds = [];
            
            // Get existing record IDs
            tbody.find('tr').each(function() {
                const id = $(this).data('id');
                if (id) {
                    existingIds.push(id);
                }
            });

            // Loop through new records (newest first)
            for (let i = newRecords.length - 1; i >= 0; i--) {
                const record = newRecords[i];
                
                // Check for duplicates
                if (existingIds.includes(record.id)) {
                    continue;
                }

                // Create table row HTML
                const row = this.createTableRow(record);
                
                // Add highlight class
                row.addClass('vmpfence-new-record');
                
                // Prepend to table
                tbody.prepend(row);
                
                // Remove highlight after animation (3 seconds)
                setTimeout(function() {
                    row.removeClass('vmpfence-new-record');
                }, 3000);
            }
        },

        /**
         * Reload Live Traffic table (full refresh)
         * @since 2.2.2
         */
        reloadLiveTrafficTable: function() {
            const self = this;
            const $tbody = $('#live-traffic-table-container tbody');
            if (!$tbody.length) {
                // console.log('[Live Traffic] Table not found, skipping reload');
                return;
            }

            // console.log('[Live Traffic] Reloading table...');

            $.ajax({
                url: vmpfenceToolsData.ajaxurl,
                type: 'POST',
                data: {
                    action: 'vmpfence_reload_live_traffic_table',
                    nonce: vmpfenceToolsData.nonce,
                    page: self.currentPage || 1,
                    per_page: self.perPage || 100
                },
                success: function(response) {
                    if (response.success && response.data.html) {
                        // console.log('[Live Traffic] Table reloaded successfully with ' + response.data.count + ' records');
                        
                        // Replace table content with fade effect
                        $tbody.fadeOut(200, function() {
                            $tbody.html(response.data.html);
                            $tbody.fadeIn(200);
                        });
                        
                        // Show toast notification
                        if (typeof VMPFenceNotifications !== 'undefined' && response.data.count > 0) {
                            VMPFenceNotifications.showInfo(
                                'Live traffic updated.',
                                2000
                            );
                        }
                    } else {
                        // console.log('[Live Traffic] Table reload failed - no HTML returned');
                    }
                },
                error: function(xhr, status, error) {
                    console.log('[Live Traffic] Table reload failed:', error);
                }
            });
        },

        /**
         * Create table row from record data
         */
        createTableRow: function(record) {
            const self = this;
            const row = $('<tr></tr>').attr('data-id', record.id);
            
            // Time column
            const timeCell = $('<td></td>').addClass('vmpfence-col-time');
            const timeText = record.ctime ? this.formatTimestamp(record.ctime) : '';
            timeCell.text(timeText);
            row.append(timeCell);
            
            // IP column
            const ipCell = $('<td></td>').addClass('vmpfence-col-ip');
            ipCell.text(record.IP || '');
            row.append(ipCell);
            
            // Type column (human/bot)
            const typeCell = $('<td></td>').addClass('vmpfence-col-type');
            const typeText = record.jsRun === 1 ? 'Human' : 'Bot';
            typeCell.text(typeText);
            row.append(typeCell);
            
            // User column
            const userCell = $('<td></td>').addClass('vmpfence-col-user');
            userCell.text(record.display_name || record.user_login || 'Guest');
            row.append(userCell);
            
            // URL column
            const urlCell = $('<td></td>').addClass('vmpfence-col-url');
            const urlText = record.URL || '';
            const shortUrl = urlText.length > 50 ? urlText.substring(0, 50) + '...' : urlText;
            urlCell.text(shortUrl).attr('title', urlText);
            row.append(urlCell);
            
            // Response column
            const responseCell = $('<td></td>').addClass('vmpfence-col-response');
            responseCell.text(record.statusCode || '');
            row.append(responseCell);
            
            // Action column
            const actionCell = $('<td></td>').addClass('vmpfence-col-action');
            actionCell.text(record.action || '');
            row.append(actionCell);
            
            return row;
        },

        /**
         * Format timestamp for display
         */
        formatTimestamp: function(timestamp) {
            if (!timestamp) return '';
            
            const date = new Date(timestamp * 1000);
            const now = new Date();
            const diff = Math.floor((now - date) / 1000);
            
            // Show relative time if less than 24 hours
            if (diff < 60) {
                return 'Just now';
            } else if (diff < 3600) {
                const mins = Math.floor(diff / 60);
                return mins + ' min' + (mins !== 1 ? 's' : '') + ' ago';
            } else if (diff < 86400) {
                const hours = Math.floor(diff / 3600);
                return hours + ' hour' + (hours !== 1 ? 's' : '') + ' ago';
            } else {
                // Show full date/time
                return date.toLocaleString();
            }
        },

        /**
         * Escape HTML
         */
        escapeHtml: function(text) {
            if (!text) return '';
            const map = {
                '&': '&amp;',
                '<': '&lt;',
                '>': '&gt;',
                '"': '&quot;',
                "'": '&#039;'
            };
            return text.toString().replace(/[&<>"']/g, function(m) { return map[m]; });
        },

        /**
         * WHOIS Lookup - Perform lookup
         */
        performWhoisLookup: function() {
            const self = this;
            const input = $('#whois-input').val().trim();
            const button = $('#whois-lookup-btn');
            const results = $('#whois-results');

            if (!input) {
                VMPFenceNotifications.showToast('Please enter an IP address or domain name', 'error', 3000);
                $('#whois-input').focus();
                return;
            }

            // Show loading state
            button.prop('disabled', true).addClass('loading');
            button.find('.button-text').text('Looking up...');
            results.hide().html('');

            // Make AJAX request
            $.ajax({
                url: ajaxurl,
                type: 'POST',
                data: {
                    action: 'vmpfence_whois_lookup',
                    nonce: vmpfenceToolsData.nonce,
                    input: input
                },
                success: function(response) {
                    if (response.success) {
                        self.displayWhoisResults(response.data);
                        VMPFenceNotifications.showToast(response.data.message || 'WHOIS lookup completed successfully', 'success', 3000, 'Success');
                    } else {
                        const errorMsg = (response.data && response.data.message) ? response.data.message : 'WHOIS lookup failed';
                        VMPFenceNotifications.showToast(errorMsg, 'error', 5000, 'Error');
                        results.html('<div class="whois-error"><strong>Error:</strong> ' + self.escapeHtml(errorMsg) + '</div>').show();
                    }
                },
                error: function(xhr, status, error) {
                    VMPFenceNotifications.showToast('Network error occurred. Please check your connection.', 'error', 5000, 'Network Error');
                    results.html('<div class="whois-error"><strong>Network Error:</strong> Unable to connect to the server. Please try again.</div>').show();
                },
                complete: function() {
                    button.prop('disabled', false).removeClass('loading');
                    button.find('.button-text').text('LOOK UP IP OR DOMAIN');
                }
            });
        },

        /**
         * Show Whois Modal and perform lookup
         */
        showWhoisModal: function(ip) {
            const self = this;
            const modal = $('#vmpfence-whois-modal');
            
            // Don't show if another modal is already open
            if ($('.vmpfence-notification-modal.show').length > 0) {
                return;
            }
            
            // Show modal
            modal.show().addClass('show');
            
            // Show loading state
            modal.find('.vmpfence-whois-modal-loading').show();
            modal.find('.vmpfence-whois-modal-results').html('');
            
            // Perform lookup
            this.performWhoisLookupInModal(ip);
        },

        /**
         * Perform Whois lookup for modal
         */
        performWhoisLookupInModal: function(ip) {
            const self = this;
            const modal = $('#vmpfence-whois-modal');
            const resultsContainer = modal.find('.vmpfence-whois-modal-results');
            const loadingContainer = modal.find('.vmpfence-whois-modal-loading');
            
            // Make AJAX request
            $.ajax({
                url: ajaxurl,
                type: 'POST',
                data: {
                    action: 'vmpfence_whois_lookup',
                    nonce: vmpfenceToolsData.nonce,
                    input: ip
                },
                success: function(response) {
                    loadingContainer.hide();
                    
                    if (response.success) {
                        self.displayWhoisResultsInModal(response.data);
                    } else {
                        const errorMsg = (response.data && response.data.message) ? response.data.message : 'WHOIS lookup failed';
                        resultsContainer.html('<div class="whois-error"><strong>Error:</strong> ' + self.escapeHtml(errorMsg) + '</div>');
                    }
                },
                error: function(xhr, status, error) {
                    loadingContainer.hide();
                    resultsContainer.html('<div class="whois-error"><strong>Network Error:</strong> Unable to connect to the server. Please try again.</div>');
                }
            });
        },

        /**
         * Display Whois results in modal
         */
        displayWhoisResultsInModal: function(data) {
            const self = this;
            const resultsContainer = $('#vmpfence-whois-modal-results');
            let html = '';

            if (!data || !data.data || !Array.isArray(data.data)) {
                resultsContainer.html('<div class="whois-error">No data received</div>');
                return;
            }

            if (data.data.length === 0) {
                resultsContainer.html('<div class="whois-error">No results found</div>');
                return;
            }

            // Show resolution info if domain lookup
            if (data.resolved) {
                html += '<div class="whois-resolution-info">';
                html += '<h3>🌐 Domain Resolution: ' + self.escapeHtml(data.resolved.domain) + '</h3>';
                html += '<p>Found ' + parseInt(data.resolved.ipv4_count || 0) + ' IPv4 and ' + parseInt(data.resolved.ipv6_count || 0) + ' IPv6 address(es)</p>';
                html += '</div>';
            }

            // Display each IP result
            data.data.forEach(function(item, index) {
                const ipType = self.escapeHtml(item.ip_type || 'IP');
                const ipIndex = item.ip_index ? ' #' + parseInt(item.ip_index) : '';

                html += '<div class="whois-result-card">';
                html += '<div class="whois-card-header">';
                html += '<h3>' + ipType + ipIndex + ' Information</h3>';
                html += '</div>';

                // IP Information
                html += '<div class="whois-info-block">';
                html += '<h4>📍 IP Information</h4>';
                html += '<table class="whois-table">';
                html += '<tr><td>IP Address:</td><td>';
                html += '<div class="whois-ip-with-button">';
                html += '<code>' + self.escapeHtml(item.ip || 'N/A') + '</code>';
                html += '<button class="whois-block-ip-btn-inline-modal" data-ip="' + self.escapeHtml(item.ip || '') + '" title="Block this IP address">';
                html += '🛡️ Block IP';
                html += '</button>';
                html += '</div>';
                html += '</td></tr>';
                html += '<tr><td>Type:</td><td>' + self.escapeHtml(item.type || 'N/A') + '</td></tr>';
                html += '<tr><td>Country:</td><td>';
                if (item.country) {
                    if (item.flag_url) {
                        html += '<img src="' + self.escapeHtml(item.flag_url) + '" alt="' + self.escapeHtml(item.country) + '" class="country-flag"> ';
                    }
                    html += self.escapeHtml(item.country);
                } else {
                    html += 'N/A';
                }
                html += '</td></tr>';
                html += '<tr><td>Region:</td><td>' + self.escapeHtml(item.region || 'N/A') + '</td></tr>';
                html += '<tr><td>City:</td><td>' + self.escapeHtml(item.city || 'N/A') + '</td></tr>';
                html += '</table>';
                html += '</div>';

                // Network Information
                html += '<div class="whois-info-block">';
                html += '<h4>🌐 Network Information</h4>';
                html += '<table class="whois-table">';
                html += '<tr><td>ISP:</td><td>' + self.escapeHtml(item.isp || 'N/A') + '</td></tr>';
                html += '<tr><td>Organization:</td><td>' + self.escapeHtml(item.org || 'N/A') + '</td></tr>';
                html += '<tr><td>ASN:</td><td>' + self.escapeHtml(item.as || 'N/A') + '</td></tr>';
                html += '</table>';
                html += '</div>';

                html += '</div>';
            });

            resultsContainer.html(html);
            
            // Scroll modal body to top
            $('.vmpfence-whois-modal-body').scrollTop(0);
            
            // Bind Block IP buttons in modal
            self.bindModalBlockIPButtons();
        },

        /**
         * Bind Block IP buttons inside modal
         */
        bindModalBlockIPButtons: function() {
            const self = this;
            
            $('.whois-block-ip-btn-inline-modal').off('click').on('click', function() {
                const ip = $(this).data('ip');
                
                if (!ip) {
                    VMPFenceNotifications.showError('Invalid IP address', 3000);
                    return;
                }
                
                // Close modal first
                self.hideWhoisModal();
                
                // Small delay to allow modal to close smoothly
                setTimeout(function() {
                    // Navigate to Firewall > Blocking with prefill parameter
                    const blockingUrl = 'admin.php?page=vmpfence-firewall&tab=blocking&prefill_ip=' + encodeURIComponent(ip) + '&source=whois';
                    window.location.href = blockingUrl;
                }, 200);
            });
        },

        /**
         * Hide Whois Modal
         */
        hideWhoisModal: function() {
            const modal = $('#vmpfence-whois-modal');
            modal.removeClass('show');
            
            // Unbind ESC key handler to prevent memory leaks
            $(document).off('keydown.vmpfenceWhoisModal');
            
            // Wait for animation then hide
            setTimeout(function() {
                modal.hide();
                modal.find('.vmpfence-whois-modal-loading').hide();
                modal.find('.vmpfence-whois-modal-results').html('');
            }, 200);
        },

        /**
         * Show Recent Traffic Modal
         */
        showRecentTrafficModal: function(ip) {
            const self = this;
            const modal = $('#vmpfence-recent-traffic-modal');
            
            // Don't show if another modal is already open
            if ($('.vmpfence-notification-modal.show').length > 0) {
                return;
            }
            
            // Update title with IP
            modal.find('.modal-title-text').text('Recent Activity for ' + ip);
            
            // Show modal
            modal.show().addClass('show');
            
            // Show loading state
            modal.find('.vmpfence-recent-traffic-modal-loading').show();
            modal.find('.vmpfence-recent-traffic-modal-results').html('');
            
            // Perform lookup
            this.fetchRecentTrafficByIP(ip);
        },

        /**
         * Fetch Recent Traffic by IP
         */
        fetchRecentTrafficByIP: function(ip) {
            const self = this;
            const modal = $('#vmpfence-recent-traffic-modal');
            const resultsContainer = modal.find('.vmpfence-recent-traffic-modal-results');
            const loadingContainer = modal.find('.vmpfence-recent-traffic-modal-loading');
            
            $.ajax({
                url: ajaxurl,
                type: 'POST',
                data: {
                    action: 'vmpfence_get_recent_traffic_by_ip',
                    nonce: vmpfenceToolsData.nonce,
                    ip: ip
                },
                success: function(response) {
                    loadingContainer.hide();
                    
                    if (response.success && response.data) {
                        self.displayRecentTrafficResults(response.data);
                    } else {
                        const errorMsg = (response.data && response.data.message) ? response.data.message : 'Failed to load recent activity';
                        resultsContainer.html('<div class="vmpfence-no-recent-activity"><span class="dashicons dashicons-warning"></span><p><strong>Error:</strong> ' + self.escapeHtml(errorMsg) + '</p></div>');
                    }
                },
                error: function() {
                    loadingContainer.hide();
                    resultsContainer.html('<div class="vmpfence-no-recent-activity"><span class="dashicons dashicons-warning"></span><p><strong>Network Error:</strong> Unable to load recent activity.</p></div>');
                }
            });
        },

        /**
         * Display Recent Traffic Results
         */
        displayRecentTrafficResults: function(data) {
            const self = this;
            const resultsContainer = $('#vmpfence-recent-traffic-modal-results');
            const ip = data.ip || '';
            const total = data.total || 0;
            const entries = data.data || [];
            
            if (entries.length === 0) {
                resultsContainer.html(
                    '<div class="vmpfence-no-recent-activity">' +
                    '<span class="dashicons dashicons-clock"></span>' +
                    '<p><strong>No Recent Activity</strong></p>' +
                    '<p>No traffic records found for this IP address.</p>' +
                    '</div>'
                );
                return;
            }
            
            let html = '';
            
            // Add Block IP button at top
            html += '<div style="margin-bottom: 20px; display: flex; justify-content: space-between; align-items: center;">';
            html += '<div><strong>Total hits:</strong> ' + parseInt(total) + ' | <strong>Showing:</strong> Latest ' + parseInt(entries.length) + ' entries</div>';
            html += '<button class="vmpfence-btn vmpfence-btn-danger recent-traffic-block-ip-btn" data-ip="' + self.escapeHtml(ip) + '" style="background: #dc3545; color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer; font-weight: 600;">🛡️ BLOCK IP</button>';
            html += '</div>';
            
            // Render each entry
            entries.forEach(function(entry, index) {
                html += '<div class="vmpfence-activity-entry">';
                
                // Header with time and seconds since last
                html += '<div class="vmpfence-activity-entry-header">';
                html += '<div class="vmpfence-activity-time">';
                html += '⏰ ' + self.escapeHtml(entry.formatted_time);
                html += '<span class="vmpfence-activity-time-ago">(' + self.escapeHtml(entry.time_ago) + ')</span>';
                html += '</div>';
                
                if (entry.seconds_since_last > 0) {
                    html += '<div class="vmpfence-activity-seconds-since">';
                    html += '⏱️ ' + parseFloat(entry.seconds_since_last).toFixed(4) + ' sec since last hit';
                    html += '</div>';
                }
                html += '</div>';
                
                // URL
                html += '<div class="vmpfence-activity-url">';
                html += '<strong>URL:</strong> <a href="' + self.escapeHtml(entry.URL) + '" target="_blank">' + self.escapeHtml(entry.URL) + '</a>';
                html += '</div>';
                
                // Meta info (Type, Status Code)
                html += '<div class="vmpfence-activity-meta">';
                
                // Type badge
                let typeClass = 'normal';
                if (entry.request_type.includes('Blocked')) {
                    typeClass = 'blocked';
                } else if (entry.request_type.includes('Login')) {
                    typeClass = 'login';
                } else if (entry.request_type.includes('Logout')) {
                    typeClass = 'logout';
                } else if (entry.request_type.includes('404')) {
                    typeClass = 'not-found';
                }
                html += '<div class="vmpfence-activity-meta-item">';
                html += '<span class="vmpfence-activity-meta-label">Type:</span>';
                html += '<span class="vmpfence-activity-type-badge ' + typeClass + '">' + self.escapeHtml(entry.request_type) + '</span>';
                html += '</div>';
                
                // Status code
                html += '<div class="vmpfence-activity-meta-item">';
                html += '<span class="vmpfence-activity-meta-label">Status:</span> ' + parseInt(entry.statusCode || 200);
                html += '</div>';
                
                html += '</div>';
                
                // Referrer (if exists)
                if (entry.referer && entry.referer !== '-') {
                    html += '<div class="vmpfence-activity-referrer">';
                    html += '<strong>Referrer:</strong> <a href="' + self.escapeHtml(entry.referer) + '" target="_blank">' + self.escapeHtml(entry.referer) + '</a>';
                    html += '</div>';
                }
                
                // User Agent
                if (entry.UA) {
                    html += '<div class="vmpfence-activity-browser">';
                    html += '<strong>Browser:</strong> ' + self.escapeHtml(entry.UA);
                    html += '</div>';
                }
                
                html += '</div>'; // .vmpfence-activity-entry
            });
            
            resultsContainer.html(html);
            
            // Reset scroll position
            $('.vmpfence-recent-traffic-modal-body').scrollTop(0);
            
            // Bind Block IP button
            self.bindRecentTrafficBlockIPButton();
        },

        /**
         * Bind Block IP Button in Recent Traffic Modal
         */
        bindRecentTrafficBlockIPButton: function() {
            const self = this;
            
            $('.recent-traffic-block-ip-btn').off('click').on('click', function() {
                const ip = $(this).data('ip');
                self.hideRecentTrafficModal();
                
                setTimeout(function() {
                    const blockingUrl = 'admin.php?page=vmpfence-firewall&tab=blocking&prefill_ip=' + encodeURIComponent(ip) + '&source=recent-traffic';
                    window.location.href = blockingUrl;
                }, 200);
            });
        },

        /**
         * Hide Recent Traffic Modal
         */
        hideRecentTrafficModal: function() {
            const modal = $('#vmpfence-recent-traffic-modal');
            modal.removeClass('show');
            
            // Unbind ESC key handler
            $(document).off('keydown.vmpfenceRecentTrafficModal');
            
            // Wait for animation then hide
            setTimeout(function() {
                modal.hide();
                modal.find('.vmpfence-recent-traffic-modal-loading').hide();
                modal.find('.vmpfence-recent-traffic-modal-results').html('');
            }, 200);
        },

        /**
         * Escape HTML to prevent XSS
         */
        escapeHtml: function(text) {
            if (text === null || text === undefined) {
                return '';
            }
            const map = {
                '&': '&amp;',
                '<': '&lt;',
                '>': '&gt;',
                '"': '&quot;',
                "'": '&#039;'
            };
            return String(text).replace(/[&<>"']/g, function(m) { return map[m]; });
        },

        /**
         * WHOIS Lookup - Display results
         */
        displayWhoisResults: function(data) {
            const self = this;
            const results = $('#whois-results');
            let html = '';

            if (!data || !data.data || !Array.isArray(data.data)) {
                results.html('<div class="whois-error">No data received</div>').show();
                return;
            }

            // Ensure we have at least one result
            if (data.data.length === 0) {
                results.html('<div class="whois-error">No results found</div>').show();
                return;
            }

            // Show resolution info if domain lookup
            if (data.resolved) {
                html += '<div class="whois-resolution-info">';
                html += '<h3>🌐 Domain Resolution: ' + self.escapeHtml(data.resolved.domain) + '</h3>';
                html += '<p>Found ' + parseInt(data.resolved.ipv4_count || 0) + ' IPv4 and ' + parseInt(data.resolved.ipv6_count || 0) + ' IPv6 address(es)</p>';
                html += '</div>';
            }

            // Display each IP result
            data.data.forEach(function(item, index) {
                const ipType = self.escapeHtml(item.ip_type || 'IP');
                const ipIndex = item.ip_index ? ' #' + parseInt(item.ip_index) : '';

                html += '<div class="whois-result-card">';
                html += '<div class="whois-card-header">';
                html += '<h3>' + ipType + ipIndex + ' Information</h3>';
                html += '</div>';

                // IP Information
                html += '<div class="whois-info-block">';
                html += '<h4>📍 IP Information</h4>';
                html += '<table class="whois-table">';
                html += '<tr><td>IP Address:</td><td>';
                html += '<div class="whois-ip-with-button">';
                html += '<code>' + self.escapeHtml(item.ip || 'N/A') + '</code>';
                html += '<button class="whois-block-ip-btn-inline" data-ip="' + self.escapeHtml(item.ip || '') + '" title="Block this IP address">';
                html += '🛡️ Block IP';
                html += '</button>';
                html += '</div>';
                html += '</td></tr>';
                html += '<tr><td>Type:</td><td>' + self.escapeHtml(item.type || 'N/A') + '</td></tr>';
                html += '<tr><td>Country:</td><td>';
                if (item.country_flag) {
                    html += '<img src="' + self.escapeHtml(item.country_flag) + '" alt="" class="country-flag"> ';
                }
                html += self.escapeHtml(item.country || 'N/A') + ' (' + self.escapeHtml(item.country_code || 'N/A') + ')</td></tr>';
                html += '<tr><td>Region:</td><td>' + self.escapeHtml(item.region || 'N/A') + '</td></tr>';
                html += '<tr><td>City:</td><td>' + self.escapeHtml(item.city || 'N/A') + '</td></tr>';
                html += '<tr><td>Coordinates:</td><td>' + self.escapeHtml(item.latitude || 'N/A') + ', ' + self.escapeHtml(item.longitude || 'N/A') + '</td></tr>';
                html += '<tr><td>Timezone:</td><td>' + self.escapeHtml(item.timezone_name || 'N/A') + ' (UTC' + self.escapeHtml(item.timezone_gmt || 'N/A') + ')</td></tr>';
                html += '</table>';
                html += '</div>';

                // Network Information
                html += '<div class="whois-info-block">';
                html += '<h4>🌐 Network Information</h4>';
                html += '<table class="whois-table">';
                html += '<tr><td>ISP:</td><td>' + self.escapeHtml(item.isp || 'N/A') + '</td></tr>';
                html += '<tr><td>Organization:</td><td>' + self.escapeHtml(item.org || 'N/A') + '</td></tr>';
                html += '<tr><td>ASN:</td><td>' + self.escapeHtml(item.asn || 'N/A') + '</td></tr>';
                html += '</table>';
                html += '</div>';

                html += '</div>';
            });

            results.html(html).slideDown(300);
            
            // Bind click handler for Block IP buttons (inline next to IP address)
            $('.whois-block-ip-btn-inline').on('click', function() {
                const ip = $(this).data('ip');
                if (!ip) {
                    VMPFenceNotifications.showError('Invalid IP address', 3000);
                    return;
                }
                
                // Navigate to Firewall > Blocking with prefill parameter and source
                const blockingUrl = 'admin.php?page=vmpfence-firewall&tab=blocking&prefill_ip=' + encodeURIComponent(ip) + '&source=whois';
                window.location.href = blockingUrl;
            });
        },

        /**
         * Initialize diagnostics accordion
         */
        initDiagnosticsAccordion: function() {
            // Handle accordion header clicks
            $(document).on('click', '.diagnostics-accordion-header', function() {
                const $item = $(this).closest('.diagnostics-accordion-item');
                const $content = $item.find('.diagnostics-accordion-content');
                const isActive = $item.hasClass('active');

                // Toggle active class and slide content
                if (isActive) {
                    $item.removeClass('active');
                    $content.slideUp(300);
                     } else {
                                $item.addClass('active');
                                $content.slideDown(300);
                            }
            });
                    
            // Handle Expand All button
            $(document).on('click', '.diagnostics-button-secondary', function() {
                const $button = $(this);
                const isExpanded = $button.text().includes('COLLAPSE');
                    
                if (isExpanded) {
                    // Collapse all
                    $('.diagnostics-accordion-item').removeClass('active');
                    $('.diagnostics-accordion-content').slideUp(300);
                    $button.text('EXPAND ALL DIAGNOSTICS');
                    } else {
                                // Expand all
                                $('.diagnostics-accordion-item').addClass('active');
                                $('.diagnostics-accordion-content').slideDown(300);
                                $button.text('COLLAPSE ALL DIAGNOSTICS');
                            }
            });
        },
        
        /**
         * Export configuration to cloud
         */
        exportConfig: function() {
            const self = this;
            const btn = $('#export-config-btn');
            const resultDiv = $('#export-result');

            // Disable button and show loading
            btn.prop('disabled', true).text('EXPORTING...');
            resultDiv.hide().html('');
            
            // Show loading toast
            VMPFenceNotifications.showInfo('Exporting configuration...', 0);

            $.ajax({
                url: vmpfenceToolsData.ajaxurl,
                type: 'POST',
                data: {
                    action: 'vmpfence_export_config',
                    nonce: vmpfenceToolsData.nonce
                },
                success: function(response) {
                    // Close loading toast
                    VMPFenceNotifications.clearAll();
                                        
                    if (response && response.success && response.data) {
                        const data = response.data;
                        
                        // Validate we have a token
                        if (!data.token) {
                            VMPFenceNotifications.showError('Export failed: No token received', 5000);
                            return;
                        }
                        
                        const expiresDate = new Date(data.expires_at).toLocaleString();
                        
                        // Show success toast
                        VMPFenceNotifications.showSuccess(data.message || 'Configuration exported successfully!', 3000);
                        
                        // Display token information
                        let html = '<div class="import-export-token-display">';
                        html += '<div class="import-export-success-message">';
                        html += '<span class="dashicons dashicons-yes-alt"></span>';
                        html += '<span>' + self.escapeHtml(data.message || 'Configuration exported successfully') + '</span>';
                        html += '</div>';
                        html += '<div class="import-export-token-info">';
                        html += '<strong>Your Export Token:</strong>';
                        html += '<div class="token-value" id="export-token-value">' + self.escapeHtml(data.token) + '</div>';
                        html += '<button type="button" class="copy-token-btn" onclick="vmpfenceCopyToken()">COPY TOKEN</button>';
                        html += '</div>';
                        html += '<div class="token-expiry">Token expires: ' + expiresDate + '</div>';
                        if (data.sections && data.sections.length > 0) {
                            html += '<div class="token-sections">Exported sections: ' + data.sections.join(', ') + '</div>';
                        }
                        html += '</div>';
                        
                        resultDiv.html(html).slideDown();
                    } else {
                        // Handle error response - wp_send_json_error puts message in response.data directly
                        let errorMsg = 'Unknown error';
                        
                        if (response && response.data) {
                            // If response.data is a string, use it directly
                            if (typeof response.data === 'string') {
                                errorMsg = response.data;
                            } 
                            // If response.data has a message property
                            else if (response.data.message) {
                                errorMsg = response.data.message;
                            }
                            // If response.data is an object, try to extract meaningful info
                            else if (typeof response.data === 'object') {
                                errorMsg = JSON.stringify(response.data);
                            }
                        }
                        
                        console.error('Export failed:', errorMsg, response);
                        VMPFenceNotifications.showError(errorMsg, 5000);
                    }
                },
                error: function(xhr, status, error) {
                    VMPFenceNotifications.clearAll();
                    VMPFenceNotifications.showError('Network error: Unable to connect to server. Please try again.', 5000);
                },
                complete: function() {
                    btn.prop('disabled', false).text('EXPORT OPTIONS');
                }
            });
        },

        /**
         * Import configuration from cloud
         */
        importConfig: function() {
            const self = this;
            const btn = $('#import-config-btn');
            const resultDiv = $('#import-result');
            const token = $('#import-token').val().trim();

            // Validate token is not empty
            if (!token) {
                VMPFenceNotifications.showWarning('Please enter a token to import configuration.', 3000);
                return;
            }
            
            // Validate token format (12 alphanumeric characters)
            if (!/^[a-zA-Z0-9]{12}$/.test(token)) {
                VMPFenceNotifications.showWarning('Invalid token format. Token should be 12 alphanumeric characters.', 4000);
                return;
            }

            // Disable button and show loading
            btn.prop('disabled', true).text('IMPORTING...');
            resultDiv.hide().html('');
            
            // Show loading toast
            VMPFenceNotifications.showInfo('Importing configuration...', 0);

            $.ajax({
                url: vmpfenceToolsData.ajaxurl,
                type: 'POST',
                data: {
                    action: 'vmpfence_import_config',
                    nonce: vmpfenceToolsData.nonce,
                    token: token
                },
                success: function(response) {
                    // Close loading toast
                    VMPFenceNotifications.clearAll();
                    
                    if (response && response.success && response.data) {
                        const data = response.data;
                        const message = data.message || 'Configuration imported successfully!';
                        const sections = (data.sections && data.sections.length > 0) ? data.sections.join(', ') : 'all sections';
                        
                        // Show success toast with details
                        VMPFenceNotifications.showSuccess(message + ' (Imported: ' + sections + ')', 3000);
                        
                        // Clear token field
                        $('#import-token').val('');
                        
                        // Refresh page after 2 seconds to show imported settings
                        setTimeout(function() {
                            window.location.reload();
                        }, 2000);
                    } else {
                        const errorMsg = (response && response.data && response.data.message) || 'Import failed. Please check your token and try again.';
                        VMPFenceNotifications.showError(errorMsg, 5000);
                    }
                },
                error: function(xhr, status, error) {
                    VMPFenceNotifications.clearAll();
                    VMPFenceNotifications.showError('Network error: Unable to connect to server. Please try again.', 5000);
                },
                complete: function() {
                    btn.prop('disabled', false).text('IMPORT OPTIONS');
                }
            });
        },

        /**
         * Copy token to clipboard
         */
        copyToken: function() {
            const tokenElement = document.getElementById('export-token-value');
            if (!tokenElement) return;

            const token = tokenElement.textContent;
            
            // Modern clipboard API
            if (navigator.clipboard && navigator.clipboard.writeText) {
                navigator.clipboard.writeText(token).then(function() {
                    VMPFenceNotifications.showSuccess('Token copied to clipboard!', 2000);
                }).catch(function() {
                    VMPFenceTools.fallbackCopyToken(token);
                });
            } else {
                VMPFenceTools.fallbackCopyToken(token);
            }
        },

        /**
         * Fallback copy method for older browsers
         */
        fallbackCopyToken: function(token) {
            const textArea = document.createElement('textarea');
            textArea.value = token;
            textArea.style.position = 'fixed';
            textArea.style.left = '-9999px';
            document.body.appendChild(textArea);
            textArea.select();
            
            try {
                document.execCommand('copy');
                VMPFenceNotifications.showSuccess('Token copied to clipboard!', 2000);
            } catch (err) {
                VMPFenceNotifications.showError('Failed to copy token', 3000);
            }
            
            document.body.removeChild(textArea);
        }
    };

    // Initialize when document is ready
    $(document).ready(function() {
        if ($('.vmpfence-tools-container').length) {
            VMPFenceTools.init();
            VMPFenceTools.loadOptions(); // Load saved options
        }
    });

    // Expose to global scope for onclick handlers
    window.VMPFenceTools = VMPFenceTools;

})(jQuery);

// Global functions for onclick handlers
function vmpfenceExportConfig() {
    if (typeof jQuery !== 'undefined' && typeof window.VMPFenceTools !== 'undefined') {
        window.VMPFenceTools.exportConfig();
    }
}

function vmpfenceImportConfig() {
    if (typeof jQuery !== 'undefined' && typeof window.VMPFenceTools !== 'undefined') {
        window.VMPFenceTools.importConfig();
    }
}

function vmpfenceCopyToken() {
    if (typeof jQuery !== 'undefined' && typeof window.VMPFenceTools !== 'undefined') {
        window.VMPFenceTools.copyToken();
    }
}
