<?php
/**
 * WordPress Hooks Management Class
 *
 * @package VMPFence
 * @since 1.0.0
 * @since 2.2.5 -- Added Enhanced Audit Log integration for all hooks, and marked legacy audit log calls as deprecated and removed from this class.
 */

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

/**
 * VMPFence Hooks Class
 *
 * @since 1.0.0
 */
class VMPFence_Hooks {

    /**
     * Constructor
     *
     * @since 1.0.0
     */
    public function __construct() {
        // Initialize live traffic logging
        if (class_exists('VMPFence_Live_Traffic_Logger')) {
            VMPFence_Live_Traffic_Logger::getInstance()->initLogRequest();
        }
        
        $this->init_hooks();
    }

    /**
     * Initialize WordPress hooks
     *
     * @since 1.0.0
     * @return void
     */
    private function init_hooks() {
        // User hooks
        add_action('user_register', array($this, 'handle_user_registration'));
        add_action('wp_logout', array($this, 'handle_logout'));
        add_action('password_reset', array($this, 'handle_password_reset'), 10, 2);
        
        // Authentication hooks for Live Traffic
        add_action('wp_login', array($this, 'handle_login_success_live_traffic'), 10, 2);
        add_action('wp_login_failed', array($this, 'handle_login_failed_live_traffic'), 10, 1);
        add_action('lostpassword_post', array($this, 'handle_lost_password_live_traffic'), 10, 1);

        // Admin hooks
        add_action('wp_loaded', array($this, 'handle_wp_loaded'));
        add_action('init', array($this, 'handle_init'));
        add_action('template_redirect', array($this, 'handle_template_redirect'));

        // Plugin/theme hooks
        add_action('activated_plugin', array($this, 'handle_plugin_activation'));
        add_action('deactivated_plugin', array($this, 'handle_plugin_deactivation'));
        add_action('switch_theme', array($this, 'handle_theme_switch'));

        // Content hooks
        add_action('save_post', array($this, 'handle_post_save'), 10, 2);
        add_action('delete_post', array($this, 'handle_post_delete'));
        add_action('wp_insert_comment', array($this, 'handle_comment_insert'));

        // File system hooks
        add_action('wp_handle_upload', array($this, 'handle_file_upload'));

        // Core update hooks
        add_action('_core_updated_successfully', array($this, 'handle_core_update'));

        // Multisite hooks
        if (is_multisite()) {
            add_action('wpmu_new_blog', array($this, 'handle_new_site'), 10, 2);
            add_action('wp_delete_site', array($this, 'handle_delete_site'));
        }

        // XMLRPC hooks
        add_filter('xmlrpc_enabled', array($this, 'filter_xmlrpc_enabled'));
        add_action('xmlrpc_call', array($this, 'handle_xmlrpc_call'));

        // REST API hooks
        add_action('rest_api_init', array($this, 'handle_rest_api_init'));

        // Cron hooks
        add_action('wp_scheduled_delete', array($this, 'handle_scheduled_delete'));
        
        // VMPFence scheduled scanning hooks
        add_action(VMPFence_Constants::CRON_SCHEDULED_SCAN, array($this, 'handle_scheduled_scan'));
        add_action(VMPFence_Constants::CRON_SCHEDULE_GENERATOR, array($this, 'handle_schedule_generator'));
        add_action('vmpfence_monitor_fork_scan', array($this, 'handle_monitor_fork_scan'));
        add_filter('cron_schedules', array($this, 'add_custom_cron_intervals'));

        // Live traffic human cache cleanup
        add_action('vmpfence_cleanup_human_cache', array($this, 'handle_cleanup_human_cache'));

        // Frontend script enqueue
        add_action('wp_enqueue_scripts', array($this, 'enqueue_beacon_script'));

        // Error handling hooks
        add_action('wp_die_handler', array($this, 'handle_wp_die'));
    }

