<?php
/**
 * ==========================
 * 🔐 IGNY8 FILE RULE HEADER
 * ==========================
 * @file         : igny8-cron-master-dispatcher.php
 * @location     : /core/cron/igny8-cron-master-dispatcher.php
 * @type         : CRON Handler
 * @scope        : Global
 * @allowed      : Cron scheduling, automation dispatch, resource management
 * @reusability  : Globally Reusable
 * @notes        : Central cron dispatcher for all automation jobs
 */

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

/**
 * Master Dispatcher - Main execution function
 * 
 * Runs every 5 minutes via cPanel, checks database schedules,
 * and executes only due automations with proper limits and timing.
 */
function igny8_master_dispatcher_run() {
    echo "<div style='background:#e8f4fd;padding:10px;margin:5px;border:1px solid #2196F3;'>";
    echo "<strong>Igny8 MASTER DISPATCHER: Starting smart automation check</strong><br>";
    error_log("Igny8 MASTER DISPATCHER: Starting smart automation check");
    
    // Get all defined cron jobs
    $cron_jobs = igny8_get_defined_cron_jobs();
    $current_time = current_time('timestamp');
    $executed_jobs = [];
    $skipped_jobs = [];
    
    echo "<strong>Igny8 MASTER DISPATCHER: Found " . count($cron_jobs) . " defined jobs</strong><br>";
    
    // Get settings and limits
    $cron_settings = get_option('igny8_cron_settings', []);
    $cron_limits = get_option('igny8_cron_limits', []);
    
    // Initialize default settings if missing
    if (empty($cron_settings)) {
        $cron_settings = igny8_get_default_cron_settings();
        update_option('igny8_cron_settings', $cron_settings);
        echo "<strong>Igny8 MASTER DISPATCHER: Initialized default settings</strong><br>";
    }
    
    if (empty($cron_limits)) {
        $cron_limits = igny8_get_default_cron_limits();
        update_option('igny8_cron_limits', $cron_limits);
        echo "<strong>Igny8 MASTER DISPATCHER: Initialized default limits</strong><br>";
    }
    
    // Process each job in priority order
    foreach ($cron_jobs as $job_name => $job_config) {
        echo "<strong>Igny8 MASTER DISPATCHER: Checking job: " . $job_name . "</strong><br>";
        
        // Check if job is enabled
        $job_settings = $cron_settings[$job_name] ?? [];
        if (!($job_settings['enabled'] ?? false)) {
            echo "<strong>Igny8 MASTER DISPATCHER: Job disabled, skipping</strong><br>";
            $skipped_jobs[] = $job_name;
            continue;
        }
        
        // Check if job is due (simplified - just check if enabled and not recently run)
        $last_run = $job_settings['last_run'] ?? 0;
        $time_since_last_run = $current_time - $last_run;
        
        // Run job if it hasn't been run in the last 5 minutes (to prevent duplicate runs)
        if ($time_since_last_run < 300) {
            echo "<strong>Igny8 MASTER DISPATCHER: Job run recently, skipping</strong><br>";
            $skipped_jobs[] = $job_name;
            continue;
        }
        
        // Check if job is already running (duplicate prevention)
        $lock_key = 'igny8_cron_running_' . $job_name;
        if (get_transient($lock_key)) {
            echo "<strong>Igny8 MASTER DISPATCHER: Job already running, skipping</strong><br>";
            $skipped_jobs[] = $job_name;
            continue;
        }
        
        // Set lock for this job
        $max_execution_time = $job_config['max_execution_time'] ?? 300;
        set_transient($lock_key, true, $max_execution_time);
        
        echo "<strong>Igny8 MASTER DISPATCHER: Executing job: " . $job_name . "</strong><br>";
        
        try {
            // Get job limit
            $job_limit = $cron_limits[$job_name] ?? 1;
            
            // Set limit as global variable for handlers to use
            $GLOBALS['igny8_cron_limit'] = $job_limit;
            
            // Execute the job
            $start_time = microtime(true);
            do_action($job_name);
            $execution_time = microtime(true) - $start_time;
            
            // Update last run time
            $cron_settings[$job_name]['last_run'] = $current_time;
            update_option('igny8_cron_settings', $cron_settings);
            
            // Track individual job execution with detailed logging
            $processed_count = $GLOBALS['igny8_cron_processed_count'] ?? 0;
            $result_details = $GLOBALS['igny8_cron_result_details'] ?? '';
            
            echo "<strong>Igny8 MASTER DISPATCHER: Global variables - processed_count: $processed_count, result_details: $result_details</strong><br>";
            
            $job_health = [
                'last_run' => $current_time,
                'success' => true,
                'last_success' => true,
                'execution_time' => round($execution_time, 2),
                'error_message' => '',
                'processed_count' => $processed_count,
                'result_details' => $result_details,
                'execution_method' => (isset($_GET['import_key']) && !empty($_GET['import_key'])) ? 'external_url' : 'server_cron'
            ];
            update_option('igny8_cron_health_' . $job_name, $job_health);
            
            $executed_jobs[] = [
                'job' => $job_name,
                'execution_time' => round($execution_time, 2),
                'success' => true
            ];
            
            echo "<strong>Igny8 MASTER DISPATCHER: Job completed successfully in " . round($execution_time, 2) . "s</strong><br>";
            
        } catch (Exception $e) {
            echo "<strong>Igny8 MASTER DISPATCHER: Job failed: " . $e->getMessage() . "</strong><br>";
            error_log("Igny8 MASTER DISPATCHER: Job $job_name failed - " . $e->getMessage());
            
            // Track individual job failure
            $job_health = [
                'last_run' => $current_time,
                'success' => false,
                'last_success' => false,
                'execution_time' => 0,
                'error_message' => $e->getMessage(),
                'processed_count' => $GLOBALS['igny8_cron_processed_count'] ?? 0,
                'result_details' => 'FAILED: ' . $e->getMessage(),
                'execution_method' => (isset($_GET['import_key']) && !empty($_GET['import_key'])) ? 'external_url' : 'server_cron'
            ];
            update_option('igny8_cron_health_' . $job_name, $job_health);
            
            $executed_jobs[] = [
                'job' => $job_name,
                'execution_time' => 0,
                'success' => false,
                'last_success' => false,
                'error' => $e->getMessage()
            ];
        } catch (Throwable $e) {
            echo "<strong>Igny8 MASTER DISPATCHER: Job fatal error: " . $e->getMessage() . "</strong><br>";
            error_log("Igny8 MASTER DISPATCHER: Job $job_name fatal error - " . $e->getMessage());
            
            // Track individual job failure
            $job_health = [
                'last_run' => $current_time,
                'success' => false,
                'last_success' => false,
                'execution_time' => 0,
                'error_message' => $e->getMessage(),
                'processed_count' => $GLOBALS['igny8_cron_processed_count'] ?? 0,
                'result_details' => 'FAILED: ' . $e->getMessage(),
                'execution_method' => (isset($_GET['import_key']) && !empty($_GET['import_key'])) ? 'external_url' : 'server_cron'
            ];
            update_option('igny8_cron_health_' . $job_name, $job_health);
            
            $executed_jobs[] = [
                'job' => $job_name,
                'execution_time' => 0,
                'success' => false,
                'last_success' => false,
                'error' => $e->getMessage()
            ];
        } finally {
            // Always release the lock
            delete_transient($lock_key);
        }
    }
    
    // Log summary
    echo "<strong>Igny8 MASTER DISPATCHER: Execution summary</strong><br>";
    echo "<strong>Igny8 MASTER DISPATCHER: Jobs executed: " . count($executed_jobs) . "</strong><br>";
    echo "<strong>Igny8 MASTER DISPATCHER: Jobs skipped: " . count($skipped_jobs) . "</strong><br>";
    
    // Store execution log
    update_option('igny8_cron_last_execution', [
        'timestamp' => $current_time,
        'executed' => $executed_jobs,
        'skipped' => $skipped_jobs
    ]);
    
    echo "<strong>Igny8 MASTER DISPATCHER: Smart automation check completed</strong><br>";
    echo "</div>";
    
    // Return success response for external cron
    return [
        'success' => true,
        'message' => 'Master dispatcher executed successfully',
        'executed' => count($executed_jobs),
        'skipped' => count($skipped_jobs),
        'timestamp' => current_time('mysql')
    ];
}

