/**
 * VMPFence Background Cache Processor
 * 
 * Automatically detects and caches missing plugin checksums in the background
 * with progress updates and non-blocking AJAX calls.
 * 
 * @package VMPFence
 * @since 2.1.0
 */

(function($) {
    'use strict';
    
    var VMPFenceCacheProcessor = {
        
        /**
         * Configuration
         */
        config: {
            batchSize: 5,                    // Process 5 plugins at a time
            ajaxTimeout: 30000,              // 30 second timeout per AJAX call
            retryAttempts: 3,                // Retry failed requests 3 times
            progressUpdateInterval: 100      // Update UI every 100ms
        },
        
        /**
         * State
         */
        state: {
            isProcessing: false,
            totalPlugins: 0,
            processedCount: 0,
            successCount: 0,
            failedCount: 0,
            currentBatch: [],
            missingPlugins: [],
            startTime: null,
            errors: []
        },
        
        /**
         * UI Elements (will be initialized)
         */
        ui: {
            progressContainer: null,
            progressBar: null,
            progressText: null,
            statusText: null
        },
        
        /**
         * Initialize the processor
         */
        init: function() {
            var self = this;
            
            // Don't run if already processing
            if (this.state.isProcessing) {
                return;
            }
            
            // Create UI elements
            this.createProgressUI();
            
            // Auto-detect on page load (with small delay to avoid blocking)
            setTimeout(function() {
                self.checkAndCacheMissing();
            }, 1000);
            
            // Bind manual trigger button if exists
            $(document).on('click', '#vmpfence-rebuild-cache', function(e) {
                e.preventDefault();
                self.manualRebuildCache();
            });
        },
        
        /**
         * Create progress UI elements
         */
        createProgressUI: function() {
            // Check if UI already exists
            if ($('#vmpfence-cache-progress').length > 0) {
                this.ui.progressContainer = $('#vmpfence-cache-progress');
                this.ui.progressBar = $('#vmpfence-cache-progress-bar');
                this.ui.progressText = $('#vmpfence-cache-progress-text');
                this.ui.statusText = $('#vmpfence-cache-status-text');
                return;
            }
            
            // Create new UI (will be injected into page by PHP)
            var html = '<div id="vmpfence-cache-progress" class="notice notice-info" style="display:none;">';
            html += '    <div style="padding: 12px 15px;">';
            html += '        <p id="vmpfence-cache-status-text" style="margin: 0 0 10px 0; font-weight: 600;">Building plugin checksum cache...</p>';
            html += '        <div style="background: #f0f0f1; border-radius: 4px; height: 24px; overflow: hidden; position: relative;">';
            html += '            <div id="vmpfence-cache-progress-bar" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); height: 100%; width: 0%; transition: width 0.3s ease;"></div>';
            html += '            <div id="vmpfence-cache-progress-text" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; display: flex; align-items: center; justify-content: center; color: #1d2327; font-size: 12px; font-weight: 600;">0%</div>';
            html += '        </div>';
            html += '    </div>';
            html += '</div>';
            
            // Insert after page title
            $('.wrap h1').first().after(html);
            
            this.ui.progressContainer = $('#vmpfence-cache-progress');
            this.ui.progressBar = $('#vmpfence-cache-progress-bar');
            this.ui.progressText = $('#vmpfence-cache-progress-text');
            this.ui.statusText = $('#vmpfence-cache-status-text');
        },
        
        /**
         * Show progress UI
         */
        showProgress: function() {
            if (this.ui.progressContainer) {
                this.ui.progressContainer.fadeIn(300);
            }
        },
        
        /**
         * Hide progress UI
         */
        hideProgress: function() {
            var self = this;
            if (this.ui.progressContainer) {
                setTimeout(function() {
                    self.ui.progressContainer.fadeOut(300);
                }, 2000);
            }
        },
        
        /**
         * Update progress UI
         */
        updateProgress: function(current, total, status) {
            if (!this.ui.progressBar || !this.ui.progressText || !this.ui.statusText) {
                return;
            }
            
            var percentage = total > 0 ? Math.round((current / total) * 100) : 0;
            
            this.ui.progressBar.css('width', percentage + '%');
            this.ui.progressText.text(percentage + '%');
            this.ui.statusText.text(status || 'Processing...');
        },
        
        /**
         * Check for missing plugins and cache them
         */
        checkAndCacheMissing: function() {
            var self = this;
            
            // Prevent multiple simultaneous runs
            if (this.state.isProcessing) {
                return;
            }
            
            this.state.isProcessing = true;
            this.state.startTime = Date.now();
            
            // Detect missing plugins
            $.ajax({
                url: vmpfence_yara.ajax_url,
                type: 'POST',
                data: {
                    action: 'vmpfence_detect_missing_plugins',
                    nonce: vmpfence_yara.nonce
                },
                timeout: this.config.ajaxTimeout,
                success: function(response) {
                    if (response.success && response.data) {
                        self.handleDetectionResult(response.data);
                    } else {
                        self.handleError('Detection failed: ' + (response.data?.message || 'Unknown error'));
                    }
                },
                error: function(xhr, status, error) {
                    self.handleError('Detection AJAX failed: ' + error);
                }
            });
        },
        
        /**
         * Handle detection result
         */
        handleDetectionResult: function(data) {
            var self = this;
            
            this.state.missingPlugins = data.missing_plugins || [];
            this.state.totalPlugins = this.state.missingPlugins.length;
            
            // If no missing plugins, we're done
            if (this.state.totalPlugins === 0) {
                // console.log('VMPFence: All plugins already cached (' + data.statistics.total_plugins + ' total)');
                this.state.isProcessing = false;
                return;
            }
            
            // Show progress
            this.showProgress();
            this.updateProgress(0, this.state.totalPlugins, 'Found ' + this.state.totalPlugins + ' plugins to cache...');
            
            // console.log('VMPFence: Starting cache process for ' + this.state.totalPlugins + ' plugins');
            
            // Start processing batches
            setTimeout(function() {
                self.processBatch(0);
            }, 500);
        },
        
        /**
         * Process a batch of plugins
         */
        processBatch: function(startIndex) {
            var self = this;
            
            // Check if we're done
            if (startIndex >= this.state.totalPlugins) {
                this.finishProcessing();
                return;
            }
            
            // Get next batch
            var endIndex = Math.min(startIndex + this.config.batchSize, this.state.totalPlugins);
            var batch = this.state.missingPlugins.slice(startIndex, endIndex);
            
            // Update UI
            this.updateProgress(
                startIndex,
                this.state.totalPlugins,
                'Caching plugins ' + (startIndex + 1) + '-' + endIndex + ' of ' + this.state.totalPlugins + '...'
            );
            
            // Process batch plugins sequentially (to avoid overwhelming server)
            this.processBatchPlugins(batch, 0, function() {
                // Move to next batch
                self.processBatch(endIndex);
            });
        },
        
        /**
         * Process plugins in a batch sequentially
         */
        processBatchPlugins: function(batch, index, callback) {
            var self = this;
            
            // Check if batch is complete
            if (index >= batch.length) {
                callback();
                return;
            }
            
            var plugin = batch[index];
            
            // Download checksums for this plugin
            $.ajax({
                url: vmpfence_yara.ajax_url,
                type: 'POST',
                data: {
                    action: 'vmpfence_download_plugin_checksum',
                    nonce: vmpfence_yara.nonce,
                    plugin_slug: plugin.slug,
                    plugin_version: plugin.version
                },
                timeout: this.config.ajaxTimeout,
                success: function(response) {
                    self.state.processedCount++;
                    
                    if (response.success) {
                        self.state.successCount++;
                        // console.log('VMPFence: Cached ' + plugin.name + ' (' + (response.data?.files_count || 0) + ' files)');
                    } else {
                        self.state.failedCount++;
                        self.state.errors.push({
                            plugin: plugin.name,
                            error: response.data?.message || 'Unknown error'
                        });
                        console.warn('VMPFence: Failed to cache ' + plugin.name + ': ' + (response.data?.message || 'Unknown error'));
                    }
                    
                    // Process next plugin in batch
                    self.processBatchPlugins(batch, index + 1, callback);
                },
                error: function(xhr, status, error) {
                    self.state.processedCount++;
                    self.state.failedCount++;
                    self.state.errors.push({
                        plugin: plugin.name,
                        error: 'AJAX failed: ' + error
                    });
                    console.error('VMPFence: AJAX error caching ' + plugin.name + ': ' + error);
                    
                    // Process next plugin in batch (continue even on error)
                    self.processBatchPlugins(batch, index + 1, callback);
                }
            });
        },
        
        /**
         * Finish processing
         */
        finishProcessing: function() {
            var self = this;
            var duration = ((Date.now() - this.state.startTime) / 1000).toFixed(1);
            
            // Update UI
            this.updateProgress(
                this.state.totalPlugins,
                this.state.totalPlugins,
                'Cache complete! ' + this.state.successCount + ' plugins cached in ' + duration + 's'
            );
            
            // console.log('VMPFence: Cache process complete - Success: ' + this.state.successCount + ', Failed: ' + this.state.failedCount + ', Duration: ' + duration + 's');
            
            // Log errors if any
            if (this.state.errors.length > 0) {
                console.warn('VMPFence: Encountered ' + this.state.errors.length + ' errors:', this.state.errors);
            }
            
            // Hide progress after delay
            this.hideProgress();
            
            // Reset state
            this.state.isProcessing = false;
            this.state.processedCount = 0;
            this.state.successCount = 0;
            this.state.failedCount = 0;
            this.state.errors = [];
        },
        
        /**
         * Handle errors
         */
        handleError: function(message) {
            console.error('VMPFence Cache Error: ' + message);
            
            if (this.ui.statusText) {
                this.ui.statusText.text('Error: ' + message);
            }
            
            this.state.isProcessing = false;
            
            // Hide progress after delay
            this.hideProgress();
        },
        
        /**
         * Manual cache rebuild (triggered by button)
         */
        manualRebuildCache: function() {
            
            // Reset state completely
            this.state.isProcessing = false;
            this.state.processedCount = 0;
            this.state.successCount = 0;
            this.state.failedCount = 0;
            this.state.errors = [];
            this.state.missingPlugins = [];
            
            // Start process
            this.checkAndCacheMissing();
        }
    };
    
    // Initialize when document is ready
    $(document).ready(function() {
        // Only run on YARA scanner page
        if ($('#vmpfence-yara-scanner').length > 0 || $('body').hasClass('vmpfence_page_vmpfence-yara-scanner')) {
            VMPFenceCacheProcessor.init();
        }
    });
    
    // Expose to global scope for debugging
    window.VMPFenceCacheProcessor = VMPFenceCacheProcessor;
    
})(jQuery);