    /**
     * Handle user registration
     *
     * @since 1.0.0
     * @param int $user_id User ID
     * @return void
     */
    public function handle_user_registration($user_id) {
        $user = get_user_by('id', $user_id);
        // $ip = VMPFence_Utils::get_real_ip();
        // REMOVED: VMPFence_Audit_Log::log_event('user_registered') — now handled by Observer_User
        
        // Log to Live Traffic if admin user is created
        if ($user && user_can($user, 'manage_options')) {
            if (class_exists('VMPFence_Live_Traffic_Logger')) {
                $logger = VMPFence_Live_Traffic_Logger::getInstance();
                $logger->setAction('user:adminCreate', 'Administrator created: ' . $user->user_login, array(
                    'username' => $user->user_login,
                    'user_id' => $user_id,
                    'email' => $user->user_email,
                    'roles' => $user->roles
                ));
            }
        }
    }

    /**
     * Handle logout
     *
     * @since 1.0.0
     * @return void
     */
    public function handle_logout() {
        $user = wp_get_current_user();
        // $ip = VMPFence_Utils::get_real_ip();
        // REMOVED: VMPFence_Audit_Log::log_event('user_logout') — now handled by Observer_User
        
        // Log to Live Traffic
        if (class_exists('VMPFence_Live_Traffic_Logger')) {
            $logger = VMPFence_Live_Traffic_Logger::getInstance();
            $logger->setAction('logout', 'User logout: ' . $user->user_login, array(
                'username' => $user->user_login,
                'user_id' => $user->ID
            ));
        }
    }

    /**
     * Handle password reset
     *
     * @since 1.0.0
     * @param WP_User $user User object
     * @param string $new_pass New password
     * @return void
     */
    public function handle_password_reset($user, $new_pass) {
        // $ip = VMPFence_Utils::get_real_ip();
        // REMOVED: VMPFence_Audit_Log::log_event('password_reset') — now handled by Observer_User
        
        // Log to Live Traffic
        if (class_exists('VMPFence_Live_Traffic_Logger')) {
            $logger = VMPFence_Live_Traffic_Logger::getInstance();
            $logger->setAction('user:passwordReset', 'Password reset: ' . $user->user_login, array(
                'username' => $user->user_login,
                'user_id' => $user->ID
            ));
        }
    }

    /**
     * Handle successful login for Live Traffic
     *
     * @since 2.1.0
     * @param string $user_login Username
     * @param WP_User $user User object
     * @return void
     */
    public function handle_login_success_live_traffic($user_login, $user) {
        if (class_exists('VMPFence_Live_Traffic_Logger')) {
            $logger = VMPFence_Live_Traffic_Logger::getInstance();
            $logger->setAction('loginOK', 'Successful login: ' . $user_login, array(
                'username' => $user_login,
                'user_id' => $user->ID,
                'user_roles' => $user->roles
            ));
        }
    }
    
    /**
     * Handle failed login for Live Traffic
     *
     * @since 2.1.0
     * @param string $username Username or email
     * @return void
     */
    public function handle_login_failed_live_traffic($username) {
        if (class_exists('VMPFence_Live_Traffic_Logger')) {
            $logger = VMPFence_Live_Traffic_Logger::getInstance();
            
            // Check if username exists to differentiate action type
            $user = get_user_by('login', $username);
            if (!$user) {
                $user = get_user_by('email', $username);
            }
            
            if ($user) {
                $action = 'loginFailValidUsername';
                $description = 'Failed login attempt with valid username: ' . $username;
            } else {
                $action = 'loginFailInvalidUsername';
                $description = 'Failed login attempt with invalid username: ' . $username;
            }
            
            $logger->setAction($action, $description, array(
                'username' => $username
            ));
        }
    }
    
    /**
     * Handle lost password request for Live Traffic
     *
     * @since 2.1.0
     * @param WP_Error|WP_User $errors WP_Error object on error, WP_User on success
     * @return void
     */
    public function handle_lost_password_live_traffic($errors) {
        if (class_exists('VMPFence_Live_Traffic_Logger')) {
            $logger = VMPFence_Live_Traffic_Logger::getInstance();
            
            // Handle WP_Error (failed password reset)
            if (is_wp_error($errors)) {
                $logger->setAction('lostPasswordFailed', 'Password reset failed: ' . $errors->get_error_message(), array(
                    'error_code' => $errors->get_error_code()
                ));
            } 
            // Handle WP_User (successful password reset)
            elseif ($errors instanceof WP_User) {
                $logger->setAction('lostPassword', 'Password reset request: ' . $errors->user_login, array(
                    'username' => $errors->user_login
                ));
            }
        }
    }