/**
 * Get all defined cron jobs with their configurations
 */
function igny8_get_defined_cron_jobs() {
    return [
        'igny8_auto_cluster_cron' => [
            'handler' => 'igny8_auto_cluster_cron_handler',
            'priority' => 1,
            'max_execution_time' => 600, // 10 minutes
            'description' => 'Auto cluster unmapped keywords',
            'module' => 'planner'
        ],
        'igny8_auto_generate_ideas_cron' => [
            'handler' => 'igny8_auto_generate_ideas_cron_handler',
            'priority' => 2,
            'max_execution_time' => 300, // 5 minutes
            'description' => 'Auto generate ideas from clusters',
            'module' => 'planner'
        ],
        'igny8_auto_queue_cron' => [
            'handler' => 'igny8_auto_queue_cron_handler',
            'priority' => 3,
            'max_execution_time' => 300, // 5 minutes
            'description' => 'Auto queue new ideas',
            'module' => 'planner'
        ],
        'igny8_auto_generate_content_cron' => [
            'handler' => 'igny8_auto_generate_content_cron_handler',
            'priority' => 4,
            'max_execution_time' => 600, // 10 minutes
            'description' => 'Auto generate content from queued tasks',
            'module' => 'writer'
        ],
        'igny8_auto_generate_images_cron' => [
            'handler' => 'igny8_auto_generate_images_cron_handler',
            'priority' => 5,
            'max_execution_time' => 900, // 15 minutes
            'description' => 'Auto generate images for content',
            'module' => 'writer'
        ],
        'igny8_auto_publish_drafts_cron' => [
            'handler' => 'igny8_auto_publish_drafts_cron_handler',
            'priority' => 6,
            'max_execution_time' => 300, // 5 minutes
            'description' => 'Auto publish completed drafts',
            'module' => 'writer'
        ],
        'igny8_process_ai_queue_cron' => [
            'handler' => 'igny8_process_ai_queue_cron_handler',
            'priority' => 7,
            'max_execution_time' => 300, // 5 minutes
            'description' => 'Process AI queue tasks',
            'module' => 'ai'
        ],
        'igny8_auto_recalc_cron' => [
            'handler' => 'igny8_auto_recalc_cron_handler',
            'priority' => 8,
            'max_execution_time' => 300, // 5 minutes
            'description' => 'Auto recalculate metrics',
            'module' => 'analytics'
        ],
        'igny8_auto_optimizer_cron' => [
            'handler' => 'igny8_auto_optimizer_cron_handler',
            'priority' => 9,
            'max_execution_time' => 300, // 5 minutes
            'description' => 'Auto optimize content and keywords',
            'module' => 'optimizer'
        ],
        'igny8_health_check_cron' => [
            'handler' => 'igny8_health_check_cron_handler',
            'priority' => 10,
            'max_execution_time' => 300, // 5 minutes
            'description' => 'System health check and cleanup',
            'module' => 'system'
        ]
    ];
}


