<?php
/**
 * VMPFence Scan Options AJAX Handler
 * 
 */

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

class VMPFence_Scan_Options_Ajax {
    
    public function __construct() {
        add_action('wp_ajax_vmpfence_restore_defaults', array($this, 'restore_defaults'));
        add_action('wp_ajax_vmpfence_load_scan_type', array($this, 'load_scan_type'));
        add_action('wp_ajax_vmpfence_save_changes', array($this, 'save_changes'));
        add_action('wp_ajax_vmpfence_load_current_config', array($this, 'load_current_config'));
        add_action('wp_ajax_vmpfence_enable_scans', array($this, 'enable_scans'));
        
        // New scheduling AJAX handlers
        add_action('wp_ajax_vmpfence_preview_schedule', array($this, 'preview_schedule'));
        add_action('wp_ajax_vmpfence_update_schedule', array($this, 'update_schedule'));
        add_action('wp_ajax_vmpfence_get_schedule_status', array($this, 'get_schedule_status'));
        add_action('wp_ajax_vmpfence_preview_manual_pattern', array($this, 'preview_manual_pattern'));
        add_action('wp_ajax_vmpfence_get_pattern_description', array($this, 'get_pattern_description'));
        add_action('wp_ajax_vmpfence_get_current_schedule', array($this, 'get_current_schedule'));
    }
    
    /**
     * Restore defaults button functionality
     * Resets to default values with standard scan type
     */
    public function restore_defaults() {
        // Verify nonce
        if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'] ?? '')), 'vmpfence_scan_options')) {
            wp_die('Security check failed');
        }
        