    /**
     * Handle WordPress loaded
     *
     * @since 1.0.0
     * @return void
     */
    public function handle_wp_loaded() {
        // Check for security threats on every page load
        $this->perform_security_checks();
        
        // CRITICAL: Ensure scheduled scans are always active (Fix for recurring scans)
        $this->ensure_scheduled_scans_active();
    }

    /**
     * Handle init
     *
     * @since 1.0.0
     * @return void
     */
    public function handle_init() {
        // Traffic logging now handled by VMPFence_Live_Traffic_Logger singleton
        // Logger is initialized in constructor and uses shutdown hook
    }

    /**
     * Handle template redirect
     *
     * @since 1.0.0
     * @return void
     */
    public function handle_template_redirect() {
        // Track all requests with accurate hit type (happens AFTER WordPress routing)
        $this->track_request_for_rate_limiting();
        
        // Log 404 errors
        if (is_404()) {
            $this->handle_404_request();
        }
    }

    /**
     * Ensure scheduled scans are always active (CRITICAL FIX)
     * 
     * This method runs on every page load to ensure scheduled scans
     * continue working even if the cron events get cleared or expire.
     * Only checks once per hour to avoid performance impact.
     *
     * @since 1.0.0
     * @return void
     */
    private function ensure_scheduled_scans_active() {
        // Only check once per hour to avoid performance issues
        $lastUpdate = VMPFence_Config::get('lastScheduleUpdate', 0);
        $currentTime = time();
        
        // Check if we haven't validated schedules in the last hour
        if (($currentTime - $lastUpdate) < 3600) { // 1 hour
            return;
        }
        
        // Check if scheduled scans are enabled
        if (!VMPFence_Config::get('scheduledScansEnabled', true)) {
            return;
        }
        
        // Check if we have any future scheduled scans
        $nextScan = wp_next_scheduled('vmpfence_scheduled_scan');
        
        if (!$nextScan) {
            // No scheduled scans found - regenerate schedule
            require_once VMPFENCE_PLUGIN_DIR . 'includes/class-scan-scheduler.php';
            $scheduler = VMPFence_Scan_Scheduler::shared();
            
            if ($scheduler->scheduleAllScans()) {
                // error_log('VMPFence: Automatically regenerated missing scheduled scans');
                VMPFence_Config::set('lastScheduleUpdate', $currentTime);
             } // else {
            //     error_log('VMPFence: Failed to regenerate scheduled scans');
            // }
        }
    }

    /**
     * Handle plugin activation
     *
     * @since 1.0.0
     * @param string $plugin Plugin file
     * @return void
     */
    public function handle_plugin_activation($plugin) {
        // $user = wp_get_current_user();
        // REMOVED: VMPFence_Audit_Log::log_event('plugin_activated') — now handled by Observer_Site
    }

    /**
     * Handle plugin deactivation
     *
     * @since 1.0.0
     * @since 2.2.2 - Avoid logging if tables are being deleted on deactivation
     * @param string $plugin Plugin file
     * @return void
     */
    public function handle_plugin_deactivation($plugin) {
        // Check if tables will be deleted (to prevent audit log DB error)
        $enable_deactivation_choice = get_option('vmpfence_enable_deactivation_choice', 0);
        $will_delete_tables = false;
        if ($enable_deactivation_choice) {
            $data_action = get_transient('vmpfence_deactivation_data_action');
            $will_delete_tables = ($data_action === 'delete');
        }
        
        // REMOVED: VMPFence_Audit_Log::log_event('plugin_deactivated') — now handled by Observer_Site
        // Note: deactivation-aware table deletion check is preserved in plugin lifecycle
    }