/**
 * Get default cron settings
 */
function igny8_get_default_cron_settings() {
    $jobs = igny8_get_defined_cron_jobs();
    $settings = [];
    
    foreach ($jobs as $job_name => $config) {
        $settings[$job_name] = [
            'enabled' => false, // Default to disabled
            'last_run' => 0
        ];
    }
    
    return $settings;
}

/**
 * Get default cron limits
 */
function igny8_get_default_cron_limits() {
    return [
        'igny8_auto_cluster_cron' => 1,
        'igny8_auto_generate_ideas_cron' => 1,
        'igny8_auto_queue_cron' => 1,
        'igny8_auto_generate_content_cron' => 1,
        'igny8_auto_generate_images_cron' => 1,
        'igny8_auto_publish_drafts_cron' => 1,
        'igny8_process_ai_queue_cron' => 1,
        'igny8_auto_recalc_cron' => 1,
        'igny8_auto_optimizer_cron' => 1,
        'igny8_health_check_cron' => 1
    ];
}

/**
 * Update cron settings for a specific job
 */
function igny8_update_cron_job_settings($job_name, $settings) {
    $cron_settings = get_option('igny8_cron_settings', []);
    $cron_settings[$job_name] = array_merge($cron_settings[$job_name] ?? [], $settings);
    update_option('igny8_cron_settings', $cron_settings);
}

/**
 * Update cron limits for a specific job
 */
function igny8_update_cron_job_limits($job_name, $limit) {
    $cron_limits = get_option('igny8_cron_limits', []);
    $cron_limits[$job_name] = $limit;
    update_option('igny8_cron_limits', $cron_limits);
}

/**
 * Get health status for a specific job
 */
function igny8_get_job_health_status($job_name) {
    $health = get_option('igny8_cron_health_' . $job_name, []);
    $cron_settings = get_option('igny8_cron_settings', []);
    $job_settings = $cron_settings[$job_name] ?? [];
    
    return [
        'enabled' => $job_settings['enabled'] ?? false,
        'last_run' => isset($health['last_run']) ? date('Y-m-d H:i:s', $health['last_run']) : 'Never',
        'last_success' => $health['success'] ?? null,
        'execution_time' => isset($health['execution_time']) ? round($health['execution_time'], 2) : 0,
        'error_message' => $health['error_message'] ?? '',
        'processed_count' => $health['processed_count'] ?? 0,
        'result_details' => $health['result_details'] ?? '',
        'execution_method' => $health['execution_method'] ?? 'unknown'
    ];
}

/**
 * Get cron job status and next run time
 */
function igny8_get_cron_job_status($job_name) {
    $cron_settings = get_option('igny8_cron_settings', []);
    $job_settings = $cron_settings[$job_name] ?? [];
    
    if (empty($job_settings)) {
        return [
            'enabled' => false,
            'last_run' => 'Never'
        ];
    }
    
    return [
        'enabled' => $job_settings['enabled'] ?? false,
        'last_run' => isset($job_settings['last_run']) && $job_settings['last_run'] ? date('Y-m-d H:i:s', $job_settings['last_run']) : 'Never'
    ];
}