        try {
            // Get standard scan type configuration
            $standard_config = VMPFence_Scan_Config::standardScanOptions();
            
            if (!$standard_config) {
                throw new Exception('Could not load standard configuration');
            }
            
            // Save standard scan type to database
            VMPFence_Config::set('scanType', 'standard');
            
            // Save all standard configuration options to database
            foreach ($standard_config as $option_name => $value) {
                if ($option_name !== 'scanType') { // Skip scanType as we already saved it
                    VMPFence_Config::set($option_name, $value);
                }
            }
            
            // Return the standard configuration for frontend
            wp_send_json_success(array(
                'config' => $standard_config,
                'scan_type' => 'standard',
                'message' => 'Defaults restored to Standard scan type'
            ));
            
        } catch (Exception $e) {
            wp_send_json_error(array(
                'message' => 'Error restoring defaults: ' . $e->getMessage()
            ));
        }
    }
    
    /**
     * Load scan type configuration
     * Returns configuration for selected scan type (limited, standard, high_sensitivity)
     */
    public function load_scan_type() {
        // Verify nonce
        if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'] ?? '')), 'vmpfence_scan_options')) {
            wp_die('Security check failed');
        }
        
        try {
            $scan_type = isset($_POST['scan_type']) ? sanitize_text_field(wp_unslash($_POST['scan_type'])) : '';
            
            // Validate scan type
            $valid_types = array('limited', 'standard', 'high_sensitivity');
            if (!in_array($scan_type, $valid_types)) {
                throw new Exception('Invalid scan type');
            }
            
            // Get scan type configuration using the correct method
            $config = VMPFence_Scan_Config::getScanOptions($scan_type);
            
            if (!$config) {
                throw new Exception('Could not load configuration for ' . $scan_type);
            }
            
            // DO NOT SAVE TO DATABASE - only return template for preview
            // Database save happens only when user clicks "Save Changes"
            
            wp_send_json_success(array(
                'config' => $config,
                'scan_type' => $scan_type,
                'message' => ucfirst(str_replace('_', ' ', $scan_type)) . ' configuration preview loaded'
            ));
            
        } catch (Exception $e) {
            wp_send_json_error(array(
                'message' => 'Error loading scan type: ' . $e->getMessage()
            ));
        }
    }
    
    /**
     * Save changes - save all form data to database
     */
    public function save_changes() {
        // Verify nonce
        if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'] ?? '')), 'vmpfence_scan_options')) {
            wp_die('Security check failed');
        }
        
        try {
            // Get form data from POST
            $form_data = isset($_POST['form_data']) ? map_deep(wp_unslash($_POST['form_data']), 'sanitize_text_field') : array();
            
            if (!is_array($form_data)) {
                throw new Exception('Invalid form data received');
            }
            
            // Debug: Log the form data being saved
            // error_log('VMPFence: Saving form data: ' . print_r($form_data, true));
            
            // Validate scan type
            $scan_type = sanitize_text_field($form_data['scanType']);
            $valid_scan_types = array('limited', 'standard', 'high_sensitivity', 'custom');
            if (!in_array($scan_type, $valid_scan_types)) {
                throw new Exception('Invalid scan type: ' . $scan_type);
            }
            
            // Validate schedule mode (updated field name)
            $schedule_mode = isset($form_data['schedule_mode']) ? sanitize_text_field($form_data['schedule_mode']) : 'auto';
            $valid_schedule_modes = array('auto', 'manual');
            if (!in_array($schedule_mode, $valid_schedule_modes)) {
                throw new Exception('Invalid schedule mode: ' . $schedule_mode);
            }
            
            // Save scan type first
            VMPFence_Config::set('scanType', $scan_type);
            
            // Save scheduling configuration using the helper method
            $this->save_scheduling_configuration($form_data);
            
            // error_log('VMPFence: Scheduling configuration saved');
            
            // Save all other options
            $saved_options = array('scanType', 'schedule_mode'); // Track what we've saved
            $performance_options = array(); // Track performance-specific options
            
            // Skip scheduling-specific fields as they're handled separately
            $scheduling_fields = array(
                'scheduledScansEnabled', 'schedule_mode', 'manual_schedule_pattern',
                'schedule_start_hour', 'schedule_timezone', 'random_offset', 'custom_schedule'
            );
            
            foreach ($form_data as $option_name => $value) {
                if (!in_array($option_name, $saved_options) && !in_array($option_name, $scheduling_fields)) {
                    // Sanitize based on expected data type and field name
                    if ($option_name === 'scan_exclude' || $option_name === 'scan_include_extra') {
                        // For textarea fields that contain multiple lines, preserve newlines
                        $sanitized_value = sanitize_textarea_field($value);
                    } else if (is_numeric($value)) {
                        $sanitized_value = intval($value);
                    } else if (is_string($value)) {
                        $sanitized_value = sanitize_text_field($value);
                    } else {
                        $sanitized_value = $value; // boolean/other types
                    }
                    
                    // Save to VMPFence_Config
                    VMPFence_Config::set($option_name, $sanitized_value);
                    
                    // Track performance-specific options for separate storage
                    $performance_keys = array(
                        'lowResourceScansEnabled', 'scan_maxIssues', 'scan_maxDuration', 
                        'maxMem', 'scan_maxExecTime', 'scan_max_resume_attempts'
                    );
                    if (in_array($option_name, $performance_keys)) {
                        $performance_options[$option_name] = $sanitized_value;
                    }
                    
                    $saved_options[] = $option_name;
                }
            }
            
            // Save performance options to separate option for Performance Manager compatibility
            if (!empty($performance_options)) {
                update_option('vmpfence_scan_options', $performance_options);
            }
            
            // Update schedule if scheduling is enabled
            if (isset($form_data['scheduledScansEnabled']) && $form_data['scheduledScansEnabled']) {
                try {
                    require_once VMPFENCE_PLUGIN_DIR . 'includes/class-scan-scheduler.php';
                    $scheduler = VMPFence_Scan_Scheduler::shared();
                    $scheduler->scheduleAllScans();
                } catch (Exception $e) {
                    // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Intentional logging for debugging
                    // error_log('VMPFence: Could not update schedule after save: ' . $e->getMessage());
                }
            }
            
            // Return success response
            wp_send_json_success(array(
                'message' => 'Settings saved successfully',
                'saved_options_count' => count($saved_options),
                'scan_type' => $scan_type,
                'schedule_mode' => $schedule_mode
            ));
            
        } catch (Exception $e) {
            wp_send_json_error(array(
                'message' => 'Error saving settings: ' . $e->getMessage()
            ));
        }
    }
    
    /**
     * Load current saved configuration on page load
     */
    public function load_current_config() {
        // Verify nonce
        if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'] ?? '')), 'vmpfence_scan_options')) {
            wp_die('Security check failed');
        }
        
        try {
            // Get current saved scan type (default to 'standard' if not set)
            $current_scan_type = VMPFence_Config::get('scanType', 'standard');
            // error_log('VMPFence: Current scan type from database: ' . $current_scan_type);
            
            // Check what manualScanType is saved in database before any processing
            $saved_manual_scan_type = VMPFence_Config::get('manualScanType', 'NOT_SET');
            // error_log('VMPFence: manualScanType from database BEFORE processing: ' . $saved_manual_scan_type);
            
            // Get ALL saved configuration values from database, not template
            $scan_config = new VMPFence_Scan_Config();
            
            // Start with the scan type template as base
            $config = $scan_config->getScanOptions($current_scan_type);
            
            // Override template values with actual saved values from database
            foreach ($config as $option_name => $template_value) {
                // Get the actual saved value from database
                $saved_value = VMPFence_Config::get($option_name, $template_value);
                $config[$option_name] = $saved_value;
                
                if ($option_name === 'manualScanType') {
                    // error_log('VMPFence: manualScanType - template: ' . $template_value . ', saved: ' . $saved_value . ', final: ' . $config[$option_name]);
                }
            }
            
            // Also get additional saved options that might not be in the template
            $custom_schedule = VMPFence_Config::get('scanSched', array());
            // error_log('VMPFence: Loading custom schedule from database: ' . print_r($custom_schedule, true));
            
            $additional_options = array(
                'scheduledScansEnabled' => VMPFence_Config::get('scheduledScansEnabled', 1),
                'schedMode' => VMPFence_Config::get('schedMode', 'auto'),
                'schedStartHour' => VMPFence_Config::get('schedStartHour', 2),
                'scheduleTimezone' => VMPFence_Config::get('scheduleTimezone', wp_timezone_string()),
                'randomOffset' => VMPFence_Config::get('randomOffset', '0'),
                'scanSched' => $custom_schedule
            );
            
            // Count checked hours in custom schedule for debugging
            $totalCheckedInDB = 0;
            if (!empty($custom_schedule) && is_array($custom_schedule)) {
                foreach ($custom_schedule as $day => $hours) {
                    if (is_array($hours)) {
                        foreach ($hours as $hour => $checked) {
                            if ($checked == 1) {
                                $totalCheckedInDB++;
                            }
                        }
                    }
                }
            }
            // error_log('VMPFence: Custom schedule loaded from DB has ' . $totalCheckedInDB . ' checked hours');
            
            // Only add manualScanType if it wasn't already set from the template processing
            if (!isset($config['manualScanType'])) {
                $additional_options['manualScanType'] = VMPFence_Config::get('manualScanType', 'once_daily');
                // error_log('VMPFence: manualScanType not in template, adding from additional_options: ' . $additional_options['manualScanType']);
            } else {
                // error_log('VMPFence: manualScanType already in config from template processing: ' . $config['manualScanType']);
            }
            
            // error_log('VMPFence: Additional options being added: ' . print_r($additional_options, true));
            
            // Check if manualScanType is being overwritten here
            if (isset($config['manualScanType']) && isset($additional_options['manualScanType'])) {
                // error_log('VMPFence: POTENTIAL ISSUE - manualScanType exists in both config (' . $config['manualScanType'] . ') and additional_options (' . $additional_options['manualScanType'] . ')');
            }
            
            // Merge additional options with config
            $config = array_merge($config, $additional_options);
            
            // error_log('VMPFence: Final manualScanType after merge: ' . (isset($config['manualScanType']) ? $config['manualScanType'] : 'NOT_SET'));
            // error_log('VMPFence: Final config being returned: ' . print_r($config, true));
            
            // error_log('VMPFence: Loaded configuration: ' . print_r($config, true));
            
            wp_send_json_success(array(
                'config' => $config,
                'scan_type' => $current_scan_type,
                'message' => 'Current configuration loaded'
            ));
            
        } catch (Exception $e) {
            wp_send_json_error(array(
                'message' => 'Error loading current configuration: ' . $e->getMessage()
            ));
        }
    }
    
    /**
     * Enable automatic scans - called from main scan page
     */
    public function enable_scans() {
        // Verify nonce
        if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'] ?? '')), 'vmpfence_scan_nonce')) {
            wp_die('Security check failed');
        }
        
        try {
            // Enable scheduled scans
            VMPFence_Config::set('scheduledScansEnabled', 1);
            
            wp_send_json_success(array(
                'message' => 'Automatic scans enabled successfully'
            ));
            
        } catch (Exception $e) {
            wp_send_json_error(array(
                'message' => 'Error enabling scans: ' . $e->getMessage()
            ));
        }
    }

    /**
     * Preview schedule based on current configuration
     */
    public function preview_schedule() {
        // Verify nonce
        if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'] ?? '')), 'vmpfence_scan_options')) {
            wp_die('Security check failed');
        }
        
        try {
            // Get schedule data from request
            $schedule_data_raw = isset($_POST['schedule_data']) ? map_deep(wp_unslash($_POST['schedule_data']), 'sanitize_text_field') : array();
            
            // Handle both JSON string and array formats
            if (is_string($schedule_data_raw)) {
                $schedule_data = json_decode($schedule_data_raw, true);
                
                // Validate JSON decode
                if ($schedule_data === null && json_last_error() !== JSON_ERROR_NONE) {
                    throw new Exception('Invalid JSON in schedule_data: ' . json_last_error_msg());
                }
            } else if (is_array($schedule_data_raw)) {
                $schedule_data = $schedule_data_raw;
            } else {
                $schedule_data = array();
            }
            
            // Load scheduler class
            require_once VMPFENCE_PLUGIN_DIR . 'includes/class-scan-scheduler.php';
            $scheduler = VMPFence_Scan_Scheduler::shared();
            
            // DO NOT MODIFY DATABASE - Create temporary config for preview only
            $preview_config = array();
            
            // Get current values and apply preview values
            if (isset($schedule_data['mode'])) {
                $preview_config['schedMode'] = $schedule_data['mode'];
            } else {
                $preview_config['schedMode'] = VMPFence_Config::get('schedMode', 'auto');
            }
            
            if (isset($schedule_data['pattern'])) {
                $preview_config['manualScanType'] = $schedule_data['pattern'];
            } else {
                $preview_config['manualScanType'] = VMPFence_Config::get('manualScanType', 'once_daily');
            }
            
            if (isset($schedule_data['start_hour'])) {
                $preview_config['schedStartHour'] = (int) $schedule_data['start_hour'];
            } else {
                $preview_config['schedStartHour'] = VMPFence_Config::get('schedStartHour', 2);
            }
            
            if (isset($schedule_data['timezone'])) {
                $preview_config['scheduleTimezone'] = $schedule_data['timezone'];
            } else {
                $preview_config['scheduleTimezone'] = VMPFence_Config::get('scheduleTimezone', wp_timezone_string());
            }
            
            if (isset($schedule_data['random_offset'])) {
                // Debug the exact value received from JavaScript
                // error_log('VMPFence: Preview - random_offset raw value: ' . var_export($schedule_data['random_offset'], true) . ' (type: ' . gettype($schedule_data['random_offset']) . ')');
                
                // Proper boolean conversion for JavaScript boolean values
                $randomOffsetRaw = $schedule_data['random_offset'];
                if ($randomOffsetRaw === true || $randomOffsetRaw === 'true' || $randomOffsetRaw === 1 || $randomOffsetRaw === '1') {
                    $preview_config['randomOffset'] = true;
                } else {
                    $preview_config['randomOffset'] = false;
                }
                
                // error_log('VMPFence: Preview - randomOffset converted to: ' . ($preview_config['randomOffset'] ? 'true' : 'false'));
            } else {
                // Convert string '0'/'1' to proper boolean
                $randomOffsetValue = VMPFence_Config::get('randomOffset', '0');
                $preview_config['randomOffset'] = ($randomOffsetValue === '1' || $randomOffsetValue === 1 || $randomOffsetValue === true);
                // error_log('VMPFence: Preview - randomOffset from DB: ' . var_export($randomOffsetValue, true) . ' converted to: ' . ($preview_config['randomOffset'] ? 'true' : 'false'));
            }
            
            if (isset($schedule_data['custom_schedule'])) {
                $preview_config['scanSched'] = $schedule_data['custom_schedule'];
            } else {
                $preview_config['scanSched'] = VMPFence_Config::get('scanSched', array());
            }
            
            // Generate preview schedule 
            $upcoming_scans = array();
            if (isset($schedule_data['enabled']) && $schedule_data['enabled']) {
                // Check if this is a preview of current settings or proposed changes
                $isCurrentSettings = $this->isPreviewingCurrentSettings($schedule_data);
                
                if ($isCurrentSettings) {
                    // Show actual saved schedule from database
                    $upcoming_scans = $this->getActualSchedulePreview();
                } else {
                    // Generate temporary preview for proposed changes (including random offset if enabled)
                    $upcoming_scans = $this->generatePreviewSchedule($preview_config);
                }
            }
            
            $response_data = array(
                'upcoming_scans' => $upcoming_scans,
                'mode' => ucfirst(str_replace('_', ' ', $preview_config['schedMode'])),
                'next_scan' => !empty($upcoming_scans) ? $upcoming_scans[0] : null,
                'last_update' => gmdate('Y-m-d H:i:s')
            );
            
            wp_send_json_success($response_data);
            
        } catch (Exception $e) {
            wp_send_json_error(array(
                'message' => 'Error generating schedule preview: ' . $e->getMessage()
            ));
        }
    }

    /**
     * Get actual saved schedule from database (shows real times with random offset applied)
     */
    public function get_current_schedule() {
        // Verify nonce
        if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'] ?? '')), 'vmpfence_scan_options')) {
            wp_die('Security check failed');
        }
        
        try {
            $scheduled = VMPFence_Config::get('allScansScheduled', array());
            $upcoming_scans = array();
            $now = time();
            
            // Sort by timestamp
            ksort($scheduled);
            
            foreach ($scheduled as $timestamp) {
                if ($timestamp > $now) {
                    $upcoming_scans[] = array(
                        'timestamp' => $timestamp,
                        'formatted_time' => gmdate('Y-m-d H:i:s', (int)$timestamp),
                        'relative_time' => human_time_diff($now, (int)$timestamp)
                    );
                }
                
                // Limit to next 10 scans for display
                if (count($upcoming_scans) >= 10) {
                    break;
                }
            }
            
            $response_data = array(
                'upcoming_scans' => $upcoming_scans,
                'mode' => ucfirst(VMPFence_Config::get('schedMode', 'auto')),
                'next_scan' => !empty($upcoming_scans) ? $upcoming_scans[0] : null,
                'last_update' => gmdate('Y-m-d H:i:s'),
                'random_offset_enabled' => VMPFence_Config::get('randomOffset', false),
                'total_scheduled' => count($scheduled)
            );
            
            wp_send_json_success($response_data);
            
        } catch (Exception $e) {
            wp_send_json_error(array(
                'message' => 'Error getting current schedule: ' . $e->getMessage()
            ));
        }
    }

    /**
     * Update schedule configuration and regenerate
     */
    public function update_schedule() {
        // Verify nonce
        if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'] ?? '')), 'vmpfence_scan_options')) {
            wp_die('Security check failed');
        }
        
        try {
            // Get form data
            $form_data = isset($_POST['form_data']) ? map_deep(wp_unslash($_POST['form_data']), 'sanitize_text_field') : array();
            
            // Validate and save scheduling configuration
            $this->save_scheduling_configuration($form_data);
            
            // Load scheduler and regenerate schedule
            require_once VMPFENCE_PLUGIN_DIR . 'includes/class-scan-scheduler.php';
            $scheduler = VMPFence_Scan_Scheduler::shared();
            
            if (isset($form_data['scheduledScansEnabled']) && $form_data['scheduledScansEnabled']) {
                // Schedule scans
                $success = $scheduler->scheduleAllScans();
                if (!$success) {
                    throw new Exception('Failed to schedule scans');
                }
                $message = 'Schedule updated and scans scheduled successfully';
            } else {
                // Unschedule scans
                $scheduler->unscheduleAllScans();
                $message = 'Scans unscheduled successfully';
            }
            
            wp_send_json_success(array(
                'message' => $message
            ));
            
        } catch (Exception $e) {
            wp_send_json_error(array(
                'message' => 'Error updating schedule: ' . $e->getMessage()
            ));
        }
    }

    /**
     * Get current schedule status
     */
    public function get_schedule_status() {
        // Verify nonce
        if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'] ?? '')), 'vmpfence_scan_options')) {
            wp_die('Security check failed');
        }
        
        try {
            // Load scheduler class
            require_once VMPFENCE_PLUGIN_DIR . 'includes/class-scan-scheduler.php';
            $scheduler = VMPFence_Scan_Scheduler::shared();
            
            $next_scan_time = $scheduler->nextScheduledScanTime();
            $upcoming_scans = $scheduler->getScheduledScanTimes(5);
            $scheduling_mode = $scheduler->schedulingMode();
            $last_update = VMPFence_Config::get('lastScheduleUpdate', 0);
            
            // Format upcoming scans
            $formatted_scans = array();
            foreach ($upcoming_scans as $timestamp) {
                $formatted_scans[] = array(
                    'timestamp' => $timestamp,
                    'formatted_time' => gmdate('Y-m-d H:i:s', (int)$timestamp),
                    'relative_time' => human_time_diff(time(), (int)$timestamp)
                );
            }
            
            $response_data = array(
                'next_scan' => $next_scan_time ? array(
                    'timestamp' => $next_scan_time,
                    'formatted_time' => gmdate('Y-m-d H:i:s', (int)$next_scan_time),
                    'relative_time' => human_time_diff(time(), (int)$next_scan_time)
                ) : null,
                'upcoming_scans' => $formatted_scans,
                'mode' => ucfirst(str_replace('_', ' ', $scheduling_mode)),
                'last_update' => $last_update ? gmdate('Y-m-d H:i:s', (int)$last_update) : 'Never',
                'total_scheduled' => count($upcoming_scans)
            );
            
            wp_send_json_success($response_data);
            
        } catch (Exception $e) {
            wp_send_json_error(array(
                'message' => 'Error getting schedule status: ' . $e->getMessage()
            ));
        }
    }

    /**
     * Save scheduling configuration to database
     */
    private function save_scheduling_configuration($form_data) {
        // error_log('VMPFence: save_scheduling_configuration called with: ' . print_r($form_data, true));
        
        // Save basic scheduling options
        if (isset($form_data['scheduledScansEnabled'])) {
            $value = (bool) $form_data['scheduledScansEnabled'];
            VMPFence_Config::set('scheduledScansEnabled', $value);
            // error_log('VMPFence: Set scheduledScansEnabled to: ' . ($value ? 'true' : 'false'));
        }
        
        if (isset($form_data['schedule_mode'])) {
            $value = sanitize_text_field($form_data['schedule_mode']);
            VMPFence_Config::set('schedMode', $value);
            // error_log('VMPFence: Set schedMode to: ' . $value);
        }
        
        if (isset($form_data['manual_schedule_pattern'])) {
            $value = sanitize_text_field($form_data['manual_schedule_pattern']);
            VMPFence_Config::set('manualScanType', $value);
            // error_log('VMPFence: Set manualScanType to: ' . $value);
        }
        
        if (isset($form_data['schedule_start_hour'])) {
            $value = (int) $form_data['schedule_start_hour'];
            VMPFence_Config::set('schedStartHour', $value);
            // error_log('VMPFence: Set schedStartHour to: ' . $value);
        }
        
        if (isset($form_data['schedule_timezone'])) {
            $value = sanitize_text_field($form_data['schedule_timezone']);
            VMPFence_Config::set('scheduleTimezone', $value);
            // error_log('VMPFence: Set scheduleTimezone to: ' . $value);
        }
        
        if (isset($form_data['random_offset'])) {
            // Save as '1' or '0' string for reliable database storage
            $value = $form_data['random_offset'] ? '1' : '0';
            VMPFence_Config::set('randomOffset', $value);
            // error_log('VMPFence: Set randomOffset to: ' . $value . ' (was: ' . var_export($form_data['random_offset'], true) . ')');
        }
        
        // Save custom schedule grid if provided
        if (isset($form_data['custom_schedule']) && is_array($form_data['custom_schedule'])) {
            // error_log('VMPFence: Processing custom schedule data...');
            
            $totalCheckedHours = 0;
            $sanitized_schedule = array();
            
            for ($day = 0; $day < 7; $day++) {
                $sanitized_schedule[$day] = array();
                for ($hour = 0; $hour < 24; $hour++) {
                    $value = isset($form_data['custom_schedule'][$day][$hour]) ? 
                        (int) $form_data['custom_schedule'][$day][$hour] : 0;
                    $sanitized_schedule[$day][$hour] = $value;
                    
                    if ($value === 1) {
                        $totalCheckedHours++;
                        // Log first few checked hours for debugging
                        if ($totalCheckedHours <= 5) {
                            // error_log('VMPFence: Found checked hour at day ' . $day . ', hour ' . $hour);
                        }
                    }
                }
            }
            
            // error_log('VMPFence: Custom schedule processing complete. Total checked hours: ' . $totalCheckedHours);
            // error_log('VMPFence: Sample day 0 data: ' . print_r($sanitized_schedule[0], true));
            
            VMPFence_Config::set('scanSched', $sanitized_schedule);
            // error_log('VMPFence: Set scanSched to custom grid');
            
            // Verify the data was saved
            $saved_data = VMPFence_Config::get('scanSched', array());
            // error_log('VMPFence: Verification - retrieved scanSched: ' . print_r($saved_data, true));
        } else {
            // error_log('VMPFence: No custom_schedule data provided or not an array');
        }
        
        // error_log('VMPFence: Scheduling configuration save completed');
    }

    /**
     * Generate preview schedule without modifying database
     */
    private function generatePreviewSchedule($preview_config) {
        $upcoming_scans = array();
        $now = time();
        $timezone = isset($preview_config['scheduleTimezone']) ? $preview_config['scheduleTimezone'] : wp_timezone_string();
        
        // Get site timezone offset
        $originalTz = date_default_timezone_get();
        date_default_timezone_set($timezone);
        
        try {
            $mode = isset($preview_config['schedMode']) ? $preview_config['schedMode'] : 'auto';
            
            if ($mode === 'auto') {
                // Generate automatic schedule preview
                $upcoming_scans = $this->generateAutomaticPreview($preview_config);
            } else {
                // Generate manual schedule preview
                $upcoming_scans = $this->generateManualPreview($preview_config);
            }
            
        } finally {
            // Restore original timezone
            date_default_timezone_set($originalTz);
        }
        
        return $upcoming_scans;
    }

    /**
     * Generate automatic schedule preview
     * NOTE: Preview shows BASE TIMES ONLY - random offset is applied during save, not preview
     */
    private function generateAutomaticPreview($preview_config) {
        $upcoming_scans = array();
        $now = time();
        
        // Generate scans for next 5 days (for preview)
        for ($day = 1; $day <= 5; $day++) {
            $targetDate = $now + ($day * 86400);
            
            // Use a simple calculation for automatic mode preview
            $optimalHour = 2; // Default to 2 AM for automatic mode
            
            // DO NOT apply random offset during preview
            // Preview shows clean base times so users understand the pattern
            // Random offset is only applied when saving the actual schedule
            
            // Create timestamp for scan WITHOUT random offset
            $scanTime = mktime($optimalHour, 0, 0, gmdate('m', $targetDate), gmdate('d', $targetDate), gmdate('Y', $targetDate));
            
            if ($scanTime > time()) {
                $upcoming_scans[] = array(
                    'timestamp' => $scanTime,
                    'formatted_time' => gmdate('Y-m-d H:i:s', (int)$scanTime),
                    'relative_time' => human_time_diff(time(), (int)$scanTime)
                );
            }
        }
        
        return $upcoming_scans;
    }

    /**
     * Generate manual schedule preview
     */
    private function generateManualPreview($preview_config) {
        $upcoming_scans = array();
        $now = time();
        $pattern = isset($preview_config['manualScanType']) ? $preview_config['manualScanType'] : 'once_daily';
        $start_hour = isset($preview_config['schedStartHour']) ? (int) $preview_config['schedStartHour'] : 2;
        $random_offset_raw = isset($preview_config['randomOffset']) ? $preview_config['randomOffset'] : false;
        // Ensure proper boolean conversion for string values like '0' or '1'
        $random_offset = ($random_offset_raw === '1' || $random_offset_raw === 1 || $random_offset_raw === true);
        
        // error_log('VMPFence: generateManualPreview - randomOffset raw: ' . var_export($random_offset_raw, true) . ' final: ' . ($random_offset ? 'true' : 'false'));
        
        // Generate scans for next 14 days based on pattern (starting from today)
        for ($day = 0; $day < 14; $day++) {
            $targetDate = $now + ($day * 86400);
            $dayOfWeek = (int) gmdate('w', $targetDate); // 0 = Sunday, 6 = Saturday
            
            $shouldScan = false;
            $scansPerDay = 1;
            
            switch ($pattern) {
                case 'once_daily':
                    $shouldScan = true;
                    $scansPerDay = 1;
                    break;
                    
                case 'twice_daily':
                    $shouldScan = true;
                    $scansPerDay = 2;
                    break;
                    
                case 'every_other_day':
                    $shouldScan = ($day % 2 === 1);
                    $scansPerDay = 1;
                    break;
                    
                case 'weekdays':
                    $shouldScan = ($dayOfWeek >= 1 && $dayOfWeek <= 5); // Mon-Fri
                    $scansPerDay = 1;
                    break;
                    
                case 'weekends':
                    $shouldScan = ($dayOfWeek === 0 || $dayOfWeek === 6); // Sat-Sun
                    $scansPerDay = 1;
                    break;
                    
                case 'odd_days_weekends':
                    $shouldScan = ($dayOfWeek === 1 || $dayOfWeek === 3 || $dayOfWeek === 5 || $dayOfWeek === 0 || $dayOfWeek === 6); // Mon/Wed/Fri + Weekends
                    $scansPerDay = 1;
                    break;
                    
                case 'custom':
                    // Custom schedules show exact times from grid
                    $isToday = ($day === 0); // First iteration is today
                    $currentHour = (int) gmdate('H');
                    
                    if (isset($preview_config['scanSched'][$dayOfWeek])) {
                        $daySchedule = $preview_config['scanSched'][$dayOfWeek];
                        $hoursProcessed = 0;
                        foreach ($daySchedule as $hour => $enabled) {
                            $hoursProcessed++;
                            if ($enabled) {
                                // Skip past hours for today
                                if ($isToday && $hour <= $currentHour) {
                                    continue;
                                }
                                
                                $scanTime = mktime($hour, 0, 0, gmdate('m', $targetDate), gmdate('d', $targetDate), gmdate('Y', $targetDate));
                                
                                // Apply random offset if enabled
                                if ($random_offset) {
                                    $siteHash = crc32(get_site_url());
                                    $dayHash = crc32($day . $hour . $siteHash);
                                    $offset = abs($dayHash) % 3600; // 1 hour maximum
                                    $scanTime += $offset;
                                }
                                
                                if ($scanTime > time()) {
                                    $upcoming_scans[] = array(
                                        'timestamp' => $scanTime,
                                        'formatted_time' => gmdate('Y-m-d H:i:s', (int)$scanTime),
                                        'relative_time' => human_time_diff(time(), (int)$scanTime)
                                    );
                                }
                            }
                        }
                    }
                    continue 2; // Skip the rest of this loop iteration
            }
            
            if ($shouldScan) {
                for ($scanNum = 0; $scanNum < $scansPerDay; $scanNum++) {
                    $scanHour = $start_hour;
                    
                    // For twice daily, add 12 hours for second scan
                    if ($scansPerDay === 2 && $scanNum === 1) {
                        $scanHour = ($start_hour + 12) % 24;
                    }
                    
                    // Create base time
                    $scanTime = mktime($scanHour, 0, 0, gmdate('m', $targetDate), gmdate('d', $targetDate), gmdate('Y', $targetDate));
                    
                    // Apply random offset if enabled
                    if ($random_offset) {
                        $siteHash = crc32(get_site_url());
                        $dayHash = crc32($day . $scanNum . $siteHash);
                        $offset = abs($dayHash) % 3600; // 1 hour maximum
                        $scanTime += $offset;
                    }
                    
                    if ($scanTime > time()) {
                        $upcoming_scans[] = array(
                            'timestamp' => $scanTime,
                            'formatted_time' => gmdate('Y-m-d H:i:s', (int)$scanTime),
                            'relative_time' => human_time_diff(time(), (int)$scanTime)
                        );
                    }
                }
            }
        }
        
        // Debug: Log total scans generated before limiting
        // error_log('VMPFence: generateManualPreview - Total scans generated: ' . count($upcoming_scans));
        
        // Sort by timestamp and limit to 10 results
        usort($upcoming_scans, function($a, $b) {
            return $a['timestamp'] - $b['timestamp'];
        });
        
        return array_slice($upcoming_scans, 0, 10);
    }

    /**
     * Preview manual scheduling pattern
     */
    public function preview_manual_pattern() {
        // Verify nonce
        if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'] ?? '')), 'vmpfence_scan_options')) {
            wp_die('Security check failed');
        }

        try {
            // Load scheduler class
            require_once VMPFENCE_PLUGIN_DIR . 'includes/class-scan-scheduler.php';
            $scheduler = VMPFence_Scan_Scheduler::shared();

            // Get pattern and start hour from request
            $pattern = isset($_POST['pattern']) ? sanitize_text_field(wp_unslash($_POST['pattern'])) : null;
            $start_hour = isset($_POST['start_hour']) ? intval($_POST['start_hour']) : null;

            if (!$pattern) {
                throw new Exception('Pattern is required');
            }

            // Get preview of the manual schedule
            $preview = $scheduler->previewManualSchedule($pattern, $start_hour);
            $description = $scheduler->getManualPatternDescription($pattern);

            wp_send_json_success(array(
                'description' => $description,
                'preview' => $preview,
                'pattern' => $pattern
            ));

        } catch (Exception $e) {
            wp_send_json_error(array(
                'message' => 'Error previewing manual pattern: ' . $e->getMessage()
            ));
        }
    }

    /**
     * Get pattern description for manual scheduling
     */
    public function get_pattern_description() {
        // Verify nonce
        if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'] ?? '')), 'vmpfence_scan_options')) {
            wp_die('Security check failed');
        }

        try {
            // Load scheduler class
            require_once VMPFENCE_PLUGIN_DIR . 'includes/class-scan-scheduler.php';
            $scheduler = VMPFence_Scan_Scheduler::shared();

            // Get pattern from request
            $pattern = isset($_POST['pattern']) ? sanitize_text_field(wp_unslash($_POST['pattern'])) : null;
            $start_hour = isset($_POST['start_hour']) ? intval($_POST['start_hour']) : null;

            if (!$pattern) {
                throw new Exception('Pattern is required');
            }

            // Get description
            $description = $scheduler->getManualPatternDescription($pattern);

            wp_send_json_success(array(
                'description' => $description,
                'pattern' => $pattern
            ));

        } catch (Exception $e) {
            wp_send_json_error(array(
                'message' => 'Error getting pattern description: ' . $e->getMessage()
            ));
        }
    }

    /**
     * Check if the preview request is for current settings or proposed changes
     */
    private function isPreviewingCurrentSettings($schedule_data) {
        // Compare all relevant settings with current database values
        $currentMode = VMPFence_Config::get('schedMode', 'auto');
        $currentPattern = VMPFence_Config::get('manualScanType', 'once_daily');
        $currentStartHour = (int)VMPFence_Config::get('schedStartHour', 2);  // Cast to int for comparison
        $currentTimezone = VMPFence_Config::get('scheduleTimezone', wp_timezone_string());
        $currentRandomOffset = VMPFence_Config::get('randomOffset', false);
        $currentCustomSchedule = VMPFence_Config::get('scanSched', array());
        
        $proposedMode = isset($schedule_data['mode']) ? $schedule_data['mode'] : $currentMode;
        $proposedPattern = isset($schedule_data['pattern']) ? $schedule_data['pattern'] : $currentPattern;
        $proposedStartHour = isset($schedule_data['start_hour']) ? (int)$schedule_data['start_hour'] : $currentStartHour;
        $proposedTimezone = isset($schedule_data['timezone']) ? $schedule_data['timezone'] : $currentTimezone;
        $proposedRandomOffset = isset($schedule_data['random_offset']) ? (bool)$schedule_data['random_offset'] : $currentRandomOffset;
        $proposedCustomSchedule = isset($schedule_data['custom_schedule']) ? $schedule_data['custom_schedule'] : $currentCustomSchedule;
        
        // Return true if all settings match current database values
        return ($currentMode === $proposedMode &&
                $currentPattern === $proposedPattern &&
                $currentStartHour === $proposedStartHour &&
                $currentTimezone === $proposedTimezone &&
                $currentRandomOffset === $proposedRandomOffset &&
                $currentCustomSchedule === $proposedCustomSchedule);
    }

    /**
     * Get preview of actual saved schedule from database
     */
    private function getActualSchedulePreview() {
        $scheduled = VMPFence_Config::get('allScansScheduled', array());
        $upcoming_scans = array();
        $now = time();
        
        foreach ($scheduled as $timestamp) {
            if ($timestamp > $now) {
                $upcoming_scans[] = array(
                    'timestamp' => $timestamp,
                    'formatted_time' => gmdate('Y-m-d H:i:s', (int)$timestamp),
                    'relative_time' => human_time_diff($now, (int)$timestamp)
                );
            }
        }
        
        // Sort by timestamp and limit to 10 results
        usort($upcoming_scans, function($a, $b) {
            return $a['timestamp'] - $b['timestamp'];
        });
        
        return array_slice($upcoming_scans, 0, 10);
    }
}

// Initialize AJAX handler
new VMPFence_Scan_Options_Ajax();