    /**
     * Handle theme switch
     *
     * @since 1.0.0
     * @param string $new_name New theme name
     * @return void
     */
    public function handle_theme_switch($new_name) {
        // $user = wp_get_current_user();
        // REMOVED: VMPFence_Audit_Log::log_event('theme_changed') — now handled by Observer_Site
    }

    /**
     * Handle post save
     *
     * @since 1.0.0
     * @param int $post_id Post ID
     * @param WP_Post $post Post object
     * @return void
     */
    public function handle_post_save($post_id, $post) {
        if (wp_is_post_revision($post_id) || wp_is_post_autosave($post_id)) {
            return;
        }
        // REMOVED: VMPFence_Audit_Log::log_event('post_saved') — now handled by Observer_Content
    }

    /**
     * Handle post delete
     *
     * @since 1.0.0
     * @param int $post_id Post ID
     * @return void
     */
    public function handle_post_delete($post_id) {
        // $post = get_post($post_id);
        // $user = wp_get_current_user();
        // REMOVED: VMPFence_Audit_Log::log_event('post_deleted') — now handled by Observer_Content
    }

    /**
     * Handle comment insert
     *
     * @since 1.0.0
     * @param int $comment_id Comment ID
     * @return void
     */
    public function handle_comment_insert($comment_id) {
        // $comment = get_comment($comment_id);
        // $ip = VMPFence_Utils::get_real_ip();
        // REMOVED: VMPFence_Audit_Log::log_event('comment_posted') — now handled by Observer_Content
    }

    /**
     * Handle file upload
     *
     * @since 1.0.0
     * @param array $upload Upload information
     * @return array
     */
    public function handle_file_upload($upload) {
        // REMOVED: VMPFence_Audit_Log::log_event('file_uploaded') — now handled by Observer_Content
        return $upload;
    }

    /**
     * Handle core update
     *
     * @since 1.0.0
     * @param string $wp_version WordPress version
     * @return void
     */
    public function handle_core_update($wp_version) {
        // REMOVED: VMPFence_Audit_Log::log_event('core_updated') — now handled by Observer_Site
    }

    /**
     * Handle new site creation (multisite)
     *
     * @since 1.0.0
     * @param int $blog_id Blog ID
     * @param int $user_id User ID
     * @return void
     */
    public function handle_new_site($blog_id, $user_id) {
        // $user = get_user_by('id', $user_id); 
        // REMOVED: VMPFence_Audit_Log::log_event('site_created') — now handled by Observer_Multisite
    }

    /**
     * Handle site deletion (multisite)
     *
     * @since 1.0.0
     * @param WP_Site $site Site object
     * @return void
     */
    public function handle_delete_site($site) {
        // REMOVED: VMPFence_Audit_Log::log_event('site_deleted') — now handled by Observer_Multisite
    }

    /**
     * Filter XML-RPC enabled
     *
     * @since 1.0.0
     * @param bool $enabled Whether XML-RPC is enabled
     * @return bool
     */
    public function filter_xmlrpc_enabled($enabled) {
        if (!VMPFence_Config::get('xmlrpc_enabled', true)) {
            return false;
        }

        return $enabled;
    }

    /**
     * Handle XML-RPC call
     *
     * @since 1.0.0
     * @param string $name Method name
     * @return void
     */
    public function handle_xmlrpc_call($name) {
        $ip = VMPFence_Utils::get_real_ip();
        
        // DIRECT AUDIT LOG: Intentionally bypasses observer system.
        // Reason: Fires in xmlrpc_methods filter, early in request lifecycle before observers may be loaded.
        VMPFence_Audit_Log::log_event('xmlrpc_call', array(
            'method' => $name,
            'ip' => $ip,
            'timestamp' => time()
        ));
    }

    /**
     * Handle REST API init
     *
     * @since 1.0.0
     * @return void
     */
    public function handle_rest_api_init() {
        // Log REST API access if enabled
        if (VMPFence_Config::get('log_rest_api', false)) {
            $this->log_rest_api_access();
        }
    }

