/**
 * YARA Deep Scan Page JavaScript
 * Handles file uploads, WordPress file scanning, and results display
 * @package VMPFence
 * @since 2.1.0
 */

(function($) {
    'use strict';

    var YaraScanner = {
        selectedFile: null,
        selectedWPFiles: [],
        wpFileList: [], // Store WordPress file metadata (name, path, size, type)
        scanHistory: [],
        activeBatchIds: [], // Track active batch IDs for cancellation
        currentSessionBatches: [], // Track current scan session batches
        isScanning: false, // Track if scan is in progress
        stats: {
            totalScans: 0,
            threatsFound: 0,
            cleanFiles: 0
        },
        performanceMetrics: {
            avg_seconds_per_mb: 2.5, // Default baseline (hybrid approach)
            total_scans: 0,
            base_overhead: 1.0 // Base network/processing overhead in seconds
        },
        scanStartTime: null,
        estimatedTotalTime: 0,

        init: function() {
            // Initialize toast notification system
            if (typeof VMPFenceNotifications !== 'undefined') {
                VMPFenceNotifications.init();
            }
            
            this.loadPerformanceMetrics();
            this.bindEvents();
            this.loadStats();
            this.loadHistory();
            this.updateYARAServerStats(); // Fetch real-time rule count from server
            this.setupPageUnloadHandler(); // Cancel scans on page close
        },
        
        loadPerformanceMetrics: function() {
            var self = this;
            $.ajax({
                url: vmpfence_yara.ajax_url,
                type: 'POST',
                data: {
                    action: 'vmpfence_yara_get_performance_metrics',
                    nonce: vmpfence_yara.nonce
                },
                success: function(response) {
                    if (response.success && response.data) {
                        self.performanceMetrics.avg_seconds_per_mb = response.data.avg_seconds_per_mb || 2.5;
                        self.performanceMetrics.total_scans = response.data.total_scans || 0;
                    }
                }
            });
        },
        
        estimateScanTime: function(fileSizeBytes) {
            var fileSizeMB = fileSizeBytes / (1024 * 1024);
            var baseOverhead = this.performanceMetrics.base_overhead;
            var avgSecondsPerMB = this.performanceMetrics.avg_seconds_per_mb;
            
            // Hybrid approach: use historical data if available (20+ scans), otherwise use file size baseline
            if (this.performanceMetrics.total_scans < 20) {
                // File size baseline for new installations
                if (fileSizeMB < 0.1) {
                    return 1 + baseOverhead; // Small files: ~2s
                } else if (fileSizeMB < 1) {
                    return (fileSizeMB * 2) + baseOverhead; // Medium: ~2-3s
                } else {
                    return (fileSizeMB * 3) + baseOverhead; // Large: ~3-5s per MB
                }
            } else {
                // Historical average (learned from actual scans)
                return (fileSizeMB * avgSecondsPerMB) + baseOverhead;
            }
        },
        
        formatTimeEstimate: function(seconds) {
            if (seconds < 60) {
                return Math.round(seconds) + 's';
            } else if (seconds < 3600) {
                var minutes = Math.floor(seconds / 60);
                var secs = Math.round(seconds % 60);
                return minutes + 'm ' + secs + 's';
            } else {
                var hours = Math.floor(seconds / 3600);
                var mins = Math.round((seconds % 3600) / 60);
                return hours + 'h ' + mins + 'm';
            }
        },

        setupPageUnloadHandler: function() {
            var self = this;
            
            // Cancel all session batches when user leaves/reloads page
            $(window).on('beforeunload', function() {
                if (self.isScanning && self.currentSessionBatches.length > 0) {
                    // Cancel all batches in current session synchronously
                    self.currentSessionBatches.forEach(function(batchId) {
                        $.ajax({
                            url: vmpfence_yara.ajax_url,
                            type: 'POST',
                            async: false,
                            data: {
                                action: 'vmpfence_yara_cancel_batch',
                                nonce: vmpfence_yara.nonce,
                                batch_id: batchId
                            }
                        });
                    });
                    self.scanStartTime = null;
                    self.estimatedTotalTime = 0;
                    self.isScanning = false;
                    self.currentSessionBatches = [];
                }
            });
        },

        bindEvents: function() {
            var self = this;

            // Tab switching
            $('.vmpfence-tab').on('click', function() {
                var tab = $(this).data('tab');
                $('.vmpfence-tab').removeClass('active');
                $(this).addClass('active');
                $('.vmpfence-tab-content').removeClass('active');
                $('#' + tab + '-tab').addClass('active');

                // Load WordPress files when tab is opened
                if (tab === 'wordpress' && self.selectedWPFiles.length === 0) {
                    self.loadWordPressFiles();
                }
                
                // Load whitelisted files when tab is opened
                if (tab === 'whitelisted') {
                    self.loadWhitelistedFiles();
                }
            });

            // File upload handling
            $('#select-file-btn').on('click', function() {
                $('#file-input').click();
            });

            $('#file-input').on('change', function(e) {
                if (e.target.files.length > 0) {
                    self.handleFileSelect(e.target.files[0]);
                }
            });

            // Drag and drop
            $('#upload-area').on('dragover', function(e) {
                e.preventDefault();
                e.stopPropagation();
                $(this).addClass('dragover');
            });

            $('#upload-area').on('dragleave', function(e) {
                e.preventDefault();
                e.stopPropagation();
                $(this).removeClass('dragover');
            });

            $('#upload-area').on('drop', function(e) {
                e.preventDefault();
                e.stopPropagation();
                $(this).removeClass('dragover');
                
                var files = e.originalEvent.dataTransfer.files;
                if (files.length > 0) {
                    self.handleFileSelect(files[0]);
                }
            });

            $('#remove-file').on('click', function() {
                self.clearSelectedFile();
            });

            $('#scan-file-btn').on('click', function() {
                self.scanUploadedFile();
            });

            // Sync YARA rules button
            $('#sync-yara-rules-btn').on('click', function() {
                self.syncYARARules();
            });

            // WordPress file scanning - Batch mode (primary method)
            $('#scan-selected-btn').on('click', function() {
                self.scanWordPressFilesBatch();
            });
            
            // Cancel scan button (main page)
            $('#cancel-scan-btn').on('click', function() {
                self.cancelCurrentScan();
            });
            
            // Cancel scan button (modal)
            $('#cancel-scan-btn-modal').on('click', function() {
                self.cancelCurrentScan();
            });
            
            // Select All checkbox - selects ALL files regardless of filters
            $('#select-all-files').on('change', function() {
                if ($(this).is(':checked')) {
                    // Uncheck all filter options
                    $('#filter-plugins, #filter-themes, #filter-core, #filter-uploads, #filter-custom').prop('checked', false);
                    // Check all files
                    $('.file-checkbox').prop('checked', true);
                } else {
                    // Uncheck all files
                    $('.file-checkbox').prop('checked', false);
                }
                self.updateSelectedFiles();
            });

            // File type filter checkboxes - select only matching files
            $('#filter-plugins, #filter-themes, #filter-core, #filter-uploads').on('change', function() {
                // Uncheck Select All and Custom when any type filter is clicked
                $('#select-all-files, #filter-custom').prop('checked', false);
                self.selectFilesByType();
            });
            
            // Custom filter - manual selection mode
            $('#filter-custom').on('change', function() {
                if ($(this).is(':checked')) {
                    // Uncheck Select All and all type filters when Custom is selected
                    $('#select-all-files, #filter-plugins, #filter-themes, #filter-core, #filter-uploads').prop('checked', false);
                }
                // Keep current file selections as-is in custom mode
                self.updateSelectedFiles();
            });
            
            // Individual file checkbox - switches to Custom mode
            $(document).on('change', '.file-checkbox', function() {
                // Check if user is manually toggling files
                var anyTypeFilterChecked = $('#filter-plugins, #filter-themes, #filter-core, #filter-uploads').is(':checked');
                var selectAllChecked = $('#select-all-files').is(':checked');
                
                // If a type filter or Select All is active, switching to manual selection means Custom mode
                if (anyTypeFilterChecked || selectAllChecked) {
                    $('#select-all-files, #filter-plugins, #filter-themes, #filter-core, #filter-uploads').prop('checked', false);
                    $('#filter-custom').prop('checked', true);
                }
                
                self.updateSelectedFiles();
            });

            // History
            $('#refresh-history').on('click', function() {
                self.loadHistory();
            });

            $('#history-filter').on('change', function() {
                self.filterHistory($(this).val());
            });

            $('#history-search').on('input', function() {
                self.searchHistory($(this).val());
            });
            
            // Whitelist tab handlers
            $('#refresh-whitelist').on('click', function() {
                self.loadWhitelistedFiles();
            });
            
            // Handle unwhitelist button clicks (delegated)
            $(document).on('click', '.unwhitelist-file-btn', function() {
                var fileHash = $(this).data('hash');
                var fileName = $(this).data('name');
                self.unwhitelistFile(fileHash, fileName);
            });

            // Modal
            $('#close-modal, #close-modal-btn').on('click', function() {
                $('#results-modal').hide();
            });

            $('#download-report').on('click', function() {
                self.downloadReport();
            });
        },

        handleFileSelect: function(file) {
            // Validate file size (10MB max)
            if (file.size > 10 * 1024 * 1024) {
                VMPFenceNotifications.showError('File size exceeds 10MB limit. Please select a smaller file.', 5000);
                return;
            }

            this.selectedFile = file;
            $('#upload-area').hide();
            $('#file-info').show();
            $('#file-name').text(file.name);
            $('#file-size').text(this.formatFileSize(file.size));
        },

        clearSelectedFile: function() {
            this.selectedFile = null;
            $('#file-input').val('');
            $('#file-info').hide();
            $('#upload-area').show();
        },

        scanUploadedFile: function() {
            if (!this.selectedFile) return;

            var self = this;
            var reader = new FileReader();

            reader.onload = function(e) {
                var fileContent = e.target.result.split(',')[1]; // Get base64 content
                var fileHash = self.calculateHash(fileContent);
                
                // Calculate ETA and start timer
                self.scanStartTime = Date.now();
                self.estimatedTotalTime = self.estimateScanTime(self.selectedFile.size);
                var etaText = 'Estimated: ' + self.formatTimeEstimate(self.estimatedTotalTime);

                self.showProgress(
                    'Scanning ' + self.selectedFile.name + ' (' + self.formatFileSize(self.selectedFile.size) + ')',
                    'Analyzing with 996+ YARA rules... | ' + etaText
                );

                $.ajax({
                    url: vmpfence_yara.ajax_url,
                    type: 'POST',
                    data: {
                        action: 'vmpfence_yara_scan_file',
                        nonce: vmpfence_yara.nonce,
                        file_name: self.selectedFile.name,
                        file_content: fileContent,
                        file_hash: fileHash,
                        scan_reason: 'manual_upload'
                    },
                    success: function(response) {
                        var elapsedTime = (Date.now() - self.scanStartTime) / 1000;
                        self.scanStartTime = null;
                        self.estimatedTotalTime = 0;
                        self.hideProgress();
                        if (response.success) {
                            // Add elapsed time to results
                            response.data.elapsed_time = self.formatTimeEstimate(elapsedTime);
                            self.showResults(response.data);
                            self.updateStats();
                            self.loadHistory();
                            self.loadPerformanceMetrics(); // Reload for updated estimates
                            self.clearSelectedFile();
                        } else {
                            VMPFenceNotifications.showError('Scan failed: ' + response.data.message, 6000);
                        }
                    },
                    error: function(xhr, status, error) {
                        self.scanStartTime = null;
                        self.estimatedTotalTime = 0;
                        self.hideProgress();
                        VMPFenceNotifications.showError('Error: ' + error, 6000);
                    }
                });
            };

            reader.readAsDataURL(this.selectedFile);
        },

        loadWordPressFiles: function() {
            var self = this;
            
            $('#file-list').html('<div class="loading-spinner"><span class="spinner is-active"></span><p>Loading WordPress files...</p></div>');

            $.ajax({
                url: vmpfence_yara.ajax_url,
                type: 'POST',
                data: {
                    action: 'vmpfence_get_wp_files',
                    nonce: vmpfence_yara.nonce
                },
                success: function(response) {
                    if (response.success) {
                        self.renderFileList(response.data.files);
                    } else {
                        $('#file-list').html('<p class="no-results">Failed to load files</p>');
                    }
                },
                error: function() {
                    $('#file-list').html('<p class="no-results">Error loading files</p>');
                }
            });
        },

        renderFileList: function(files) {
            var html = '';
            
            // Store file list for smart batching (including size metadata)
            this.wpFileList = files;
            
            $.each(files, function(index, file) {
                html += '<div class="file-item" data-type="' + file.type + '">';
                html += '<label>';
                html += '<input type="checkbox" class="file-checkbox" data-path="' + file.path + '" data-type="' + file.type + '" />';
                html += '<span class="dashicons dashicons-media-code"></span>';
                html += '<span class="file-name">' + file.name + '</span>';
                html += '<span class="file-size">' + YaraScanner.formatFileSize(file.size) + '</span>';
                html += '</label>';
                html += '</div>';
            });

            $('#file-list').html(html);

            // Note: Individual checkbox events are handled via delegated event on document
        },

        selectFilesByType: function() {
            var selectPlugins = $('#filter-plugins').is(':checked');
            var selectThemes = $('#filter-themes').is(':checked');
            var selectCore = $('#filter-core').is(':checked');
            var selectUploads = $('#filter-uploads').is(':checked');
            var selectCustom = $('#filter-custom').is(':checked');

            // If Custom is checked, don't auto-select anything (manual selection mode)
            if (selectCustom) {
                // Keep current selections as-is, just update count
                this.updateSelectedFiles();
                return;
            }

            // If no filters selected, uncheck all
            if (!selectPlugins && !selectThemes && !selectCore && !selectUploads) {
                $('.file-checkbox').prop('checked', false);
                this.updateSelectedFiles();
                return;
            }

            // Select files based on active filters using the data-type attribute
            // Multiple filters can be active simultaneously (additive selection)
            $('.file-item').each(function() {
                var checkbox = $(this).find('.file-checkbox');
                var fileType = checkbox.data('type');
                var shouldSelect = false;

                // Check if this file type matches any active filter
                if (selectPlugins && fileType === 'plugin') {
                    shouldSelect = true;
                }
                if (selectThemes && fileType === 'theme') {
                    shouldSelect = true;
                }
                if (selectCore && fileType === 'core') {
                    shouldSelect = true;
                }
                if (selectUploads && fileType === 'upload') {
                    shouldSelect = true;
                }

                checkbox.prop('checked', shouldSelect);
            });

            // Update selected count after filtering
            this.updateSelectedFiles();
        },

        updateSelectedFiles: function() {
            this.selectedWPFiles = [];
            $('.file-checkbox:checked').each(function() {
                YaraScanner.selectedWPFiles.push($(this).data('path'));
            });

            var count = this.selectedWPFiles.length;
            $('#selected-count').text(count);
            
            // Show/hide summary based on selection
            if (count > 0) {
                $('#selected-summary').show();
                $('#scan-selected-btn').prop('disabled', false);
                
                // Show info if over 100 files (will be split into batches)
                if (count > 100) {
                    var numBatches = Math.ceil(count / 100);
                    $('#batch-size-warning').text('(Will be processed in ' + numBatches + ' batches of 100 files each)').show();
                } else {
                    $('#batch-size-warning').hide();
                }
            } else {
                $('#selected-summary').hide();
                $('#batch-size-warning').hide();
                $('#scan-selected-btn').prop('disabled', true);
            }
        },

        scanWordPressFiles: function() {
            if (this.selectedWPFiles.length === 0) return;

            var self = this;
            var totalFiles = this.selectedWPFiles.length;
            var scanned = 0;
            var threatsFound = 0;

            self.showProgress('Scanning WordPress Files', 'Preparing to scan ' + totalFiles + ' files...');

            function scanNext() {
                if (scanned >= totalFiles) {
                    self.scanStartTime = null;
                    self.estimatedTotalTime = 0;
                    self.hideProgress();
                    var message = '<strong>Scan Complete!</strong><br><br>';
                    message += 'Files Scanned: <strong>' + scanned + '</strong><br>';
                    message += 'Threats Found: <strong>' + threatsFound + '</strong><br>';
                    message += 'Clean Files: <strong>' + (scanned - threatsFound) + '</strong>';
                    VMPFenceNotifications.showSuccess(message, 7000);
                    self.updateStats();
                    self.loadHistory();
                    $('.file-checkbox').prop('checked', false);
                    $('#select-all-files').prop('checked', false);
                    self.updateSelectedFiles();
                    return;
                }

                var filePath = self.selectedWPFiles[scanned];
                var fileName = filePath.split('/').pop();
                var progress = Math.round(((scanned + 1) / totalFiles) * 100);
                
                // Update progress with consistent layout
                $('#progress-detail').text(progress + '% (' + (scanned + 1) + '/' + totalFiles + ')');
                $('#progress-file-name').text('Scanning: ' + fileName);
                $('#progress-bar').css('width', progress + '%');

                $.ajax({
                    url: vmpfence_yara.ajax_url,
                    type: 'POST',
                    data: {
                        action: 'vmpfence_yara_scan_wp_file',
                        nonce: vmpfence_yara.nonce,
                        file_path: filePath
                    },
                    success: function(response) {
                        if (response.success && response.data && response.data.threats_found > 0) {
                            threatsFound++;
                        }
                        scanned++;
                        scanNext();
                    },
                    error: function() {
                        scanned++;
                        scanNext();
                    }
                });
            }

            scanNext();
        },

        loadStats: function() {
            var self = this;

            $.ajax({
                url: vmpfence_yara.ajax_url,
                type: 'POST',
                data: {
                    action: 'vmpfence_get_yara_stats',
                    nonce: vmpfence_yara.nonce
                },
                success: function(response) {
                    if (response.success) {
                        self.stats = response.data;
                        $('#total-scans').text(self.stats.totalScans || 0);
                        $('#threats-found').text(self.stats.threatsFound || 0);
                        $('#clean-files').text(self.stats.cleanFiles || 0);
                        $('#whitelisted-files').text(self.stats.whitelistedFiles || 0);
                    }
                }
            });
        },

        updateStats: function() {
            this.loadStats();
        },

        loadHistory: function() {
            var self = this;

            $('#history-tbody').html('<tr><td colspan="7" class="no-results"><span class="spinner is-active"></span> Loading scan history...</td></tr>');

            $.ajax({
                url: vmpfence_yara.ajax_url,
                type: 'POST',
                data: {
                    action: 'vmpfence_yara_get_batch_sessions',
                    nonce: vmpfence_yara.nonce
                },
                success: function(response) {
                    // console.log('Batch sessions response:', response);
                    // console.log('Response type:', typeof response);
                    // console.log('Response success:', response.success);
                    // console.log('Response data:', response.data);
                    
                    if (response.success && response.data && response.data.sessions) {
                        // console.log('Sessions array length:', response.data.sessions.length);
                        // console.log('First session:', response.data.sessions[0]);
                        
                        if (response.data.sessions.length > 0) {
                            self.scanHistory = response.data.sessions;
                            // console.log('Loaded ' + self.scanHistory.length + ' batch sessions from WordPress database');
                            self.renderHistory(response.data.sessions);
                        } else {
                            console.warn('Sessions array is empty');
                            $('#history-tbody').html('<tr><td colspan="7" class="no-results">No scan history found (empty array)</td></tr>');
                        }
                    } else {
                        console.error('Invalid response structure:', {
                            hasSuccess: !!response.success,
                            hasData: !!response.data,
                            hasSessions: !!(response.data && response.data.sessions)
                        });
                        $('#history-tbody').html('<tr><td colspan="7" class="no-results">No scan history found (invalid response)</td></tr>');
                    }
                },
                error: function() {
                    $('#history-tbody').html('<tr><td colspan="7" class="no-results">Failed to load scan history</td></tr>');
                }
            });
        },

        renderHistory: function(sessions) {
            var html = '';

            $.each(sessions, function(index, session) {
                var statusClass = session.threats_found > 0 ? 'threat' : 'clean';
                var statusIcon = session.threats_found > 0 ? '⚠️' : '✅';
                var statusText = session.status === 'completed' ? 'Completed' : (session.status === 'in_progress' ? 'In Progress' : 'Pending');
                
                // Format date - handle both 'date' (WordPress saved) and 'started_at' (API format)
                var dateString = session.date || session.started_at;
                var scanDate = dateString ? new Date(dateString.replace(/-/g, '/')) : new Date();
                var formattedDate = scanDate.toLocaleString();
                
                // Calculate duration
                var duration = 'N/A';
                if (session.scan_duration_seconds) {
                    var mins = Math.floor(session.scan_duration_seconds / 60);
                    var secs = session.scan_duration_seconds % 60;
                    duration = mins > 0 ? mins + 'm ' + secs + 's' : secs + 's';
                }
                
                // Use WordPress saved fields (total_files, completed_files) or fallback to API fields
                var totalFiles = session.total_files || 0;
                var scannedFiles = session.completed_files || session.scanned_files || totalFiles;
                
                // Get batch information - use session data if available
                var completedBatches = session.completed_batches || session.total_batches || 1;
                var totalBatches = session.total_batches || 1;
                var batchInfo = completedBatches + ' / ' + totalBatches;
                
                html += '<tr class="scan-session-row" data-session-id="' + session.session_id + '">';
                html += '<td>' + formattedDate + '</td>';
                html += '<td>' + scannedFiles + ' / ' + totalFiles + ' files</td>';
                html += '<td><span class="status-badge ' + statusClass + '">' + statusIcon + ' ' + statusText + '</span></td>';
                html += '<td class="' + (session.threats_found > 0 ? 'threat-count' : '') + '">' + (session.threats_found || 0) + '</td>';
                html += '<td>' + batchInfo + '</td>';
                html += '<td>' + duration + '</td>';
                html += '<td>';
                html += '<button class="button button-small view-session-details" data-session-id="' + session.session_id + '">View Details</button>';
                if (session.threats_found > 0) {
                    html += ' <button class="button button-small view-threats" data-session-id="' + session.session_id + '">View Threats (' + session.threats_found + ')</button>';
                }
                html += '</td>';
                html += '</tr>';
                
                // Add expandable row for details (hidden by default)
                html += '<tr class="session-details-row" id="details-' + session.session_id + '" style="display: none;">';
                html += '<td colspan="7">';
                html += '<div class="session-details-content">';
                html += '<p><strong>Session ID:</strong> ' + session.session_id + '</p>';
                html += '<p><strong>Files:</strong> ' + scannedFiles + ' scanned out of ' + totalFiles + ' total</p>';
                html += '<p><strong>Threats:</strong> ' + (session.threats_found || 0) + ' (High: ' + (session.high_severity || 0) + ', Critical: ' + (session.critical_severity || 0) + ')</p>';
                html += '<p><strong>Breakdown:</strong> Safe: ' + (session.safe || 0) + ', Quarantine: ' + (session.quarantine || 0) + ', Monitor: ' + (session.monitor || 0) + ', Failed: ' + (session.failed_files || 0) + '</p>';
                
                html += '<div class="session-files-list" id="files-' + session.session_id + '"></div>';
                html += '</div>';
                html += '</td>';
                html += '</tr>';
            });

            $('#history-tbody').html(html);

            // Bind click handlers
            $('.view-session-details').on('click', function() {
                var sessionId = $(this).data('session-id');
                YaraScanner.toggleSessionDetails(sessionId);
            });
            
            $('.view-threats').on('click', function() {
                var sessionId = $(this).data('session-id');
                YaraScanner.showThreatsOnly(sessionId);
            });
        },

        toggleSessionDetails: function(sessionId) {
            var detailsRow = $('#details-' + sessionId);
            
            if (detailsRow.is(':visible')) {
                detailsRow.hide();
            } else {
                // Hide all other details
                $('.session-details-row').hide();
                detailsRow.show();
                
                // Load batch files if not already loaded
                if ($('#files-' + sessionId).is(':empty')) {
                    this.loadSessionFiles(sessionId);
                }
            }
        },

        loadSessionFiles: function(sessionId) {
            var self = this;
            var filesContainer = $('#files-' + sessionId);
            
            filesContainer.html('<p><span class="spinner is-active"></span> Loading detailed scan results...</p>');
            
            // Extract batch IDs from session - would need to call API here
            // For now, show a message
            filesContainer.html('<p><em>Detailed file results available. Feature in progress...</em></p>');
        },

        showThreatsOnly: function(sessionId) {
            var self = this;
            var session = this.scanHistory.find(function(s) {
                return s.session_id === sessionId;
            });

            if (!session) {
                VMPFenceNotifications.showError('Session not found', 5000);
                return;
            }

            // Show loading in modal
            var loadingHtml = '<div style="text-align: center; padding: 40px;">';
            loadingHtml += '<div class="spinner is-active" style="float: none; margin: 0 auto 20px;"></div>';
            loadingHtml += '<p>Loading threat details...</p>';
            loadingHtml += '</div>';
            $('#modal-body').html(loadingHtml);
            $('#results-modal').fadeIn(300);

            // Fetch threat details via AJAX
            $.ajax({
                url: vmpfence_yara.ajax_url,
                type: 'POST',
                data: {
                    action: 'vmpfence_yara_get_threats',
                    nonce: vmpfence_yara.nonce,
                    session_id: sessionId
                },
                success: function(response) {
                    if (response.success) {
                        self.displayThreatsModal(session, response.data.threats);
                    } else {
                        VMPFenceNotifications.showError('Failed to load threats: ' + (response.data.message || 'Unknown error'), 6000);
                        $('#results-modal').fadeOut(300);
                    }
                },
                error: function() {
                    VMPFenceNotifications.showError('Failed to load threats. Please try again.', 6000);
                    $('#results-modal').fadeOut(300);
                }
            });
        },

        displayThreatsModal: function(session, threats) {
            var html = '<div class="threat-details-modal">';
            html += '<h2 style="margin-top: 0; color: #d63638;">🛡️ Threat Details</h2>';
            
            // Session summary
            var dateString = session.date || session.started_at;
            var scanDate = dateString ? new Date(dateString.replace(/-/g, '/')) : null;
            
            // Count unique threats from actual data
            var uniqueThreatsCount = Object.keys(threats).length;
            
            html += '<div style="background: #f0f0f1; padding: 15px; border-radius: 4px; margin-bottom: 20px;">';
            html += '<h3 style="margin-top: 0;">Scan Summary</h3>';
            if (scanDate) {
                html += '<p><strong>Scan Date:</strong> ' + scanDate.toLocaleString() + '</p>';
            }
            html += '<p><strong>Total Files Scanned:</strong> ' + (session.total_files || 0) + '</p>';
            html += '<p><strong>Unique Threat Files:</strong> <span style="color: #d63638; font-weight: bold;">' + uniqueThreatsCount + '</span></p>';
            if (uniqueThreatsCount !== (session.threats_found || 0)) {
                html += '<p style="font-size: 12px; color: #666;"><em>Total Detections: ' + (session.threats_found || 0) + ' (includes duplicate file scans)</em></p>';
            }
            html += '<p><strong>Batches:</strong> ' + (session.completed_batches || 1) + ' / ' + (session.total_batches || 1) + '</p>';
            html += '</div>';

            // Threat files
            var threatCount = Object.keys(threats).length;
            if (threatCount === 0) {
                html += '<div style="background: #d4edda; border-left: 4px solid #4caf50; padding: 15px; border-radius: 4px;">';
                html += '<p style="margin: 0; color: #155724;">No active threats found for this scan session.</p>';
                html += '<p style="margin: 10px 0 0 0; color: #666; font-size: 12px;">Note: Threats may have been removed or whitelisted since the scan.</p>';
                html += '</div>';
            } else {
                html += '<h3>Detected Threats (' + threatCount + ')</h3>';
                html += '<div class="threats-list" style="max-height: 400px; overflow-y: auto; border: 1px solid #ddd; border-radius: 4px;">';
                
                var index = 1;
                for (var hash in threats) {
                    if (threats.hasOwnProperty(hash)) {
                        var threat = threats[hash];
                        html += '<div style="padding: 15px; border-bottom: 1px solid #ddd; ' + (index % 2 === 0 ? 'background: #f9f9f9;' : '') + '">';
                        html += '<div style="margin-bottom: 10px;">';
                        html += '<strong style="color: #d63638;">#' + index + ' - ' + (threat.file_name || 'Unknown File') + '</strong>';
                        html += '</div>';
                        
                        html += '<div style="font-size: 12px; color: #666; margin-bottom: 5px;">';
                        html += '<strong>Path:</strong> <code style="background: #f0f0f1; padding: 2px 6px; border-radius: 2px;">' + (threat.file_path || 'N/A') + '</code>';
                        html += '</div>';
                        
                        html += '<div style="font-size: 12px; color: #666; margin-bottom: 5px;">';
                        html += '<strong>Threats:</strong> <span style="color: #d63638;">' + (threat.threats_count || 0) + '</span>';
                        html += '</div>';
                        
                        if (threat.threat_description) {
                            html += '<div style="font-size: 12px; color: #666; margin-bottom: 5px;">';
                            html += '<strong>Detection:</strong> ' + threat.threat_description;
                            html += '</div>';
                        }
                        
                        // Show matched rules
                        if (threat.matched_rules && threat.matched_rules.length > 0) {
                            html += '<div style="margin-top: 10px;">';
                            html += '<strong style="font-size: 12px;">Matched Rules:</strong>';
                            html += '<ul style="margin: 5px 0 0 20px; font-size: 11px;">';
                            threat.matched_rules.forEach(function(rule) {
                                // Handle both old format (string) and new format (object)
                                var ruleName, severity, description;
                                if (typeof rule === 'string') {
                                    // Old format: just rule name as string
                                    ruleName = rule;
                                    severity = 'unknown';
                                    description = '';
                                } else {
                                    // New format: object with rule_name, severity, description
                                    ruleName = rule.rule_name || 'Unknown Rule';
                                    severity = rule.severity || 'unknown';
                                    description = rule.description || '';
                                }
                                
                                var severityColor = severity === 'critical' ? '#d63638' : (severity === 'high' ? '#ff9800' : '#666');
                                html += '<li style="margin-bottom: 3px;">';
                                html += '<span style="color: ' + severityColor + '; font-weight: bold;">' + ruleName + '</span>';
                                if (description) {
                                    html += ' - ' + description;
                                }
                                html += '</li>';
                            });
                            html += '</ul>';
                            html += '</div>';
                        }
                        
                        html += '<div style="margin-top: 10px; font-size: 11px; color: #999;">';
                        html += '<strong>Detected:</strong> ' + (threat.detected_at || 'N/A');
                        html += '</div>';
                        
                        // Action buttons for each threat
                        html += '<div style="margin-top: 15px; padding-top: 10px; border-top: 1px solid #ddd; display: flex; gap: 8px;">';
                        html += '<button class="button button-small threat-action-delete" data-hash="' + hash + '" data-path="' + (threat.file_path || '') + '" data-name="' + (threat.file_name || '') + '" style="background: #d63638; color: white; border-color: #d63638;">';
                        html += '<span class="dashicons dashicons-trash" style="font-size: 14px; width: 14px; height: 14px; margin-top: 2px;"></span> Delete File';
                        html += '</button>';
                        html += '<button class="button button-small threat-action-whitelist" data-hash="' + hash + '" style="background: #2271b1; color: white; border-color: #2271b1;">';
                        html += '<span class="dashicons dashicons-shield" style="font-size: 14px; width: 14px; height: 14px; margin-top: 2px;"></span> Whitelist';
                        html += '</button>';
                        html += '<button class="button button-small threat-action-ignore" data-hash="' + hash + '" style="background: #757575; color: white; border-color: #757575;">';
                        html += '<span class="dashicons dashicons-hidden" style="font-size: 14px; width: 14px; height: 14px; margin-top: 2px;"></span> Ignore';
                        html += '</button>';
                        html += '</div>';
                        
                        html += '</div>';
                        index++;
                    }
                }
                
                html += '</div>';
                
                html += '<div style="margin-top: 20px; padding: 15px; background: #fff3cd; border-left: 4px solid #ff9800; border-radius: 4px;">';
                html += '<strong style="color: #856404;">⚠️ Recommended Actions</strong>';
                html += '<ul style="margin: 10px 0 0 20px; color: #856404;">';
                html += '<li>Review each threat carefully to avoid false positives</li>';
                html += '<li>Quarantine or delete confirmed malicious files</li>';
                html += '<li>Whitelist legitimate files that were incorrectly flagged</li>';
                html += '<li>Run a re-scan after taking action to verify cleanup</li>';
                html += '</ul>';
                html += '</div>';
            }
            
            html += '</div>';
            
            $('#modal-body').html(html);
            
            // Bind action button events
            var self = this;
            $('.threat-action-delete').off('click').on('click', function() {
                var hash = $(this).data('hash');
                var path = $(this).data('path');
                var name = $(this).data('name');
                self.deleteThreatFile(hash, path, name);
            });
            
            $('.threat-action-whitelist').off('click').on('click', function() {
                var hash = $(this).data('hash');
                self.whitelistThreatFile(hash);
            });
            
            $('.threat-action-ignore').off('click').on('click', function() {
                var hash = $(this).data('hash');
                self.ignoreThreatFile(hash);
            });
        },

        deleteThreatFile: function(fileHash, filePath, fileName) {
            var self = this;
            
            VMPFenceNotifications.showConfirmModal({
                title: 'Delete File',
                message: 'Are you sure you want to DELETE this file from your server?<br><br><strong>File:</strong> ' + fileName + '<br><strong>Path:</strong> ' + filePath + '<br><br>This action CANNOT be undone!',
                confirmText: 'Yes, Delete',
                cancelText: 'Cancel',
                type: 'warning'
            }).then(function(confirmed) {
                if (!confirmed) return;
                
                $.ajax({
                    url: vmpfence_yara.ajax_url,
                    type: 'POST',
                    data: {
                        action: 'vmpfence_yara_delete_threat_file',
                        nonce: vmpfence_yara.nonce,
                        file_hash: fileHash
                    },
                    success: function(response) {
                        if (response.success) {
                            VMPFenceNotifications.showSuccess(response.data.message, 4000);
                            // Refresh stats and close modal
                            self.updateStats();
                            $('#modal-overlay').fadeOut();
                        } else {
                            VMPFenceNotifications.showError('Error: ' + response.data.message, 6000);
                        }
                    },
                    error: function() {
                        VMPFenceNotifications.showError('Failed to delete file. Please try again.', 6000);
                    }
                });
            });
        },

        whitelistThreatFile: function(fileHash) {
            var self = this;
            
            VMPFenceNotifications.showConfirmModal({
                title: 'Whitelist File',
                message: 'Add this file to the whitelist?<br><br>This will mark it as safe and exclude it from future scans.',
                confirmText: 'Yes, Whitelist',
                cancelText: 'Cancel',
                type: 'info'
            }).then(function(confirmed) {
                if (!confirmed) return;
                
                $.ajax({
                    url: vmpfence_yara.ajax_url,
                    type: 'POST',
                    data: {
                        action: 'vmpfence_yara_whitelist_file',
                        nonce: vmpfence_yara.nonce,
                        file_hash: fileHash
                    },
                    success: function(response) {
                        if (response.success) {
                            VMPFenceNotifications.showSuccess('File whitelisted successfully', 4000);
                            // Refresh stats and close modal
                            self.updateStats();
                            $('#modal-overlay').fadeOut();
                        } else {
                            VMPFenceNotifications.showError('Error: ' + response.data.message, 6000);
                        }
                    },
                    error: function() {
                        VMPFenceNotifications.showError('Failed to whitelist file. Please try again.', 6000);
                    }
                });
            });
        },

        ignoreThreatFile: function(fileHash) {
            var self = this;
            
            VMPFenceNotifications.showConfirmModal({
                title: 'Mark as Fixed',
                message: 'Mark this file as fixed/ignored?<br><br>This will remove it from the threat list.',
                confirmText: 'Yes, Mark Fixed',
                cancelText: 'Cancel',
                type: 'info'
            }).then(function(confirmed) {
                if (!confirmed) return;
                
                $.ajax({
                    url: vmpfence_yara.ajax_url,
                    type: 'POST',
                    data: {
                        action: 'vmpfence_yara_mark_fixed',
                        nonce: vmpfence_yara.nonce,
                        file_hash: fileHash
                    },
                    success: function(response) {
                        if (response.success) {
                            VMPFenceNotifications.showSuccess('File marked as fixed', 4000);
                            // Refresh stats and close modal
                            self.updateStats();
                            $('#modal-overlay').fadeOut();
                        } else {
                            VMPFenceNotifications.showError('Error: ' + response.data.message, 6000);
                        }
                    },
                    error: function() {
                        VMPFenceNotifications.showError('Failed to mark file as fixed. Please try again.', 6000);
                    }
                });
            });
        },
        
        loadWhitelistedFiles: function() {
            var self = this;
            
            $('#whitelist-tbody').html('<tr><td colspan="5" class="no-results"><span class="spinner is-active"></span> Loading whitelisted files...</td></tr>');
            
            $.ajax({
                url: vmpfence_yara.ajax_url,
                type: 'POST',
                data: {
                    action: 'vmpfence_yara_get_whitelisted',
                    nonce: vmpfence_yara.nonce
                },
                success: function(response) {
                    if (response.success && response.data.whitelisted) {
                        var whitelisted = response.data.whitelisted;
                        var count = Object.keys(whitelisted).length;
                        
                        if (count === 0) {
                            $('#whitelist-tbody').html('<tr><td colspan="5" class="no-results">No whitelisted files found</td></tr>');
                            return;
                        }
                        
                        self.renderWhitelistedFiles(whitelisted);
                    } else {
                        $('#whitelist-tbody').html('<tr><td colspan="5" class="no-results">No whitelisted files found</td></tr>');
                    }
                },
                error: function() {
                    $('#whitelist-tbody').html('<tr><td colspan="5" class="no-results">Failed to load whitelisted files</td></tr>');
                }
            });
        },
        
        renderWhitelistedFiles: function(whitelisted) {
            var html = '';
            var count = 0;
            
            $.each(whitelisted, function(hash, file) {
                count++;
                var filePath = file.file_path || 'Unknown';
                var fileName = file.file_name || filePath.split('/').pop();
                var threatDesc = file.threat_description || 'N/A';
                var whitelistedDate = file.whitelisted_at ? new Date(file.whitelisted_at * 1000).toLocaleString() : 'N/A';
                var whitelistedBy = file.whitelisted_by || 'N/A';
                
                // Truncate long threat descriptions
                if (threatDesc.length > 100) {
                    threatDesc = threatDesc.substring(0, 100) + '...';
                }
                
                html += '<tr>';
                html += '<td title="' + filePath + '">' + fileName + '<br><small style="color: #666;">' + filePath + '</small></td>';
                html += '<td>' + threatDesc + '</td>';
                html += '<td>' + whitelistedDate + '</td>';
                html += '<td>User #' + whitelistedBy + '</td>';
                html += '<td>';
                html += '<button class="button button-small unwhitelist-file-btn" data-hash="' + hash + '" data-name="' + fileName + '">';
                html += '<span class="dashicons dashicons-dismiss"></span> Remove';
                html += '</button>';
                html += '</td>';
                html += '</tr>';
            });
            
            $('#whitelist-tbody').html(html);
        },
        
        unwhitelistFile: function(fileHash, fileName) {
            var self = this;
            
            VMPFenceNotifications.showConfirmModal({
                title: 'Remove from Whitelist',
                message: 'Remove "' + fileName + '" from whitelist?<br><br>This file will be scanned again in future scans.',
                confirmText: 'Yes, Remove',
                cancelText: 'Cancel',
                type: 'warning'
            }).then(function(confirmed) {
                if (!confirmed) return;
                
                $.ajax({
                    url: vmpfence_yara.ajax_url,
                    type: 'POST',
                    data: {
                        action: 'vmpfence_yara_unwhitelist_file',
                        nonce: vmpfence_yara.nonce,
                        file_hash: fileHash
                    },
                    success: function(response) {
                        if (response.success) {
                            VMPFenceNotifications.showSuccess('File removed from whitelist', 4000);
                            // Refresh whitelist table and stats
                            self.loadWhitelistedFiles();
                            self.updateStats();
                        } else {
                            VMPFenceNotifications.showError('Error: ' + response.data.message, 6000);
                        }
                    },
                    error: function() {
                        VMPFenceNotifications.showError('Failed to remove file from whitelist. Please try again.', 6000);
                    }
                });
            });
        },

        viewScanDetails: function(scanId) {
            // Legacy function - kept for compatibility
            var scan = this.scanHistory.find(function(s) {
                return s.session_id === scanId;
            });

            if (!scan) return;

            this.toggleSessionDetails(scanId);
        },

        filterHistory: function(filter) {
            // Implementation for filtering history
        },

        searchHistory: function(query) {
            // Implementation for searching history
        },

        showResults: function(results) {
            var html = '<div class="scan-results">';
            html += '<div class="result-header">';
            
            // Bug Fix UI: Display weighted threat score
            var threatScore = results.threat_score || 0;
            var confidence = results.confidence || 'safe';
            var recommendation = results.recommendation || 'safe';
            
            if (results.threats_found > 0 || threatScore > 0) {
                html += '<div class="threat-alert">';
                html += '<span class="dashicons dashicons-warning"></span>';
                html += '<h3>⚠️ Threats Detected</h3>';
                html += '<p>' + results.threats_found + ' malware signatures found</p>';
                
                // Display threat score with color coding
                html += '<div class="threat-score-display" style="margin-top: 15px; padding: 12px; background: rgba(255,255,255,0.1); border-radius: 6px;">';
                html += '<div style="display: flex; justify-content: space-between; align-items: center;">';
                html += '<div>';
                html += '<div style="font-size: 11px; text-transform: uppercase; letter-spacing: 1px; opacity: 0.8;">Threat Score</div>';
                html += '<div style="font-size: 32px; font-weight: bold; margin-top: 5px;">' + threatScore + '<span style="font-size: 18px; opacity: 0.7;">/100</span></div>';
                html += '<div style="margin-top: 5px; font-size: 13px;">';
                html += 'Confidence: <strong>' + confidence.toUpperCase() + '</strong>';
                html += '</div>';
                html += '</div>';
                
                // Progress bar visualization
                var scoreColor = threatScore >= 80 ? '#dc3545' : (threatScore >= 60 ? '#fd7e14' : (threatScore >= 30 ? '#ffc107' : '#28a745'));
                html += '<div style="flex: 1; max-width: 200px; margin-left: 20px;">';
                html += '<div style="background: rgba(255,255,255,0.2); border-radius: 10px; height: 20px; overflow: hidden;">';
                html += '<div style="background: ' + scoreColor + '; height: 100%; width: ' + threatScore + '%; transition: width 0.5s ease;"></div>';
                html += '</div>';
                html += '</div>';
                html += '</div>';
                html += '</div>';
                
                html += '</div>';
            } else {
                html += '<div class="clean-alert">';
                html += '<span class="dashicons dashicons-yes-alt"></span>';
                html += '<h3>✅ File is Clean</h3>';
                html += '<p>No threats detected</p>';
                
                // Show score even for clean files
                if (threatScore >= 0) {
                    html += '<div style="margin-top: 10px; padding: 8px; background: rgba(255,255,255,0.1); border-radius: 4px;">';
                    html += '<small>Threat Score: <strong>' + threatScore + '/100</strong> (Safe)</small>';
                    html += '</div>';
                }
                
                html += '</div>';
            }
            
            html += '</div>';

            // Show score breakdown if available
            if (results.score_breakdown) {
                html += '<div class="score-breakdown" style="margin: 20px 0; padding: 15px; background: #f8f9fa; border-radius: 8px; border-left: 4px solid #667eea;">';
                html += '<h4 style="margin: 0 0 12px 0; color: #333; font-size: 14px;">📊 Threat Score Breakdown</h4>';
                html += '<div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px;">';
                
                var breakdown = results.score_breakdown;
                if (breakdown.rule_weight !== undefined) {
                    html += '<div style="padding: 8px; background: white; border-radius: 4px;">';
                    html += '<div style="font-size: 11px; color: #666; text-transform: uppercase;">Rule Weight</div>';
                    html += '<div style="font-size: 18px; font-weight: bold; color: #333;">' + breakdown.rule_weight + ' pts</div>';
                    html += '</div>';
                }
                if (breakdown.file_characteristics !== undefined) {
                    html += '<div style="padding: 8px; background: white; border-radius: 4px;">';
                    html += '<div style="font-size: 11px; color: #666; text-transform: uppercase;">File Characteristics</div>';
                    html += '<div style="font-size: 18px; font-weight: bold; color: #333;">' + breakdown.file_characteristics + ' pts</div>';
                    html += '</div>';
                }
                if (breakdown.location_context !== undefined) {
                    html += '<div style="padding: 8px; background: white; border-radius: 4px;">';
                    html += '<div style="font-size: 11px; color: #666; text-transform: uppercase;">Location Context</div>';
                    html += '<div style="font-size: 18px; font-weight: bold; color: #333;">' + breakdown.location_context + ' pts</div>';
                    html += '</div>';
                }
                if (breakdown.checksum_penalty !== undefined) {
                    html += '<div style="padding: 8px; background: white; border-radius: 4px;">';
                    html += '<div style="font-size: 11px; color: #666; text-transform: uppercase;">Checksum Verification</div>';
                    html += '<div style="font-size: 18px; font-weight: bold; color: #333;">' + breakdown.checksum_penalty + ' pts</div>';
                    html += '</div>';
                }
                if (breakdown.combo_bonus && breakdown.combo_bonus > 0) {
                    html += '<div style="padding: 8px; background: white; border-radius: 4px; grid-column: span 2;">';
                    html += '<div style="font-size: 11px; color: #666; text-transform: uppercase;">⚡ Dangerous Combination Bonus</div>';
                    html += '<div style="font-size: 18px; font-weight: bold; color: #dc3545;">+' + breakdown.combo_bonus + ' pts</div>';
                    html += '</div>';
                }
                
                html += '</div>';
                html += '</div>';
            }
            
            // Show reasoning if available
            if (results.reasoning && results.reasoning.length > 0) {
                html += '<div class="score-reasoning" style="margin: 20px 0; padding: 15px; background: #fff3cd; border-radius: 8px; border-left: 4px solid #ffc107;">';
                html += '<h4 style="margin: 0 0 10px 0; color: #856404; font-size: 14px;">💡 Analysis Details</h4>';
                html += '<ul style="margin: 0; padding-left: 20px; color: #856404;">';
                $.each(results.reasoning, function(index, reason) {
                    html += '<li style="margin: 5px 0;">' + reason + '</li>';
                });
                html += '</ul>';
                html += '</div>';
            }

            if (results.matches && results.matches.length > 0) {
                html += '<div class="matches-list">';
                html += '<h4>Detected Malware Rules:</h4>';
                
                $.each(results.matches, function(index, match) {
                    html += '<div class="match-item">';
                    html += '<div class="match-header">';
                    html += '<strong>' + match.rule_name + '</strong>';
                    html += '<span class="severity-badge severity-' + match.severity + '">' + match.severity + '</span>';
                    html += '</div>';
                    html += '<p class="match-description">' + match.description + '</p>';
                    
                    if (match.category) {
                        html += '<p class="match-meta"><strong>Category:</strong> ' + match.category + '</p>';
                    }
                    
                    if (match.malware_family) {
                        html += '<p class="match-meta"><strong>Malware Family:</strong> ' + match.malware_family + '</p>';
                    }
                    
                    if (match.recommendation) {
                        html += '<p class="match-recommendation"><strong>Recommendation:</strong> ' + match.recommendation + '</p>';
                    }
                    
                    html += '</div>';
                });
                
                html += '</div>';
            }

            html += '<div class="scan-meta">';
            html += '<p><strong>File Hash:</strong> <code>' + results.file_hash + '</code></p>';
            if (results.elapsed_time) {
                html += '<p><strong>Total Elapsed:</strong> ' + results.elapsed_time + '</p>';
            }
            html += '<p><strong>Server Scan Time:</strong> ' + results.scan_time + '</p>';
            html += '<p><strong>Recommendation:</strong> ' + results.recommendation + '</p>';
            html += '</div>';

            html += '</div>';

            $('#modal-body').html(html);
            $('#results-modal').show();
        },

        showProgress: function(title, message) {
            $('#progress-title').text(title);
            $('#progress-message').text(message);
            $('#progress-bar').css('width', '0%');
            $('#progress-detail').text('0%');
            $('#progress-overlay').fadeIn(200);
        },

        updateProgress: function(percent, detail) {
            $('#progress-bar').css('width', percent + '%');
            $('#progress-detail').text(Math.round(percent) + '%');
            if (detail) {
                $('#progress-message').text(detail);
            }
        },

        hideProgress: function() {
            $('#progress-overlay').fadeOut(200);
        },

        downloadReport: function() {
            // Implementation for downloading scan report
            VMPFenceNotifications.showInfo('Download report feature coming soon', 4000);
        },

        formatFileSize: function(bytes) {
            if (bytes === 0) return '0 Bytes';
            var k = 1024;
            var sizes = ['Bytes', 'KB', 'MB', 'GB'];
            var i = Math.floor(Math.log(bytes) / Math.log(k));
            return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];
        },

        calculateHash: function(base64Content) {
            // Simple hash for demo - in production use proper hashing
            return 'sha256_' + base64Content.substring(0, 64);
        },
        
        /**
         * Fetch YARA rule counts from server
         */
        updateYARAServerStats: function() {
            var self = this;
            
            $.ajax({
                url: vmpfence_yara.ajax_url,
                type: 'POST',
                data: {
                    action: 'vmpfence_get_yara_server_stats',
                    nonce: vmpfence_yara.nonce
                },
                success: function(response) {
                    if (response.success && response.data) {
                        // Update rule count from server
                        var activeCount = response.data.active_count || 996;
                        $('#yara-rules-count').text(activeCount.toLocaleString());
                        
                        // Update tooltip with breakdown
                        if (response.data.total_count && response.data.total_count !== response.data.active_count) {
                            var inactive = response.data.total_count - response.data.active_count;
                            var tooltip = activeCount.toLocaleString() + ' active rules';
                            if (inactive > 0) {
                                tooltip += ' (' + inactive.toLocaleString() + ' inactive)';
                            }
                            if (response.data.current_version) {
                                tooltip += ' - Version: ' + response.data.current_version;
                            }
                            $('#yara-rules-stat').attr('title', tooltip);
                        }
                        
                        // Update progress message with actual count
                        $('#progress-message').text('Analyzing files with ' + activeCount.toLocaleString() + ' malware detection rules');
                    }
                },
                error: function() {
                    // Fallback to database count
                    $('#yara-rules-count').text('996');
                    // console.log('Could not fetch YARA server stats, using fallback value');
                }
            });
        },
        
        /**
         * Sync YARA rules from server (force refresh)
         */
        syncYARARules: function() {
            var self = this;
            var $btn = $('#sync-yara-rules-btn');
            
            // Disable button during sync
            $btn.prop('disabled', true);
            
            // Show info toast
            VMPFenceNotifications.showInfo('Syncing YARA rules from server...', 3000);
            
            $.ajax({
                url: vmpfence_yara.ajax_url,
                type: 'POST',
                data: {
                    action: 'vmpfence_get_yara_server_stats',
                    nonce: vmpfence_yara.nonce,
                    clear_cache: 'true'  // Force fresh data from server
                },
                success: function(response) {
                    if (response.success && response.data) {
                        var activeCount = response.data.active_count || 996;
                        $('#yara-rules-count').text(activeCount.toLocaleString());
                        
                        // Update tooltip with breakdown
                        if (response.data.total_count && response.data.total_count !== response.data.active_count) {
                            var inactive = response.data.total_count - response.data.active_count;
                            var tooltip = activeCount.toLocaleString() + ' active rules';
                            if (inactive > 0) {
                                tooltip += ' (' + inactive.toLocaleString() + ' inactive)';
                            }
                            if (response.data.current_version) {
                                tooltip += ' - Version: ' + response.data.current_version;
                            }
                            $('#yara-rules-stat').attr('title', tooltip);
                        }
                        
                        // Show success toast
                        VMPFenceNotifications.showSuccess('Synced successfully! <strong>' + activeCount.toLocaleString() + ' active rules</strong>', 4000);
                    } else {
                        VMPFenceNotifications.showError('Sync failed. Please try again.', 5000);
                    }
                },
                error: function() {
                    VMPFenceNotifications.showError('Connection error. Unable to sync YARA rules.', 5000);
                },
                complete: function() {
                    $btn.prop('disabled', false);
                }
            });
        },
        
        /**
         * Calculate optimal batch size based on file sizes (max 50MB per batch)
         */
        createSmartBatches: function(files) {
            var MAX_BATCH_SIZE = 50 * 1024 * 1024; // 50MB
            var batches = [];
            var currentBatch = [];
            var currentSize = 0;
            var self = this;
            
            // Defensive check: Ensure wpFileList is populated
            if (!self.wpFileList || self.wpFileList.length === 0) {
                console.error('wpFileList is not populated. Cannot create smart batches.');
                return [files]; // Fallback: return all files as single batch
            }
            
            files.forEach(function(filePath) {
                // Get file info from wpFileList
                var fileInfo = self.wpFileList.find(function(f) { return f.path === filePath; });
                if (!fileInfo) {
                    console.warn('File not found in wpFileList:', filePath);
                    return;
                }
                
                var estimatedBase64Size = Math.ceil(fileInfo.size * 1.37); // Base64 inflation ~37%
                
                // If single file > 50MB, skip it
                if (estimatedBase64Size > MAX_BATCH_SIZE) {
                    console.warn('File ' + fileInfo.name + ' exceeds 50MB (' + 
                        (estimatedBase64Size / 1024 / 1024).toFixed(2) + 'MB), skipping');
                    return;
                }
                
                // If adding this file exceeds limit, start new batch
                if (currentSize + estimatedBase64Size > MAX_BATCH_SIZE && currentBatch.length > 0) {
                    batches.push(currentBatch);
                    currentBatch = [];
                    currentSize = 0;
                }
                
                currentBatch.push(filePath);
                currentSize += estimatedBase64Size;
            });
            
            // Add remaining files
            if (currentBatch.length > 0) {
                batches.push(currentBatch);
            }
            
            return batches;
        },
        
        /**
         * Scan WordPress files in batch mode (optimized with integrity pre-filtering + smart batching)
         */
        scanWordPressFilesBatch: function() {
            if (this.selectedWPFiles.length === 0) return;

            var self = this;
            var totalFiles = this.selectedWPFiles.length;
            
            // Calculate total estimated scan time for all selected files
            var totalEstimatedTime = 0;
            self.selectedWPFiles.forEach(function(filePath) {
                var fileInfo = self.wpFileList.find(function(f) { return f.path === filePath; });
                if (fileInfo) {
                    totalEstimatedTime += self.estimateScanTime(fileInfo.size);
                }
            });
            
            // Generate unique scan session ID to group all batches
            var scanSessionId = 'scan_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
            // console.log('Starting new scan session:', scanSessionId);
            // console.log('Estimated total scan time:', self.formatTimeEstimate(totalEstimatedTime));
            
            // Initialize scan session
            self.isScanning = true;
            self.currentSessionBatches = [];
            self.currentScanSessionId = scanSessionId;
            self.scanStartTime = Date.now();
            self.estimatedTotalTime = totalEstimatedTime;
            $('#cancel-scan-btn').show();
            $('#scan-selected-btn').prop('disabled', true);
            
            // STAGE 0: Integrity Pre-Filter (NEW - filters out verified WP core/plugin/theme files)
            self.showProgress('Integrity Check', 'Verifying WordPress core and plugin files against official checksums...');
            
            var filesData = self.selectedWPFiles.map(function(path) {
                return { path: path };
            });
            
            $.ajax({
                url: vmpfence_yara.ajax_url,
                type: 'POST',
                data: {
                    action: 'vmpfence_integrity_pre_filter',
                    nonce: vmpfence_yara.nonce,
                    files: JSON.stringify(filesData)
                },
                success: function(response) {
                    // console.log('Integrity check response:', response);
                    
                    if (!response.success) {
                        self.hideProgress();
                        VMPFenceNotifications.showError('Integrity check failed: ' + (response.data.message || 'Unknown error'), 6000);
                        self.isScanning = false;
                        self.scanStartTime = null;
                        self.estimatedTotalTime = 0;
                        $('#cancel-scan-btn').hide();
                        $('#scan-selected-btn').prop('disabled', false);
                        return;
                    }
                    
                    var integrityResults = response.data;
                    
                    // Show integrity statistics
                    // console.log('Integrity filtering complete:', {
                    //     total: integrityResults.total_files,
                    //     trusted: integrityResults.trusted_count,
                    //     untrusted: integrityResults.untrusted_count,
                    //     reduction: integrityResults.reduction_percentage + '%'
                    // });
                    
                    self.showProgress(
                        'Integrity Check Complete',
                        'Verified: ' + integrityResults.trusted_count + ' files | ' +
                        'To Scan: ' + integrityResults.untrusted_count + ' files | ' +
                        'Reduction: ' + integrityResults.reduction_percentage.toFixed(1) + '%'
                    );
                    
                    // Store integrity results for final display
                    self.lastIntegrityResults = integrityResults;
                    
                    // If no files need scanning (all verified clean), show results immediately
                    if (integrityResults.untrusted_files.length === 0) {
                        // console.log('All files verified clean! No YARA scan needed.');
                        
                        // Calculate elapsed time for integrity check only
                        var elapsedTime = (Date.now() - self.scanStartTime) / 1000;
                        
                        self.displayCombinedResults(
                            { 
                                total_files: 0, 
                                total_threats: 0, 
                                high_severity: 0, 
                                critical_severity: 0 
                            },
                            integrityResults
                        );
                        self.isScanning = false;
                        self.scanStartTime = null; // Reset timer
                        self.estimatedTotalTime = 0;
                        $('#cancel-scan-btn').hide();
                        $('#scan-selected-btn').prop('disabled', false);
                        return;
                    }
                    
                    // STAGE 1: Create smart batches (only for untrusted files)
                    var filesToScan = integrityResults.untrusted_files.map(function(file) {
                        return file.path;
                    });
                    
                    var batches = self.createSmartBatches(filesToScan);
            
                    // Log batch information
                    // console.log('Smart batching: Created ' + batches.length + ' batches from ' + filesToScan.length + ' untrusted files');
                    batches.forEach(function(batch, index) {
                        var batchSize = 0;
                        batch.forEach(function(filePath) {
                            var fileInfo = self.wpFileList.find(function(f) { return f.path === filePath; });
                            if (fileInfo) batchSize += fileInfo.size;
                        });
                        // console.log('Batch ' + (index + 1) + ': ' + batch.length + ' files, ' + 
                        //     (batchSize / 1024 / 1024).toFixed(2) + 'MB');
                    });
                    
                    var totalBatches = batches.length;
                    var currentBatchIndex = 0;
                    var allResults = {
                        total_files: 0,
                        total_threats: 0,
                        high_severity: 0,
                        critical_severity: 0
                    };
                    
                    // Recalculate estimated time for only untrusted files
                    var untrustedEstimatedTime = 0;
                    filesToScan.forEach(function(filePath) {
                        var fileInfo = self.wpFileList.find(function(f) { return f.path === filePath; });
                        if (fileInfo) {
                            untrustedEstimatedTime += self.estimateScanTime(fileInfo.size);
                        }
                    });
                    self.estimatedTotalTime = untrustedEstimatedTime;

                    self.showProgress('Starting YARA Scan', 
                        'Scanning ' + filesToScan.length + ' untrusted files in ' + totalBatches + ' batch(es)... | Estimated: ' + self.formatTimeEstimate(untrustedEstimatedTime));

                    // Process batches sequentially
                    function processBatch(batchIndex) {
                        if (batchIndex >= totalBatches) {
                            // All batches complete - show combined integrity + YARA results
                            // console.log('All batches complete! Final results:', allResults);
                            self.displayCombinedResults(allResults, integrityResults);
                            return;
                        }
                
                var currentBatch = batches[batchIndex];
                var batchNum = batchIndex + 1;
                
                // Calculate elapsed and remaining time
                var elapsedTime = (Date.now() - self.scanStartTime) / 1000;
                var progressPercent = (batchIndex / totalBatches) * 100;
                var remainingTime = self.estimatedTotalTime - elapsedTime;
                if (remainingTime < 0) remainingTime = 0;
                
                var progressMessage = 'Batch ' + batchNum + ' of ' + totalBatches + ' (' + currentBatch.length + ' files) | ' +
                    'Elapsed: ' + self.formatTimeEstimate(elapsedTime) + ' | ' +
                    'ETA: ' + self.formatTimeEstimate(remainingTime);
                
                self.updateProgress(progressPercent, progressMessage);

                // Prepare files data for this batch
                var filesData = currentBatch.map(function(path) {
                    return { path: path };
                });

                // Log batch submission attempt
                // console.log('Submitting batch ' + batchNum + '/' + totalBatches + ' with ' + filesData.length + ' files');
                // console.log('Batch ' + batchNum + ' file list:', currentBatch.slice(0, 5)); // First 5 files
                
                // Submit this batch
                $.ajax({
                    url: vmpfence_yara.ajax_url,
                    type: 'POST',
                    data: {
                        action: 'vmpfence_yara_batch_scan',
                        nonce: vmpfence_yara.nonce,
                        files: JSON.stringify(filesData),
                        batch_number: batchNum,
                        total_batches: totalBatches,
                        scan_session_id: scanSessionId
                    },
                    success: function(response) {
                        // console.log('Batch ' + batchNum + ' submission response:', response);
                        
                        // Check if all files were verified (no YARA scan needed)
                        if (response.success && response.data && response.data.all_verified) {
                            // console.log('Batch ' + batchNum + ' - all files verified by integrity check');
                            // No threats found since all files were verified as trusted
                            var batchResults = {
                                total_files: response.data.verified_count || currentBatch.length,
                                total_threats: 0,
                                high_severity: 0,
                                critical_severity: 0
                            };
                            
                            // Accumulate results
                            allResults.total_files += batchResults.total_files;
                            allResults.total_threats += batchResults.total_threats;
                            allResults.high_severity += batchResults.high_severity;
                            allResults.critical_severity += batchResults.critical_severity;
                            
                            // Process next batch
                            // console.log('Proceeding to next batch: ' + (batchIndex + 1) + '/' + totalBatches);
                            processBatch(batchIndex + 1);
                            return;
                        }
                        
                        if (response.success && response.data && response.data.batch_id) {
                            var batchId = response.data.batch_id;
                            // console.log('Batch ' + batchNum + ' submitted successfully with ID:', batchId);
                            
                            // Track this batch for potential cancellation
                            self.activeBatchIds.push(batchId);
                            self.currentSessionBatches.push(batchId); // Add to session tracking
                            
                            // Poll for this batch's completion
                            self.pollBatchStatusSequential(batchId, currentBatch.length, batchNum, totalBatches, function(batchResults) {
                                // Remove from active batches when complete
                                var index = self.activeBatchIds.indexOf(batchId);
                                if (index > -1) {
                                    self.activeBatchIds.splice(index, 1);
                                }
                                
                                // Remove from session batches when complete
                                var sessionIndex = self.currentSessionBatches.indexOf(batchId);
                                if (sessionIndex > -1) {
                                    self.currentSessionBatches.splice(sessionIndex, 1);
                                }
                                
                                // Accumulate results
                                // console.log('Accumulating batch ' + batchNum + ' results:', batchResults);
                                allResults.total_files += batchResults.total_files || 0;
                                allResults.total_threats += batchResults.total_threats || 0;
                                allResults.high_severity += batchResults.high_severity || 0;
                                allResults.critical_severity += batchResults.critical_severity || 0;
                                // console.log('Total accumulated so far:', allResults);
                                
                                // Process next batch
                                // console.log('Proceeding to next batch: ' + (batchIndex + 1) + '/' + totalBatches);
                                processBatch(batchIndex + 1);
                            });
                        } else {
                            console.error('Batch ' + batchNum + ' submission failed:', response);
                            self.hideProgress();
                            var errorMsg = 'Failed to submit batch ' + batchNum;
                            if (response.data && response.data.message) {
                                errorMsg += ': ' + response.data.message;
                            }
                            VMPFenceNotifications.showError(errorMsg, 6000);
                        }
                    },
                    error: function(xhr, status, error) {
                        console.error('Batch ' + batchNum + ' AJAX error:', {
                            status: status,
                            error: error,
                            responseText: xhr.responseText,
                            statusCode: xhr.status
                        });
                        self.hideProgress();
                        VMPFenceNotifications.showError('Failed to submit batch ' + batchNum + ': ' + error + ' (HTTP ' + xhr.status + ')', 7000);
                    }
                });
            }
            
            // Start processing first batch
            processBatch(0);
                },
                error: function(xhr, status, error) {
                    console.error('Integrity check AJAX error:', {
                        status: status,
                        error: error,
                        responseText: xhr.responseText,
                        statusCode: xhr.status
                    });
                    self.hideProgress();
                    self.isScanning = false;
                    self.scanStartTime = null;
                    self.estimatedTotalTime = 0;
                    $('#cancel-scan-btn').hide();
                    $('#scan-selected-btn').prop('disabled', false);
                    VMPFenceNotifications.showError('Integrity check failed: ' + error + ' (HTTP ' + xhr.status + ')', 6000);
                }
            });
        },

        /**
         * Poll batch status for sequential batch processing
         */
        pollBatchStatusSequential: function(batchId, batchFileCount, batchNum, totalBatches, callback) {
            var self = this;
            var pollInterval = 2000; // 2 seconds
            var maxPolls = 300; // 10 minutes max
            var pollCount = 0;

            function checkStatus() {
                pollCount++;

                if (pollCount > maxPolls) {
                    self.scanStartTime = null;
                    self.estimatedTotalTime = 0;
                    self.hideProgress();
                    VMPFenceNotifications.showWarning('Batch ' + batchNum + ' timed out. Please check scan history.', 7000);
                    return;
                }

                $.ajax({
                    url: vmpfence_yara.ajax_url,
                    type: 'POST',
                    data: {
                        action: 'vmpfence_yara_batch_status',
                        nonce: vmpfence_yara.nonce,
                        batch_id: batchId
                    },
                    success: function(response) {
                        if (response.success && response.data) {
                            var status = response.data.status;
                            var progress = response.data.progress_percentage || 0;
                            var completed = response.data.completed_files || 0;
                            var totalFiles = response.data.total_files || batchFileCount;
                            var threats = response.data.total_threats_found || 0;
                            var cacheHitRate = response.data.cache_hit_rate || 0;

                            // Calculate overall progress across all batches
                            var batchProgress = ((batchNum - 1) / totalBatches) * 100 + (progress / totalBatches);
                            
                            // Calculate elapsed and remaining time
                            var elapsedTime = (Date.now() - self.scanStartTime) / 1000;
                            var remainingTime = self.estimatedTotalTime - elapsedTime;
                            if (remainingTime < 0) remainingTime = 0;
                            
                            // Show accurate file counts from backend
                            var message = 'Batch ' + batchNum + '/' + totalBatches + ': ' + completed + ' of ' + totalFiles + ' files (' + Math.round(progress) + '%) | ' +
                                'Elapsed: ' + self.formatTimeEstimate(elapsedTime) + ' | ETA: ' + self.formatTimeEstimate(remainingTime);
                            if (cacheHitRate > 0) {
                                message += ' | Cache: ' + Math.round(cacheHitRate) + '%';
                            }
                            if (threats > 0) {
                                message += ' | ⚠️ ' + threats + ' threats!';
                            }

                            self.updateProgress(batchProgress, message);

                            if (status === 'completed') {
                                // Fetch results for this batch
                                self.fetchBatchResultsSequential(batchId, callback);
                            } else if (status === 'queued') {
                                // Batch is queued - show queue information
                                var queuePosition = response.data.queue_position || 0;
                                var estimatedWait = response.data.estimated_wait_minutes || 0;
                                var activeScans = response.data.active_scans || 0;
                                
                                var queueMsg = 'Batch ' + batchNum + '/' + totalBatches + ' queued';
                                if (queuePosition > 0) {
                                    queueMsg += ' (position #' + queuePosition + ')';
                                }
                                if (estimatedWait > 0) {
                                    queueMsg += ' - ETA: ~' + estimatedWait + ' min';
                                }
                                if (activeScans >= 2) {
                                    queueMsg += ' | ⏳ High scan volume';
                                }
                                
                                self.updateProgress(batchProgress, queueMsg);
                                
                                // Continue polling - will transition to 'processing' when slot available
                                setTimeout(checkStatus, pollInterval);
                            } else if (status === 'failed' || status === 'cancelled') {
                                self.hideProgress();
                                VMPFenceNotifications.showError('Batch ' + batchNum + ' ' + status + '.', 5000);
                            } else {
                                // Continue polling for 'processing' and other statuses
                                setTimeout(checkStatus, pollInterval);
                            }
                        } else {
                            setTimeout(checkStatus, pollInterval);
                        }
                    },
                    error: function() {
                        setTimeout(checkStatus, pollInterval);
                    }
                });
            }

            checkStatus();
        },

        /**
         * Fetch batch results for sequential processing
         */
        fetchBatchResultsSequential: function(batchId, callback) {
            var self = this;

            $.ajax({
                url: vmpfence_yara.ajax_url,
                type: 'POST',
                data: {
                    action: 'vmpfence_yara_batch_results',
                    nonce: vmpfence_yara.nonce,
                    batch_id: batchId
                },
                success: function(response) {
                    if (response.success && response.data) {
                        // API returns data at top level, not nested under summary
                        var data = response.data;
                        
                        // Update stats incrementally
                        self.stats.totalScans += data.total_files || 0;
                        self.stats.threatsFound += data.total_threats_found || 0;
                        self.stats.cleanFiles += (data.total_files || 0) - (data.total_threats_found || 0);
                        self.updateStats();
                        
                        // Return data to callback
                        var batchResults = {
                            total_files: data.total_files || 0,
                            total_threats: data.total_threats_found || 0,
                            high_severity: data.high_severity_count || 0,
                            critical_severity: data.critical_severity_count || 0
                        };
                        // console.log('Batch results:', batchResults);
                        callback(batchResults);
                    } else {
                        callback({
                            total_files: 0,
                            total_threats: 0,
                            high_severity: 0,
                            critical_severity: 0
                        });
                    }
                },
                error: function() {
                    callback({
                        total_files: 0,
                        total_threats: 0,
                        high_severity: 0,
                        critical_severity: 0
                    });
                }
            });
        },

        /**
         * Cancel current scan session
         */
        cancelCurrentScan: function() {
            var self = this;
            
            if (!self.isScanning || self.currentSessionBatches.length === 0) {
                VMPFenceNotifications.showWarning('No active scan to cancel.', 4000);
                return;
            }
            
            VMPFenceNotifications.showConfirmModal({
                title: 'Cancel Scan',
                message: 'Are you sure you want to cancel the current scan?',
                confirmText: 'Yes, Cancel Scan',
                cancelText: 'No, Continue',
                type: 'warning'
            }).then(function(confirmed) {
                if (!confirmed) return;
                
                var totalBatches = self.currentSessionBatches.length;
                var cancelledCount = 0;
                
                self.updateProgress(0, 'Cancelling scan...');
                
                // Cancel all batches in current session
                self.currentSessionBatches.forEach(function(batchId) {
                    $.ajax({
                        url: vmpfence_yara.ajax_url,
                        type: 'POST',
                        data: {
                            action: 'vmpfence_yara_cancel_batch',
                            nonce: vmpfence_yara.nonce,
                            batch_id: batchId
                        },
                        success: function(response) {
                            cancelledCount++;
                            if (cancelledCount === totalBatches) {
                                // All batches cancelled
                                self.isScanning = false;
                                self.currentSessionBatches = [];
                                self.hideProgress();
                                $('#cancel-scan-btn').hide();
                                $('#scan-selected-btn').prop('disabled', false);
                                VMPFenceNotifications.showSuccess('Scan cancelled successfully.', 4000);
                            }
                        },
                        error: function() {
                            cancelledCount++;
                            if (cancelledCount === totalBatches) {
                                self.scanStartTime = null;
                                self.estimatedTotalTime = 0;
                                self.isScanning = false;
                                self.currentSessionBatches = [];
                                self.hideProgress();
                                $('#cancel-scan-btn').hide();
                                $('#scan-selected-btn').prop('disabled', false);
                            }
                        }
                    });
                });
            });
        },

        /**
         * Show summary after all batches complete
         */
        showBatchCompleteSummary: function(results) {
            var self = this;
            
            // Reset scanning state
            self.scanStartTime = null;
            self.estimatedTotalTime = 0;
            self.isScanning = false;
            self.currentSessionBatches = [];
            $('#cancel-scan-btn').hide();
            $('#scan-selected-btn').prop('disabled', false);
            
            // Use the accumulated results from this scan session
            var totalFilesScanned = results.total_files || 0;
            var totalThreats = results.total_threats || 0;
            var highSeverity = results.high_severity || 0;
            var criticalSeverity = results.critical_severity || 0;
            
            self.hideProgress();
            
            // Build HTML for modal
            var html = '<div class="scan-summary-complete">';
            html += '<div style="text-align: center; margin-bottom: 30px;">';
            
            if (totalThreats > 0) {
                html += '<div style="font-size: 64px; margin-bottom: 10px;">⚠️</div>';
                html += '<h2 style="color: #d32f2f; margin: 0;">Threats Detected!</h2>';
            } else {
                html += '<div style="font-size: 64px; margin-bottom: 10px;">✅</div>';
                html += '<h2 style="color: #4caf50; margin: 0;">All Clear!</h2>';
            }
            
            html += '</div>';
            
            html += '<div style="background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 20px;">';
            html += '<h3 style="margin-top: 0; color: #667eea;">Scan Summary</h3>';
            html += '<table style="width: 100%; border-collapse: collapse;">';
            html += '<tr style="border-bottom: 1px solid #ddd;"><td style="padding: 12px 0;"><strong>Total Files Scanned:</strong></td><td style="text-align: right; font-size: 18px; font-weight: 600;">' + totalFilesScanned + '</td></tr>';
            html += '<tr style="border-bottom: 1px solid #ddd;"><td style="padding: 12px 0;"><strong>Threats Found:</strong></td><td style="text-align: right; font-size: 18px; font-weight: 600; color: ' + (totalThreats > 0 ? '#d32f2f' : '#4caf50') + ';">' + totalThreats + '</td></tr>';
            html += '<tr style="border-bottom: 1px solid #ddd;"><td style="padding: 12px 0;"><strong>High Severity:</strong></td><td style="text-align: right; font-size: 18px; font-weight: 600; color: #ff9800;">' + highSeverity + '</td></tr>';
            html += '<tr><td style="padding: 12px 0;"><strong>Critical Severity:</strong></td><td style="text-align: right; font-size: 18px; font-weight: 600; color: #d32f2f;">' + criticalSeverity + '</td></tr>';
            html += '</table>';
            html += '</div>';
            
            if (totalThreats > 0) {
                html += '<div style="background: #fff3cd; border-left: 4px solid #ff9800; padding: 15px; border-radius: 4px; margin-bottom: 20px;">';
                html += '<strong style="color: #856404;">⚠️ Action Required</strong>';
                html += '<p style="margin: 10px 0 0 0; color: #856404;">Threats were detected in the scanned files. Please check the <strong>Scan History</strong> tab for detailed information about each threat and recommended actions.</p>';
                html += '</div>';
            } else {
                html += '<div style="background: #d4edda; border-left: 4px solid #4caf50; padding: 15px; border-radius: 4px; margin-bottom: 20px;">';
                html += '<strong style="color: #155724;">✓ No Threats Found</strong>';
                html += '<p style="margin: 10px 0 0 0; color: #155724;">All scanned files are clean. No malware or suspicious code patterns were detected.</p>';
                html += '</div>';
            }
            
            html += '</div>';
            
            // Show in modal
            $('#modal-body').html(html);
            $('#results-modal').fadeIn(300);
            
            // Refresh history and clear selection
            self.loadHistory();
            $('.file-checkbox').prop('checked', false);
            $('#select-all-files').prop('checked', false);
            self.updateSelectedFiles();
        },

        /**
         * Display combined integrity check + YARA scan results
         * Shows verified clean files, integrity issues, and YARA threats
         * 
         * @param {Object} yaraResults - Results from YARA scan (total_files, total_threats, high_severity, critical_severity)
         * @param {Object} integrityResults - Results from integrity check (trusted_files, untrusted_files, integrity_issues, reduction_percentage)
         */
        displayCombinedResults: function(yaraResults, integrityResults) {
            var self = this;
            
            // Calculate total elapsed time
            var totalElapsedTime = 0;
            if (self.scanStartTime) {
                totalElapsedTime = (Date.now() - self.scanStartTime) / 1000;
            }
            
            // Reset scanning state
            self.isScanning = false;
            self.currentSessionBatches = [];
            self.scanStartTime = null; // Reset timer for next scan
            self.estimatedTotalTime = 0; // Reset estimate
            $('#cancel-scan-btn').hide();
            $('#scan-selected-btn').prop('disabled', false);
            
            self.hideProgress();
            
            // Calculate totals
            var totalFilesChecked = integrityResults.total_files || 0;
            var trustedFiles = integrityResults.trusted_count || 0;
            var integrityIssues = integrityResults.integrity_issues.length || 0;
            var yaraScanned = yaraResults.total_files || 0;
            var yaraThreats = yaraResults.total_threats || 0;
            var highSeverity = yaraResults.high_severity || 0;
            var criticalSeverity = yaraResults.critical_severity || 0;
            var reductionPercentage = integrityResults.reduction_percentage || 0;
            
            // Build HTML for modal
            var html = '<div class="integrity-yara-results">';
            
            // Header with status icon
            html += '<div style="text-align: center; margin-bottom: 30px;">';
            if (yaraThreats > 0) {
                html += '<div style="font-size: 64px; margin-bottom: 10px;">⚠️</div>';
                html += '<h2 style="color: #d32f2f; margin: 0;">Threats Detected!</h2>';
            } else if (integrityIssues > 0) {
                html += '<div style="font-size: 64px; margin-bottom: 10px;">⚠️</div>';
                html += '<h2 style="color: #ff9800; margin: 0;">Modified Files Detected</h2>';
            } else {
                html += '<div style="font-size: 64px; margin-bottom: 10px;">✅</div>';
                html += '<h2 style="color: #4caf50; margin: 0;">All Files Verified Clean!</h2>';
            }
            html += '</div>';
            
            // Stats Grid
            html += '<div class="stats-grid" style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px; margin-bottom: 25px;">';
            
            // Verified Clean
            html += '<div class="stat-box" style="background: linear-gradient(135deg, #4caf50 0%, #66bb6a 100%); color: white; padding: 20px; border-radius: 12px; text-align: center; box-shadow: 0 4px 6px rgba(0,0,0,0.1);">';
            html += '<div style="font-size: 32px; font-weight: 700; margin-bottom: 5px;">' + trustedFiles + '</div>';
            html += '<div style="font-size: 14px; opacity: 0.9;">Verified Clean</div>';
            html += '<div style="font-size: 11px; margin-top: 5px; opacity: 0.7;">Official WordPress.org files</div>';
            html += '</div>';
            
            // Modified Files
            html += '<div class="stat-box" style="background: linear-gradient(135deg, #ff9800 0%, #ffa726 100%); color: white; padding: 20px; border-radius: 12px; text-align: center; box-shadow: 0 4px 6px rgba(0,0,0,0.1);">';
            html += '<div style="font-size: 32px; font-weight: 700; margin-bottom: 5px;">' + integrityIssues + '</div>';
            html += '<div style="font-size: 14px; opacity: 0.9;">Modified Files</div>';
            html += '<div style="font-size: 11px; margin-top: 5px; opacity: 0.7;">Hash mismatch detected</div>';
            html += '</div>';
            
            // Threats Found
            var threatColor = yaraThreats > 0 ? '#d32f2f' : '#4caf50';
            html += '<div class="stat-box" style="background: linear-gradient(135deg, ' + threatColor + ' 0%, ' + (yaraThreats > 0 ? '#e53935' : '#66bb6a') + ' 100%); color: white; padding: 20px; border-radius: 12px; text-align: center; box-shadow: 0 4px 6px rgba(0,0,0,0.1);">';
            html += '<div style="font-size: 32px; font-weight: 700; margin-bottom: 5px;">' + yaraThreats + '</div>';
            html += '<div style="font-size: 14px; opacity: 0.9;">Threats Found</div>';
            html += '<div style="font-size: 11px; margin-top: 5px; opacity: 0.7;">YARA malware signatures</div>';
            html += '</div>';
            
            html += '</div>';
            
            // Scan Details Table
            html += '<div style="background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 20px;">';
            html += '<h3 style="margin-top: 0; color: #667eea; display: flex; align-items: center; gap: 8px;"><span style="font-size: 20px;">📊</span> Scan Details</h3>';
            html += '<table style="width: 100%; border-collapse: collapse;">';
            html += '<tr style="border-bottom: 1px solid #ddd;"><td style="padding: 12px 0;"><strong>Total Files Checked:</strong></td><td style="text-align: right; font-size: 16px;">' + totalFilesChecked + '</td></tr>';
            html += '<tr style="border-bottom: 1px solid #ddd;"><td style="padding: 12px 0;"><strong>Files Verified (Skipped YARA):</strong></td><td style="text-align: right; font-size: 16px; color: #4caf50;">' + trustedFiles + ' (' + reductionPercentage.toFixed(1) + '%)</td></tr>';
            html += '<tr style="border-bottom: 1px solid #ddd;"><td style="padding: 12px 0;"><strong>Files Scanned by YARA:</strong></td><td style="text-align: right; font-size: 16px;">' + yaraScanned + '</td></tr>';
            html += '<tr style="border-bottom: 1px solid #ddd;"><td style="padding: 12px 0;"><strong>Integrity Issues:</strong></td><td style="text-align: right; font-size: 16px; color: ' + (integrityIssues > 0 ? '#ff9800' : '#4caf50') + ';">' + integrityIssues + '</td></tr>';
            html += '<tr style="border-bottom: 1px solid #ddd;"><td style="padding: 12px 0;"><strong>Malware Threats:</strong></td><td style="text-align: right; font-size: 16px; color: ' + (yaraThreats > 0 ? '#d32f2f' : '#4caf50') + ';">' + yaraThreats + '</td></tr>';
            
            if (yaraThreats > 0) {
                html += '<tr style="border-bottom: 1px solid #ddd;"><td style="padding: 12px 0; padding-left: 20px;">High Severity:</td><td style="text-align: right; font-size: 16px; color: #ff9800;">' + highSeverity + '</td></tr>';
                html += '<tr><td style="padding: 12px 0; padding-left: 20px;">Critical Severity:</td><td style="text-align: right; font-size: 16px; color: #d32f2f;">' + criticalSeverity + '</td></tr>';
            }
            
            html += '</table>';
            html += '</div>';
            
            // Performance Metrics
            html += '<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 15px 20px; border-radius: 8px; margin-bottom: 20px;">';
            html += '<strong style="font-size: 16px;">🚀 Performance Metrics</strong>';
            html += '<p style="margin: 10px 0 0 0; font-size: 14px; opacity: 0.95;">Integrity filtering reduced scans by <strong>' + reductionPercentage.toFixed(1) + '%</strong> by verifying ' + trustedFiles + ' files against official WordPress.org checksums.</p>';
            if (totalElapsedTime > 0) {
                html += '<p style="margin: 10px 0 0 0; font-size: 14px; opacity: 0.95;">Total scan time: <strong>' + self.formatTimeEstimate(totalElapsedTime) + '</strong></p>';
            }
            html += '</div>';
            
            // Modified Files Details Section
            if (integrityIssues > 0 && integrityResults.integrity_issues && integrityResults.integrity_issues.length > 0) {
                // console.log('Displaying integrity issues:', integrityResults.integrity_issues);
                
                html += '<div style="background: #fff; border: 1px solid #ff9800; border-radius: 8px; padding: 20px; margin-bottom: 20px;">';
                html += '<h3 style="margin-top: 0; color: #ff9800; display: flex; align-items: center; gap: 8px;"><span style="font-size: 20px;">⚠️</span> Modified Files (' + integrityIssues + ')</h3>';
                html += '<p style="color: #666; margin-bottom: 15px;">The following files have been modified from their official WordPress.org versions:</p>';
                html += '<div style="max-height: 300px; overflow-y: auto; border: 1px solid #e0e0e0; border-radius: 4px;">';
                html += '<table style="width: 100%; border-collapse: collapse; font-size: 13px;">';
                html += '<thead style="background: #f5f5f5; position: sticky; top: 0;">';
                html += '<tr>';
                html += '<th style="padding: 10px; text-align: left; border-bottom: 2px solid #ddd; font-weight: 600;">File Path</th>';
                html += '<th style="padding: 10px; text-align: center; border-bottom: 2px solid #ddd; font-weight: 600; width: 100px;">Status</th>';
                html += '<th style="padding: 10px; text-align: center; border-bottom: 2px solid #ddd; font-weight: 600; width: 80px;">Size</th>';
                html += '</tr>';
                html += '</thead>';
                html += '<tbody>';
                
                $.each(integrityResults.integrity_issues, function(index, issue) {
                    var statusBadge = 'Modified';
                    var statusColor = '#ff9800';
                    
                    // Status is always 'modified' since integrity_issues only contains hash mismatches
                    if (issue.type === 'hash_mismatch') {
                        statusBadge = 'Hash Mismatch';
                        statusColor = '#ff9800';
                    }
                    
                    // Get file size if available
                    var fileSize = 'N/A';
                    if (issue.path) {
                        // Try to find the file in our wpFileList to get the size
                        var fileInfo = self.wpFileList.find(function(f) { 
                            return f.path === issue.path || f.path === '/' + issue.path; 
                        });
                        if (fileInfo && fileInfo.size) {
                            fileSize = self.formatFileSize(fileInfo.size);
                        }
                    }
                    
                    html += '<tr style="border-bottom: 1px solid #f0f0f0;">';
                    html += '<td style="padding: 12px; font-family: monospace; font-size: 12px; word-break: break-all;">' + (issue.path || 'Unknown') + '</td>';
                    html += '<td style="padding: 12px; text-align: center;"><span style="background: ' + statusColor + '; color: white; padding: 4px 8px; border-radius: 4px; font-size: 11px; font-weight: 600;">' + statusBadge + '</span></td>';
                    html += '<td style="padding: 12px; text-align: center; color: #666;">' + fileSize + '</td>';
                    html += '</tr>';
                });
                
                html += '</tbody>';
                html += '</table>';
                html += '</div>';
                html += '<p style="margin: 15px 0 0 0; font-size: 12px; color: #666;"><strong>Note:</strong> Modified files may be legitimate customizations or could indicate unauthorized changes. Review each file carefully.</p>';
                html += '</div>';
            }
            
            // Action Required
            if (yaraThreats > 0) {
                html += '<div style="background: #fff3cd; border-left: 4px solid #d32f2f; padding: 15px; border-radius: 4px; margin-bottom: 20px;">';
                html += '<strong style="color: #721c24;">⚠️ Action Required - Threats Detected</strong>';
                html += '<p style="margin: 10px 0 0 0; color: #721c24;">YARA detected <strong>' + yaraThreats + ' threat(s)</strong> in scanned files. Check the <strong>Scan History</strong> tab for details and take immediate action.</p>';
                html += '</div>';
            } else if (integrityIssues > 0) {
                html += '<div style="background: #fff3cd; border-left: 4px solid #ff9800; padding: 15px; border-radius: 4px; margin-bottom: 20px;">';
                html += '<strong style="color: #856404;">⚠️ Modified Files Detected</strong>';
                html += '<p style="margin: 10px 0 0 0; color: #856404;"><strong>' + integrityIssues + ' file(s)</strong> have been modified from their official WordPress.org versions. While these may be legitimate customizations, review them carefully as they could indicate tampering.</p>';
                html += '</div>';
            } else {
                html += '<div style="background: #d4edda; border-left: 4px solid #4caf50; padding: 15px; border-radius: 4px; margin-bottom: 20px;">';
                html += '<strong style="color: #155724;">✓ All Files Verified Clean</strong>';
                html += '<p style="margin: 10px 0 0 0; color: #155724;">All <strong>' + totalFilesChecked + ' files</strong> match official WordPress.org checksums. No integrity issues or threats detected.</p>';
                html += '</div>';
            }
            
            html += '</div>';
            
            // Show in modal
            $('#modal-body').html(html);
            $('#results-modal').fadeIn(300);
            
            // Refresh history and clear selection
            self.loadHistory();
            $('.file-checkbox').prop('checked', false);
            $('#select-all-files').prop('checked', false);
            self.updateSelectedFiles();
        },

        /**
         * Poll batch scan status until completed (original single batch version)
         */
        pollBatchStatus: function(batchId, totalFiles) {
            var self = this;
            var pollInterval = 2000; // 2 seconds
            var maxPolls = 300; // 10 minutes max (300 * 2s)
            var pollCount = 0;

            function checkStatus() {
                pollCount++;

                if (pollCount > maxPolls) {
                    self.hideProgress();
                    VMPFenceNotifications.showWarning('Batch scan timed out. Please check scan history.', 7000);
                    return;
                }

                $.ajax({
                    url: vmpfence_yara.ajax_url,
                    type: 'POST',
                    data: {
                        action: 'vmpfence_yara_batch_status',
                        nonce: vmpfence_yara.nonce,
                        batch_id: batchId
                    },
                    success: function(response) {
                        if (response.success && response.data) {
                            var status = response.data.status;
                            var progress = response.data.progress_percentage || 0;
                            var completed = response.data.completed_files || 0;
                            var threats = response.data.total_threats_found || 0;
                            var cacheHitRate = response.data.cache_hit_rate || 0;

                            var message = 'Scanned ' + completed + ' of ' + totalFiles + ' files';
                            if (cacheHitRate > 0) {
                                message += ' (Cache: ' + cacheHitRate + '%)';
                            }
                            if (threats > 0) {
                                message += ' - ' + threats + ' threats found!';
                            }

                            self.updateProgress(progress, message);

                            if (status === 'completed' || status === 'failed') {
                                // Fetch final results
                                setTimeout(function() {
                                    self.fetchBatchResults(batchId);
                                }, 500);
                            } else if (status === 'cancelled') {
                                self.hideProgress();
                                VMPFenceNotifications.showInfo('Batch scan was cancelled.', 4000);
                            } else {
                                // Continue polling
                                setTimeout(checkStatus, pollInterval);
                            }
                        } else {
                            self.hideProgress();
                            VMPFenceNotifications.showError('Failed to get batch status: ' + (response.data ? response.data.message : 'Unknown error'), 6000);
                        }
                    },
                    error: function() {
                        // Retry on error
                        setTimeout(checkStatus, pollInterval);
                    }
                });
            }

            // Start polling
            checkStatus();
        },

        /**
         * Fetch and display batch results
         */
        fetchBatchResults: function(batchId) {
            var self = this;

            $.ajax({
                url: vmpfence_yara.ajax_url,
                type: 'POST',
                data: {
                    action: 'vmpfence_yara_batch_results',
                    nonce: vmpfence_yara.nonce,
                    batch_id: batchId
                },
                success: function(response) {
                    self.scanStartTime = null;
                    self.estimatedTotalTime = 0;
                    self.hideProgress();

                    if (response.success && response.data) {
                        var data = response.data;
                        var summary = data.summary || {};
                        var files = data.files || [];

                        // Update stats (use top-level fields, not summary)
                        self.stats.totalScans += data.total_files || 0;
                        self.stats.threatsFound += data.total_threats_found || 0;
                        self.stats.cleanFiles += (summary.safe || 0);
                        self.updateStats();

                        // Show summary alert
                        var message = '<strong>Batch Scan Complete!</strong><br><br>';
                        message += 'Files Scanned: <strong>' + (data.completed_files || 0) + '/' + (data.total_files || 0) + '</strong><br>';
                        message += 'Threats Found: <strong>' + (data.total_threats_found || 0) + '</strong><br>';
                        message += 'High Severity: <strong>' + (data.high_severity_count || 0) + '</strong><br>';
                        message += 'Critical Severity: <strong>' + (data.critical_severity_count || 0) + '</strong><br>';
                        message += 'Cache Hit Rate: <strong>' + (data.cache_hit_rate || 0) + '%</strong><br><br>';
                        message += 'Safe: ' + (summary.safe || 0) + '<br>';
                        message += 'Quarantine: ' + (summary.quarantine || 0) + '<br>';
                        message += 'Monitor: ' + (summary.monitor || 0) + '<br>';
                        message += 'Failed: ' + (data.failed_files || 0) + '<br>';

                        if (data.total_threats_found > 0) {
                            message += '<br>Check scan history for threat details.';
                        }

                        VMPFenceNotifications.showSuccess(message, 8000);

                        // Refresh history
                        self.loadHistory();

                        // Clear selection
                        $('.file-checkbox').prop('checked', false);
                        $('#select-all-files').prop('checked', false);
                        self.updateSelectedFiles();
                    } else {
                        VMPFenceNotifications.showError('Failed to fetch batch results: ' + (response.data ? response.data.message : 'Unknown error'), 6000);
                    }
                },
                error: function(xhr, status, error) {
                    self.hideProgress();
                    VMPFenceNotifications.showError('Failed to fetch batch results: ' + error, 6000);
                }
            });
        }
    };

    // Initialize when document is ready
    $(document).ready(function() {
        YaraScanner.init();
    });

    // Export for external access if needed
    window.YaraScanner = YaraScanner;

})(jQuery);