    /**
     * Handle scheduled delete
     *
     * @since 1.0.0
     * @return void
     */
    public function handle_scheduled_delete() {
        // This can be used for cleanup operations
        do_action('vmpfence_scheduled_cleanup');
    }

    /**
     * Handle wp_die
     *
     * @since 1.0.0
     * @param callable $handler Die handler
     * @return callable
     */
    public function handle_wp_die($handler) {
        // Log critical errors
        if (VMPFence_Config::get('log_wp_die', false)) {
            $this->log_wp_die();
        }

        return $handler;
    }

    /**
     * Perform security checks
     *
     * @since 1.0.0
     * @return void
     */
    private function perform_security_checks() {
        // Check for malicious requests
        $this->check_malicious_requests();

        // Check for suspicious user agents
        $this->check_suspicious_user_agents();

        // Check for known attack patterns
        $this->check_attack_patterns();
    }

    /**
     * Check for malicious requests
     *
     * @since 1.0.0
     * @return void
     */
    private function check_malicious_requests() {
        $request_uri = sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'] ?? ''));
        $query_string = sanitize_text_field(wp_unslash($_SERVER['QUERY_STRING'] ?? ''));

        // Check for SQL injection patterns
        $sql_patterns = array(
            '/union.*select/i',
            '/select.*from/i',
            '/insert.*into/i',
            '/delete.*from/i',
            '/update.*set/i'
        );

        foreach ($sql_patterns as $pattern) {
            if (preg_match($pattern, $request_uri) || preg_match($pattern, $query_string)) {
                $this->log_security_event('sql_injection_attempt', array(
                    'request_uri' => $request_uri,
                    'query_string' => $query_string,
                    'pattern' => $pattern
                ));
                break;
            }
        }
    }

    /**
     * Check for suspicious user agents
     *
     * @since 1.0.0
     * @return void
     */
    private function check_suspicious_user_agents() {
        $user_agent = sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'] ?? ''));

        $suspicious_agents = array(
            'sqlmap',
            'nikto',
            'nmap',
            'masscan',
            'zmap',
            'acunetix'
        );

        foreach ($suspicious_agents as $agent) {
            if (stripos($user_agent, $agent) !== false) {
                $this->log_security_event('suspicious_user_agent', array(
                    'user_agent' => $user_agent,
                    'detected_tool' => $agent
                ));
                break;
            }
        }
    }

    /**
     * Check for attack patterns
     *
     * @since 1.0.0
     * @return void
     */
    private function check_attack_patterns() {
        $request_uri = sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'] ?? ''));

        // Check for directory traversal
        if (preg_match('/\.\.[\/\\\\]/i', $request_uri)) {
            $this->log_security_event('directory_traversal_attempt', array(
                'request_uri' => $request_uri
            ));
        }

        // Check for file inclusion attempts
        if (preg_match('/(include|require).*\.(php|txt|log)/i', $request_uri)) {
            $this->log_security_event('file_inclusion_attempt', array(
                'request_uri' => $request_uri
            ));
        }
    }

    /**
     * Log security event (convenience method)
     *
     * @since 2.1.0
     * @param string $action Action type
     * @param array $data Event data
     * @return void
     */
    public function log_security_event_traffic($action, $data = array()) {
        if (class_exists('VMPFence_Live_Traffic_Logger')) {
            $description = '';
            if (isset($data['message'])) {
                $description = $data['message'];
            } elseif (isset($data['request_uri'])) {
                $description = 'Request to: ' . $data['request_uri'];
            }
            
            VMPFence_Live_Traffic_Logger::getInstance()->logSecurityEvent($action, $description, $data);
        }
    }

    /**
     * Track request for rate limiting with accurate hit type
     *
     * @since 2.0.0
     * @return void
     */
    private function track_request_for_rate_limiting() {
        // Only track if rate limiting is enabled
        if (!VMPFence_Config::get('rate_limiting_enabled')) {
            return;
        }

        $ip = VMPFence_Utils::get_real_ip();
        $request_uri = sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'] ?? ''));
        $user_agent = sanitize_text_field($_SERVER['HTTP_USER_AGENT'] ?? '');
        
        // Get rate limit controller
        $rate_controller = vmpfence_get_rate_limit_controller();
        
        if (!$rate_controller) {
            return;
        }

        // Determine hit type based on WordPress routing (accurate after template_redirect)
        $status_code = is_404() ? 404 : 200;
        
        // Build request data
        $request = array(
            'ip' => $ip,
            'uri' => $request_uri,
            'method' => sanitize_text_field($_SERVER['REQUEST_METHOD'] ?? 'GET'),
            'params' => array(),
            'user_agent' => $user_agent,
            'referer' => sanitize_text_field($_SERVER['HTTP_REFERER'] ?? ''),
            'status_code' => $status_code
        );
        
        // Check rate limits (this will track the request)
        $violation = $rate_controller->check_rate_limits($request);
        
        if ($violation && ($violation['action'] === 'block' || $violation['type'] === 'blocked')) {
            // IP has been blocked by rate limiter
            // wp_die( 
            //     esc_html__('Access blocked due to rate limit violation.', 'vmpfence-security'),
            //     esc_html__('Rate Limit Exceeded', 'vmpfence-security'),
            //     array('response' => 403)
            // );
            include VMPFENCE_PLUGIN_DIR . '/firewall/views/rate-limit-403-blocked.php';
            exit;
        }
    }

    /**
     * Handle 404 requests
     *
     * @since 1.0.0
     * @return void
     */
    private function handle_404_request() {
        $ip = VMPFence_Utils::get_real_ip();
        $request_uri = sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'] ?? ''));

        // Set status code in live traffic logger
        if (class_exists('VMPFence_Live_Traffic_Logger')) {
            VMPFence_Live_Traffic_Logger::getInstance()->setStatusCode(404);
        }

        // Just log the 404 - rate limiting is handled in track_request_for_rate_limiting()
        $this->log_security_event('404_error', array(
            'request_uri' => $request_uri,
            'ip' => $ip
        ));
    }

    /**
     * Log REST API access
     *
     * @since 1.0.0
     * @return void
     */
    private function log_rest_api_access() {
        $ip = VMPFence_Utils::get_real_ip();
        $request_uri = sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'] ?? ''));

        // DIRECT AUDIT LOG: Intentionally bypasses observer system.
        // Reason: Fires in rest_api_init, may be before observer registration.
        VMPFence_Audit_Log::log_event('rest_api_access', array(
            'ip' => $ip,
            'request_uri' => $request_uri,
            'timestamp' => time()
        ));
    }

    /**
     * Log wp_die events
     *
     * @since 1.0.0
     * @return void
     */
    private function log_wp_die() {
        $ip = VMPFence_Utils::get_real_ip();

        // DIRECT AUDIT LOG: Intentionally bypasses observer system.
        // Reason: Fires in wp_die_handler filter, critical error path.
        VMPFence_Audit_Log::log_event('wp_die_called', array(
            'ip' => $ip,
            'timestamp' => time()
        ));
    }

    /**
     * Log security event
     *
     * @since 1.0.0
     * @param string $event_type Event type
     * @param array $data Event data
     * @return void
     */
    private function log_security_event($event_type, $data) {
        // Route through Logging Service instead of raw $wpdb->insert()
        // This ensures security detection events go through the proper API-sync pipeline
        if (class_exists('VMPFence_Logging_Service')) {
            $instance = VMPFence_Logging_Service::get_instance();
            if ($instance) {
                $instance->log_event($event_type, 'warning', $data, 'detection');
                return;
            }
        }

        // Fallback: direct DB insert if Logging Service not available
        global $wpdb;

        $table_name = VMPFence_Constants::get_table_name(VMPFence_Constants::TABLE_EVENTS);
        $ip = VMPFence_Utils::get_real_ip();
        
        // Ensure table exists before inserting (self-healing for frontend hooks)
        if (class_exists('VMPFence_Database') && !VMPFence_Database::events_table_exists()) {
            VMPFence_Database::ensure_events_table_exists();
        }

        $wpdb->insert(
            $table_name,
            array(
                'time' => time(),
                'event_type' => $event_type,
                'severity' => VMPFence_Constants::SEVERITY_MEDIUM,
                'source_ip' => $ip,
                'user_id' => get_current_user_id(),
                'username' => wp_get_current_user()->user_login ?? '',
                'data' => maybe_serialize($data)
            ),
            array('%d', '%s', '%d', '%s', '%d', '%s', '%s')
        );
    }

    /**
     * Handle scheduled scan execution
     *
     * @since 1.0.0
     * @return void
     */
    public function handle_scheduled_scan() {
        if (class_exists('VMPFence_Scan_Scheduler')) {
            $scheduler = VMPFence_Scan_Scheduler::shared();
            $scheduler->executeScheduledScan();
        }
    }

    /**
     * Handle automatic schedule generation
     *
     * @since 1.0.0
     * @return void
     */
    public function handle_schedule_generator() {
        if (class_exists('VMPFence_Scan_Scheduler')) {
            $scheduler = VMPFence_Scan_Scheduler::shared();
            $scheduler->generateAndScheduleAutomaticScans();
        }
    }

    /**
     * Add custom cron intervals for VMPFence scheduling
     *
     * @since 1.0.0
     * @param array $schedules Existing cron schedules
     * @return array Modified schedules
     */
    public function add_custom_cron_intervals($schedules) {
        // Add 12-hour interval for twice daily scans
        $schedules['vmpfence_twice_daily'] = array(
            'interval' => 12 * HOUR_IN_SECONDS,
            'display' => __('VMPFence Twice Daily', 'vmpfence-security')
        );
        
        // Add every other day interval
        $schedules['vmpfence_every_other_day'] = array(
            'interval' => 2 * DAY_IN_SECONDS,
            'display' => __('VMPFence Every Other Day', 'vmpfence-security')
        );
        return $schedules;
    }

    /**
     * Handle monitor fork scan execution
     *
     * @since 1.0.0
     * @param string $scan_type Scan type to execute
     * @return void
     */
    public function handle_monitor_fork_scan($scan_type = 'standard') {
        // Load scheduler class if needed
        if (!class_exists('VMPFence_Scan_Scheduler')) {
            require_once VMPFENCE_PLUGIN_DIR . 'includes/class-scan-scheduler.php';
        }
        
        // Execute the forked scan
        VMPFence_Scan_Scheduler::handleMonitorForkScan($scan_type);
    }

    /**
     * Enqueue live traffic beacon script on frontend
     *
     * @since 2.1.0
     * @return void
     */
    public function enqueue_beacon_script() {
        // Don't enqueue in admin
        if (is_admin()) {
            return;
        }

        // Don't enqueue for crawlers (check user agent quickly)
        $ua = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
        if (preg_match('/(bot|crawler|spider|curl|wget)/i', $ua)) {
            return;
        }

        // Check if beacon is enabled
        $beacon_enabled = get_option('vmpfence_enable_beacon', 1);
        if (!$beacon_enabled) {
            return;
        }

        // Enqueue script
        wp_enqueue_script(
            'vmpfence-beacon',
            VMPFENCE_PLUGIN_URL . 'admin/assets/js/live-traffic-beacon.js',
            array('jquery'),
            VMPFENCE_VERSION,
            true
        );

        // Localize script with AJAX URL and nonce
        wp_localize_script('vmpfence-beacon', 'vmpfenceBeacon', array(
            'ajaxUrl' => admin_url('admin-ajax.php'),
            'nonce' => wp_create_nonce('vmpfence_beacon')
        ));
    }

    /**
     * Handle cleanup of expired human cache entries
     *
     * Called by cron job daily
     *
     * @since 2.1.0
     * @return void
     */
    public function handle_cleanup_human_cache() {
        if (class_exists('VMPFence_Visitor_Classifier')) {
            VMPFence_Visitor_Classifier::cleanup_expired_cache();
        }
    }
}
