<?php
/**
 * ==========================
 * 🔐 IGNY8 FILE RULE HEADER
 * ==========================
 * @file         : igny8-cron-handlers.php
 * @location     : /core/cron/igny8-cron-handlers.php
 * @type         : CRON Handler
 * @scope        : Global
 * @allowed      : Cron job implementations, automation handlers, error handling
 * @reusability  : Globally Reusable
 * @notes        : All cron job handler implementations with safety checks
 */

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

/**
 * AI Queue Processing Cron Handler
 * 
 * Processes AI queue tasks with safety checks and duplicate prevention.
 */
function igny8_process_ai_queue_cron_handler() {
    // Check if AI queue processing is enabled
    if (igny8_get_ai_setting('ai_queue_enabled', 'enabled') !== 'enabled') {
        igny8_log_ai_event('AI Queue Skipped', 'ai', 'queue_processing', 'info', 'AI queue processing disabled', 'Automation disabled in settings');
        return;
    }
    
    global $wpdb;
    
    // Get processing lock to prevent duplicates
    $lock_key = 'igny8_ai_queue_processing';
    if (get_transient($lock_key)) {
        igny8_log_ai_event('AI Queue Skipped', 'ai', 'queue_processing', 'info', 'Queue processing already running', 'Duplicate execution prevented');
        return;
    }
    
    // Set lock for 5 minutes
    set_transient($lock_key, true, 300);
    
    try {
        // Use global limit from settings
        $limit = $GLOBALS['igny8_cron_limit'] ?? null;
        if ($limit === null) {
            error_log('Igny8 AI Queue Cron: No limit set in Smart Automation Jobs table');
            $GLOBALS['igny8_cron_processed_count'] = 0;
            $GLOBALS['igny8_cron_result_details'] = "FAILED: No limit set in Smart Automation Jobs table";
            return;
        }
        $processed = igny8_process_ai_queue($limit);
        
        if ($processed > 0) {
            igny8_log_ai_event('AI Queue Processed', 'ai', 'queue_processing', 'success', 'AI queue tasks processed', "Tasks processed: $processed");
            
        // Set global variables for detailed logging
        $GLOBALS['igny8_cron_processed_count'] = $processed;
        $GLOBALS['igny8_cron_result_details'] = "Processed {$processed} AI queue tasks";
        echo "<strong>Igny8 AI QUEUE HANDLER: Set global variables - processed_count: $processed, result_details: Processed {$processed} AI queue tasks</strong><br>";
        } else {
            igny8_log_ai_event('AI Queue Empty', 'ai', 'queue_processing', 'info', 'No tasks in queue', 'All tasks are already processed');
            
            // Set global variables for detailed logging
            $GLOBALS['igny8_cron_processed_count'] = 0;
            $GLOBALS['igny8_cron_result_details'] = "No AI queue tasks to process";
        }
        
    } catch (Exception $e) {
        igny8_log_ai_event('AI Queue Error', 'ai', 'queue_processing', 'error', 'AI queue processing failed', $e->getMessage());
        
        // Set global variables for detailed logging (failure case)
        $GLOBALS['igny8_cron_processed_count'] = 0;
        $GLOBALS['igny8_cron_result_details'] = "FAILED: " . $e->getMessage();
    } finally {
        // Always release the lock
        delete_transient($lock_key);
    }
}

/**
 * Auto Cluster Cron Handler
 * 
 * Automatically clusters unmapped keywords with taxonomy safety.
 */
function igny8_auto_cluster_cron_handler() {
    // Suppress PHP warnings for model rates in cron context
    $old_error_reporting = error_reporting();
    error_reporting($old_error_reporting & ~E_WARNING);
    
    echo "<div style='background:#e8f4fd;padding:10px;margin:5px;border:1px solid #2196F3;'>";
    echo "<strong>Igny8 CRON HANDLER: auto_cluster started</strong><br>";
    error_log("Igny8 CRON HANDLER: auto_cluster started");
    
    // Check if automation is enabled via cron settings
    echo "<strong>Igny8 CRON HANDLER: Checking if automation is enabled</strong><br>";
    $cron_settings = get_option('igny8_cron_settings', []);
    $job_settings = $cron_settings['igny8_auto_cluster_cron'] ?? [];
    $auto_cluster_enabled = $job_settings['enabled'] ?? false;
    echo "<strong>Igny8 CRON HANDLER: auto_cluster_enabled =</strong> " . ($auto_cluster_enabled ? 'enabled' : 'disabled') . "<br>";
    
    if (!$auto_cluster_enabled) {
        echo "<strong>Igny8 CRON HANDLER: Automation disabled, exiting</strong><br>";
        error_log("Igny8 CRON HANDLER: auto_cluster automation disabled");
        echo "</div>";
        return;
    }
    echo "<strong>Igny8 CRON HANDLER: Automation enabled, continuing</strong><br>";
    
    // Check if AI mode is enabled
    echo "<strong>Igny8 CRON HANDLER: Checking AI mode</strong><br>";
    $planner_mode = igny8_get_ai_setting('planner_mode', 'manual');
    echo "<strong>Igny8 CRON HANDLER: planner_mode =</strong> " . $planner_mode . "<br>";
    
    if ($planner_mode !== 'ai') {
        echo "<strong>Igny8 CRON HANDLER: AI mode disabled, exiting</strong><br>";
        error_log("Igny8 CRON HANDLER: AI mode disabled");
        echo "</div>";
        return;
    }
    echo "<strong>Igny8 CRON HANDLER: AI mode enabled, continuing</strong><br>";
    
    // Check if sector is selected
    echo "<strong>Igny8 CRON HANDLER: Checking sector options</strong><br>";
    
    // Check if function exists first
    if (!function_exists('igny8_get_sector_options')) {
        echo "<strong>Igny8 CRON HANDLER: ERROR - igny8_get_sector_options function not found</strong><br>";
        igny8_log_ai_event('Auto Cluster Failed', 'planner', 'auto_cluster', 'error', 'Sector options function not available', 'Function igny8_get_sector_options not found');
        echo "<strong>Igny8 CRON HANDLER: Exiting due to missing function</strong><br>";
        echo "</div>";
        return;
    }
    
    try {
        echo "<strong>Igny8 CRON HANDLER: Calling igny8_get_sector_options()</strong><br>";
        $sector_options = igny8_get_sector_options();
        echo "<strong>Igny8 CRON HANDLER: sector_options count =</strong> " . count($sector_options) . "<br>";
        echo "<strong>Igny8 CRON HANDLER: sector_options content:</strong> " . print_r($sector_options, true) . "<br>";
    } catch (Exception $e) {
        echo "<strong>Igny8 CRON HANDLER: ERROR - Exception in igny8_get_sector_options:</strong> " . $e->getMessage() . "<br>";
        igny8_log_ai_event('Auto Cluster Failed', 'planner', 'auto_cluster', 'error', 'Exception in sector options function', $e->getMessage());
        echo "<strong>Igny8 CRON HANDLER: Exiting due to sector options exception</strong><br>";
        echo "</div>";
        return;
    }
    
    if (empty($sector_options)) {
        echo "<strong>Igny8 CRON HANDLER: No sector selected, checking alternatives</strong><br>";
        echo "<strong>Igny8 CRON HANDLER: Checking if igny8_get_sector_options function exists:</strong> " . (function_exists('igny8_get_sector_options') ? 'YES' : 'NO') . "<br>";
        
        // Try to get sectors directly from database
        global $wpdb;
        $sectors = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}igny8_sectors WHERE status = 'active'");
        echo "<strong>Igny8 CRON HANDLER: Direct DB query found " . count($sectors) . " active sectors</strong><br>";
        
        if (empty($sectors)) {
            echo "<strong>Igny8 CRON HANDLER: ERROR - No active sectors found, cannot proceed</strong><br>";
            igny8_log_ai_event('Auto Cluster Failed', 'planner', 'auto_cluster', 'error', 'No active sectors configured', 'Sector configuration required for clustering');
            echo "<strong>Igny8 CRON HANDLER: Exiting due to missing sectors</strong><br>";
            echo "</div>";
            return;
        } else {
            echo "<strong>Igny8 CRON HANDLER: Found sectors in DB, using them</strong><br>";
            $sector_options = $sectors;
        }
    }
    echo "<strong>Igny8 CRON HANDLER: Sector selected, continuing</strong><br>";
    
    global $wpdb;
    echo "<strong>Igny8 CRON HANDLER: Database connection established</strong><br>";
    
    // Get unmapped keywords (use dynamic limit from settings)
    $limit = $GLOBALS['igny8_cron_limit'] ?? null;
    if ($limit === null) {
        // Try to get limit from Smart Automation Jobs table directly
        $cron_limits = get_option('igny8_cron_limits', []);
        $limit = $cron_limits['igny8_auto_cluster_cron'] ?? null;
        
        if ($limit === null) {
            error_log('Igny8 Auto Cluster Cron: No limit set in Smart Automation Jobs table');
            $GLOBALS['igny8_cron_processed_count'] = 0;
            $GLOBALS['igny8_cron_result_details'] = "FAILED: No limit set in Smart Automation Jobs table";
            return;
        }
        
        echo "<strong>Igny8 CRON HANDLER: Using limit from Smart Automation Jobs table: $limit</strong><br>";
    }
    echo "<strong>Igny8 CRON HANDLER: Querying unmapped keywords (limit: $limit)</strong><br>";
    $query = "SELECT id, keyword FROM {$wpdb->prefix}igny8_keywords WHERE cluster_id IS NULL OR cluster_id = 0 LIMIT $limit";
    echo "<strong>Igny8 CRON HANDLER: SQL Query:</strong> " . $query . "<br>";
    
    $unmapped_keywords = $wpdb->get_results($query);
    
    echo "<strong>Igny8 CRON HANDLER: Found</strong> " . count($unmapped_keywords) . " unmapped keywords<br>";
    
    if (!empty($unmapped_keywords)) {
        echo "<strong>Igny8 CRON HANDLER: Sample keywords:</strong><br>";
        foreach (array_slice($unmapped_keywords, 0, 3) as $keyword) {
            echo "- ID: " . $keyword->id . ", Keyword: " . $keyword->keyword . "<br>";
        }
    }
    
    if (empty($unmapped_keywords)) {
        echo "<strong>Igny8 CRON HANDLER: ERROR - No unmapped keywords found</strong><br>";
        igny8_log_ai_event('Auto Cluster Failed', 'planner', 'auto_cluster', 'error', 'No unmapped keywords available for clustering', 'All keywords are already clustered or no keywords exist');
        echo "<strong>Igny8 CRON HANDLER: Exiting due to no keywords to process</strong><br>";
        echo "</div>";
        return;
    }
    
    $keyword_ids = array_column($unmapped_keywords, 'id');
    echo "<strong>Igny8 CRON HANDLER: Processing</strong> " . count($keyword_ids) . " keywords<br>";
    
    // Log automation start
    echo "<strong>Igny8 CRON HANDLER: Logging automation start</strong><br>";
    igny8_log_ai_event('Auto Cluster Started', 'planner', 'auto_cluster', 'info', 'Starting automated clustering', 'Keywords: ' . count($keyword_ids));
    
    // Direct clustering without AJAX simulation
    echo "<strong>Igny8 CRON HANDLER: Starting direct clustering process</strong><br>";
    
    // Set up user context for permissions
    if (!current_user_can('manage_options')) {
        // Get admin user for cron context
        $admin_users = get_users(['role' => 'administrator', 'number' => 1]);
        if (!empty($admin_users)) {
            wp_set_current_user($admin_users[0]->ID);
            echo "<strong>Igny8 CRON HANDLER: Set admin user context for permissions</strong><br>";
        }
    }
    
    // Get keywords data
    echo "<strong>Igny8 CRON HANDLER: Getting keywords data</strong><br>";
    $placeholders = implode(',', array_fill(0, count($keyword_ids), '%d'));
    $keywords = $wpdb->get_results($wpdb->prepare("
        SELECT * FROM {$wpdb->prefix}igny8_keywords 
        WHERE id IN ({$placeholders})
    ", $keyword_ids));
    
    echo "<strong>Igny8 CRON HANDLER: Found " . count($keywords) . " keywords in database</strong><br>";
    
    if (empty($keywords)) {
        echo "<strong>Igny8 CRON HANDLER: ERROR - No valid keywords found</strong><br>";
        igny8_log_ai_event('Auto Cluster Failed', 'planner', 'auto_cluster', 'error', 'No valid keywords found in database', 'Keyword IDs: ' . implode(',', $keyword_ids));
        echo "</div>";
        return;
    }
    
    // Check if keywords already have clusters
    $keywords_with_clusters = array_filter($keywords, function($keyword) {
        return !empty($keyword->cluster_id) && $keyword->cluster_id > 0;
    });
    
    if (!empty($keywords_with_clusters)) {
        echo "<strong>Igny8 CRON HANDLER: WARNING - Some keywords already have clusters</strong><br>";
        $keyword_names = array_column($keywords_with_clusters, 'keyword');
        echo "<strong>Igny8 CRON HANDLER: Already clustered: " . implode(', ', array_slice($keyword_names, 0, 3)) . "</strong><br>";
    }
    
    // Get clustering prompt
    echo "<strong>Igny8 CRON HANDLER: Getting clustering prompt</strong><br>";
    $prompt_template = wp_unslash(igny8_get_ai_setting('clustering_prompt', igny8_get_default_clustering_prompt()));
    echo "<strong>Igny8 CRON HANDLER: Prompt length: " . strlen($prompt_template) . "</strong><br>";
    
    // Generate session ID for progress tracking
    $session_id = 'cron_clustering_' . time() . '_' . wp_generate_password(8, false);
    echo "<strong>Igny8 CRON HANDLER: Session ID: " . $session_id . "</strong><br>";
    
    // Log AI request initiation
    igny8_log_ai_event('Cron AI Request Initiated', 'planner', 'clustering', 'info', 'Starting cron AI clustering process', 'Keywords: ' . count($keyword_ids) . ', Session: ' . $session_id);
    
    // Process with AI
    echo "<strong>Igny8 CRON HANDLER: Calling AI processing</strong><br>";
    try {
        $ai_result = igny8_process_ai_request('clustering', $keywords, $prompt_template);
        echo "<strong>Igny8 CRON HANDLER: AI processing completed</strong><br>";
        
        if ($ai_result === false) {
            echo "<strong>Igny8 CRON HANDLER: ERROR - AI processing returned false</strong><br>";
            igny8_log_ai_event('Cron AI Processing Failed', 'planner', 'clustering', 'error', 'AI processing returned false', 'Check OpenAI API configuration');
            echo "</div>";
            return;
        }
        
        if (!is_array($ai_result) || !isset($ai_result['clusters'])) {
            echo "<strong>Igny8 CRON HANDLER: ERROR - AI returned invalid result</strong><br>";
            igny8_log_ai_event('Cron AI Processing Failed', 'planner', 'clustering', 'error', 'AI returned invalid result', 'Result type: ' . gettype($ai_result));
            echo "</div>";
            return;
        }
        
        echo "<strong>Igny8 CRON HANDLER: AI returned " . count($ai_result['clusters']) . " clusters</strong><br>";
        
        // Debug: Show AI response structure
        echo "<strong>Igny8 CRON HANDLER: AI Response Debug:</strong><br>";
        echo "<strong>Igny8 CRON HANDLER: Full AI result structure:</strong> " . json_encode($ai_result, JSON_PRETTY_PRINT) . "<br>";
        
        igny8_log_ai_event('Cron AI Processing Complete', 'planner', 'clustering', 'success', 'AI returned ' . count($ai_result['clusters']) . ' clusters', 'Clusters: ' . json_encode(array_column($ai_result['clusters'], 'name')));
        
        // Log database operations start
        echo "<strong>Igny8 CRON HANDLER: Starting database operations</strong><br>";
        igny8_log_ai_event('Cron Database Operations Started', 'planner', 'clustering', 'info', 'Starting to create clusters in database', 'Clusters to create: ' . count($ai_result['clusters']));
        
        // Get sector options for assignment logic (same as AJAX handler)
        echo "<strong>Igny8 CRON HANDLER: Getting sector options for assignment</strong><br>";
        $sector_options = igny8_get_sector_options();
        $sector_count = count($sector_options);
        echo "<strong>Igny8 CRON HANDLER: Found " . $sector_count . " sectors</strong><br>";
        
        // Create clusters in database (following AJAX handler process)
        $created_clusters = [];
        $clusters_created = 0;
        $keywords_processed = 0;
        
        foreach ($ai_result['clusters'] as $cluster_data) {
            echo "<strong>Igny8 CRON HANDLER: Processing cluster: " . $cluster_data['name'] . "</strong><br>";
            
            try {
            
            // Determine sector_id based on sector count (same logic as AJAX handler)
            $sector_id = 1; // Default fallback
            echo "<strong>Igny8 CRON HANDLER: Determining sector assignment</strong><br>";
            
            if ($sector_count == 1) {
                // Only 1 sector: assign all clusters to that sector
                $sector_id = $sector_options[0]['value'];
                echo "<strong>Igny8 CRON HANDLER: Single sector found, assigning to sector ID: " . $sector_id . "</strong><br>";
            } elseif ($sector_count > 1) {
                // Multiple sectors: use AI response sector assignment
                if (isset($cluster_data['sector']) && !empty($cluster_data['sector'])) {
                    echo "<strong>Igny8 CRON HANDLER: AI provided sector: " . $cluster_data['sector'] . "</strong><br>";
                    // Find sector ID by matching sector name from AI response
                    foreach ($sector_options as $sector) {
                        if (strtolower(trim($sector['label'])) === strtolower(trim($cluster_data['sector']))) {
                            $sector_id = $sector['value'];
                            echo "<strong>Igny8 CRON HANDLER: Matched sector ID: " . $sector_id . "</strong><br>";
                            break;
                        }
                    }
                }
                // If no match found or no sector in AI response, use first sector as fallback
                if ($sector_id == 1 && !isset($cluster_data['sector'])) {
                    $sector_id = $sector_options[0]['value'];
                    echo "<strong>Igny8 CRON HANDLER: No sector match, using first sector ID: " . $sector_id . "</strong><br>";
                }
            }
            
            // Create cluster record in database (same as AJAX handler)
            echo "<strong>Igny8 CRON HANDLER: Creating cluster record in database</strong><br>";
            $result = $wpdb->insert(
                $wpdb->prefix . 'igny8_clusters',
                [
                    'cluster_name' => sanitize_text_field($cluster_data['name']),
                    'sector_id' => $sector_id,
                    'status' => 'active',
                    'keyword_count' => count($cluster_data['keywords']),
                    'total_volume' => 0,
                    'avg_difficulty' => 0,
                    'mapped_pages_count' => 0,
                    'created_at' => current_time('mysql')
                ],
                ['%s', '%d', '%s', '%d', '%d', '%f', '%d', '%s']
            );
            
            if ($result) {
                $cluster_id = $wpdb->insert_id;
                $created_clusters[] = $cluster_id;
                $clusters_created++;
                echo "<strong>Igny8 CRON HANDLER: SUCCESS - Created cluster record with ID: " . $cluster_id . "</strong><br>";
                
                // Trigger taxonomy term creation for AI-generated cluster (same as AJAX handler)
                echo "<strong>Igny8 CRON HANDLER: Triggering taxonomy term creation</strong><br>";
                try {
                    do_action('igny8_cluster_added', $cluster_id);
                    echo "<strong>Igny8 CRON HANDLER: SUCCESS - Taxonomy term creation triggered</strong><br>";
                    igny8_log_ai_event('Cron Cluster Taxonomy Triggered', 'planner', 'clustering', 'info', 'Triggered igny8_cluster_added action', "Cluster: {$cluster_data['name']} (ID: {$cluster_id})");
                } catch (Exception $e) {
                    echo "<strong>Igny8 CRON HANDLER: WARNING - Taxonomy term creation failed: " . $e->getMessage() . "</strong><br>";
                    igny8_log_ai_event('Cron Cluster Taxonomy Failed', 'planner', 'clustering', 'warning', 'Taxonomy term creation failed', "Cluster: {$cluster_data['name']} (ID: {$cluster_id}), Error: " . $e->getMessage());
                } catch (Throwable $e) {
                    echo "<strong>Igny8 CRON HANDLER: ERROR - Fatal error in taxonomy term creation: " . $e->getMessage() . "</strong><br>";
                    igny8_log_ai_event('Cron Cluster Taxonomy Fatal Error', 'planner', 'clustering', 'error', 'Fatal error in taxonomy term creation', "Cluster: {$cluster_data['name']} (ID: {$cluster_id}), Error: " . $e->getMessage());
                }
                
                // Log cluster creation
                igny8_log_ai_event('Cron Cluster Created', 'planner', 'clustering', 'success', 'Cluster created successfully', "Cluster: {$cluster_data['name']} (ID: {$cluster_id})");
                
                // Update keywords with cluster_id (same as AJAX handler)
            if (isset($cluster_data['keywords']) && is_array($cluster_data['keywords'])) {
                    echo "<strong>Igny8 CRON HANDLER: Processing " . count($cluster_data['keywords']) . " keywords for this cluster</strong><br>";
                    
                foreach ($cluster_data['keywords'] as $keyword_name) {
                        echo "<strong>Igny8 CRON HANDLER: Looking for keyword: " . $keyword_name . "</strong><br>";
                        
                        $update_result = $wpdb->update(
                            $wpdb->prefix . 'igny8_keywords',
                            ['cluster_id' => $cluster_id],
                            ['keyword' => $keyword_name],
                            ['%d'],
                            ['%s']
                        );
                        
                        if ($update_result !== false) {
                        $keywords_processed++;
                            echo "<strong>Igny8 CRON HANDLER: SUCCESS - Assigned keyword '" . $keyword_name . "' to cluster ID " . $cluster_id . "</strong><br>";
                        } else {
                            echo "<strong>Igny8 CRON HANDLER: ERROR - Failed to update keyword '" . $keyword_name . "': " . $wpdb->last_error . "</strong><br>";
                        }
                    }
                    
                    // Log keyword updates
                    igny8_log_ai_event('Cron Keywords Updated', 'planner', 'clustering', 'success', 'Keywords assigned to cluster', "Cluster: {$cluster_data['name']}, Keywords: " . count($cluster_data['keywords']));
                } else {
                    echo "<strong>Igny8 CRON HANDLER: WARNING - No keywords found in cluster data</strong><br>";
                }
                
                // Update cluster metrics (same as AJAX handler)
                echo "<strong>Igny8 CRON HANDLER: Updating cluster metrics</strong><br>";
                try {
                    $metrics_result = igny8_update_cluster_metrics($cluster_id);
                    if ($metrics_result) {
                        echo "<strong>Igny8 CRON HANDLER: SUCCESS - Cluster metrics updated</strong><br>";
                        igny8_log_ai_event('Cron Metrics Updated', 'planner', 'clustering', 'success', 'Cluster metrics calculated', "Cluster: {$cluster_data['name']}");
                    } else {
                        echo "<strong>Igny8 CRON HANDLER: WARNING - Failed to update cluster metrics</strong><br>";
                        igny8_log_ai_event('Cron Metrics Update Failed', 'planner', 'clustering', 'warning', 'Failed to update cluster metrics', "Cluster: {$cluster_data['name']}");
                    }
                } catch (Exception $e) {
                    echo "<strong>Igny8 CRON HANDLER: ERROR - Exception during metrics update: " . $e->getMessage() . "</strong><br>";
                    igny8_log_ai_event('Cron Metrics Update Error', 'planner', 'clustering', 'error', 'Exception during metrics update', "Cluster: {$cluster_data['name']}, Error: " . $e->getMessage());
                }
            } else {
                // Log cluster creation failure
                echo "<strong>Igny8 CRON HANDLER: ERROR - Failed to create cluster record: " . $wpdb->last_error . "</strong><br>";
                igny8_log_ai_event('Cron Cluster Creation Failed', 'planner', 'clustering', 'error', 'Failed to create cluster in database', "Cluster: {$cluster_data['name']}, Error: " . $wpdb->last_error);
            }
            
            } catch (Exception $e) {
                echo "<strong>Igny8 CRON HANDLER: ERROR - Exception processing cluster '{$cluster_data['name']}': " . $e->getMessage() . "</strong><br>";
                igny8_log_ai_event('Cron Cluster Processing Error', 'planner', 'clustering', 'error', 'Exception processing cluster', "Cluster: {$cluster_data['name']}, Error: " . $e->getMessage());
                echo "<strong>Igny8 CRON HANDLER: Continuing with next cluster</strong><br>";
                continue;
            } catch (Throwable $e) {
                echo "<strong>Igny8 CRON HANDLER: FATAL ERROR - Fatal error processing cluster '{$cluster_data['name']}': " . $e->getMessage() . "</strong><br>";
                igny8_log_ai_event('Cron Cluster Processing Fatal Error', 'planner', 'clustering', 'error', 'Fatal error processing cluster', "Cluster: {$cluster_data['name']}, Error: " . $e->getMessage());
                echo "<strong>Igny8 CRON HANDLER: Continuing with next cluster</strong><br>";
                continue;
            }
        }
        
        echo "<strong>Igny8 CRON HANDLER: Clustering completed successfully</strong><br>";
        echo "<strong>Igny8 CRON HANDLER: Database clusters created: " . $clusters_created . "</strong><br>";
        echo "<strong>Igny8 CRON HANDLER: Keywords processed: " . $keywords_processed . "</strong><br>";
        
        // Verify the results by checking database
        echo "<strong>Igny8 CRON HANDLER: Verifying results in database</strong><br>";
        $verify_clusters = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}igny8_clusters WHERE status = 'active'");
        $verify_keywords = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}igny8_keywords WHERE cluster_id IS NOT NULL AND cluster_id > 0");
        $verify_taxonomy_terms = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->terms} t INNER JOIN {$wpdb->term_taxonomy} tt ON t.term_id = tt.term_id WHERE tt.taxonomy = 'clusters'");
        
        echo "<strong>Igny8 CRON HANDLER: Total active clusters in database: " . $verify_clusters . "</strong><br>";
        echo "<strong>Igny8 CRON HANDLER: Total clustered keywords in database: " . $verify_keywords . "</strong><br>";
        echo "<strong>Igny8 CRON HANDLER: Total taxonomy terms for clusters: " . $verify_taxonomy_terms . "</strong><br>";
        
        // Log completion with verification
        igny8_log_ai_event('Cron Auto Cluster Complete', 'planner', 'auto_cluster', 'success', 'Cron automated clustering completed', 'Database clusters: ' . $clusters_created . ', Keywords processed: ' . $keywords_processed . ', Verified clusters: ' . $verify_clusters . ', Verified keywords: ' . $verify_keywords . ', Verified taxonomy terms: ' . $verify_taxonomy_terms);
        
        // Set global variables for detailed logging
        $GLOBALS['igny8_cron_processed_count'] = $keywords_processed;
        $GLOBALS['igny8_cron_result_details'] = "Processed {$keywords_processed} keywords, created {$clusters_created} clusters";
        
    } catch (Exception $e) {
        echo "<strong>Igny8 CRON HANDLER: ERROR - Exception during AI processing:</strong> " . $e->getMessage() . "<br>";
        igny8_log_ai_event('Cron Auto Cluster Failed', 'planner', 'auto_cluster', 'error', 'Exception during AI processing', $e->getMessage());
        
        // Set global variables for detailed logging (failure case)
        $GLOBALS['igny8_cron_processed_count'] = 0;
        $GLOBALS['igny8_cron_result_details'] = "FAILED: " . $e->getMessage();
        
        echo "</div>";
        return;
    }
    echo "<strong>Igny8 CRON HANDLER: auto_cluster completed</strong><br>";
    echo "</div>"; // Close the handler div
    
    // Restore error reporting
    error_reporting($old_error_reporting);
}

/**
 * Auto Generate Ideas Cron Handler
 * 
 * Automatically generates ideas from clusters without ideas.
 */
function igny8_auto_generate_ideas_cron_handler() {
    // Suppress PHP warnings for model rates in cron context
    $old_error_reporting = error_reporting();
    error_reporting($old_error_reporting & ~E_WARNING);
    
    echo "<div style='background:#e8f4fd;padding:10px;margin:5px;border:1px solid #2196F3;'>";
    echo "<strong>Igny8 CRON HANDLER: auto_generate_ideas started</strong><br>";
    error_log("Igny8 CRON HANDLER: auto_generate_ideas started");
    
    // Check if automation is enabled via cron settings
    echo "<strong>Igny8 CRON HANDLER: Checking if automation is enabled</strong><br>";
    $cron_settings = get_option('igny8_cron_settings', []);
    $job_settings = $cron_settings['igny8_auto_generate_ideas_cron'] ?? [];
    $auto_ideas_enabled = $job_settings['enabled'] ?? false;
    echo "<strong>Igny8 CRON HANDLER: auto_ideas_enabled =</strong> " . ($auto_ideas_enabled ? 'enabled' : 'disabled') . "<br>";
    
    if (!$auto_ideas_enabled) {
        echo "<strong>Igny8 CRON HANDLER: Automation disabled, exiting</strong><br>";
        error_log("Igny8 CRON HANDLER: auto_generate_ideas automation disabled");
        echo "</div>";
        return;
    }
    echo "<strong>Igny8 CRON HANDLER: Automation enabled, continuing</strong><br>";
    
    // Check if AI mode is enabled
    echo "<strong>Igny8 CRON HANDLER: Checking AI mode</strong><br>";
    $planner_mode = igny8_get_ai_setting('planner_mode', 'manual');
    echo "<strong>Igny8 CRON HANDLER: planner_mode =</strong> " . $planner_mode . "<br>";
    
    if ($planner_mode !== 'ai') {
        echo "<strong>Igny8 CRON HANDLER: AI mode disabled, exiting</strong><br>";
        error_log("Igny8 CRON HANDLER: AI mode disabled");
        echo "</div>";
        return;
    }
    echo "<strong>Igny8 CRON HANDLER: AI mode enabled, continuing</strong><br>";
    
    global $wpdb;
    echo "<strong>Igny8 CRON HANDLER: Database connection established</strong><br>";
    
    // Get clusters without ideas (use dynamic limit from settings)
    $limit = $GLOBALS['igny8_cron_limit'] ?? null;
    if ($limit === null) {
        error_log('Igny8 Auto Cluster Cron: No limit set in Smart Automation Jobs table');
        $GLOBALS['igny8_cron_processed_count'] = 0;
        $GLOBALS['igny8_cron_result_details'] = "FAILED: No limit set in Smart Automation Jobs table";
        return;
    }
    echo "<strong>Igny8 CRON HANDLER: Querying clusters without ideas (limit: $limit)</strong><br>";
    $clusters_without_ideas = $wpdb->get_results("
        SELECT c.id FROM {$wpdb->prefix}igny8_clusters c
        LEFT JOIN {$wpdb->prefix}igny8_content_ideas i ON c.id = i.keyword_cluster_id
        WHERE i.id IS NULL
        LIMIT $limit
    ");
    
    echo "<strong>Igny8 CRON HANDLER: Found</strong> " . count($clusters_without_ideas) . " clusters without ideas<br>";
    
    if (empty($clusters_without_ideas)) {
        echo "<strong>Igny8 CRON HANDLER: No clusters without ideas found, exiting</strong><br>";
        igny8_log_ai_event('Auto Generate Ideas Skipped', 'planner', 'auto_generate_ideas', 'info', 'No clusters without ideas found', 'All clusters already have ideas');
        echo "</div>";
        return;
    }
    
    $cluster_ids = array_column($clusters_without_ideas, 'id');
    echo "<strong>Igny8 CRON HANDLER: Processing</strong> " . count($cluster_ids) . " clusters<br>";
    
    // Log automation start
    echo "<strong>Igny8 CRON HANDLER: Logging automation start</strong><br>";
    igny8_log_ai_event('Auto Generate Ideas Started', 'planner', 'auto_generate_ideas', 'info', 'Starting automated idea generation', 'Clusters: ' . count($cluster_ids));
    
    // Set up user context for permissions
    echo "<strong>Igny8 CRON HANDLER: Setting up user context</strong><br>";
    if (!current_user_can('manage_options')) {
        // Get admin user for cron context
        $admin_users = get_users(['role' => 'administrator', 'number' => 1]);
        if (!empty($admin_users)) {
            wp_set_current_user($admin_users[0]->ID);
            echo "<strong>Igny8 CRON HANDLER: Set admin user context for permissions</strong><br>";
        }
    }
    
    // Simulate AJAX request to existing AI function
    echo "<strong>Igny8 CRON HANDLER: Starting AJAX simulation</strong><br>";
    $_POST['cluster_ids'] = json_encode($cluster_ids);
    $_POST['nonce'] = wp_create_nonce('igny8_planner_settings');
    
    // Capture output to prevent JSON response in cron
    ob_start();
    igny8_ajax_ai_generate_ideas();
    $output = ob_get_clean();
    
    echo "<strong>Igny8 CRON HANDLER: AJAX execution completed</strong><br>";
    
    // Parse JSON response
    $response = json_decode($output, true);
    echo "<strong>Igny8 CRON HANDLER: Response parsed, success =</strong> " . ($response['success'] ?? 'false') . "<br>";
    
    if ($response && $response['success']) {
        $ideas_created = $response['data']['ideas_created'] ?? count($cluster_ids);
        echo "<strong>Igny8 CRON HANDLER: SUCCESS - Ideas generated: " . $ideas_created . "</strong><br>";
        igny8_log_ai_event('Auto Generate Ideas Complete', 'planner', 'auto_generate_ideas', 'success', 'Automated idea generation completed', 'Ideas created: ' . $ideas_created);
        
        // Set global variables for detailed logging
        $GLOBALS['igny8_cron_processed_count'] = $ideas_created;
        $GLOBALS['igny8_cron_result_details'] = "Processed {$ideas_created} clusters, created {$ideas_created} ideas";
    } else {
        $error_msg = $response['data']['message'] ?? 'Unknown error';
        echo "<strong>Igny8 CRON HANDLER: ERROR - " . $error_msg . "</strong><br>";
        igny8_log_ai_event('Auto Generate Ideas Failed', 'planner', 'auto_generate_ideas', 'error', 'Automated idea generation failed', $error_msg);
        
        // Set global variables for detailed logging (failure case)
        $GLOBALS['igny8_cron_processed_count'] = 0;
        $GLOBALS['igny8_cron_result_details'] = "FAILED: " . $error_msg;
    }
    
    echo "<strong>Igny8 CRON HANDLER: auto_generate_ideas completed</strong><br>";
    echo "</div>"; // Close the handler div
    
    // Restore error reporting
    error_reporting($old_error_reporting);
}

/**
 * Auto Queue Cron Handler
 * 
 * Automatically queues new ideas for content generation.
 */
function igny8_auto_queue_cron_handler() {
    // Suppress PHP warnings for model rates in cron context
    $old_error_reporting = error_reporting();
    error_reporting($old_error_reporting & ~E_WARNING);
    
    echo "<div style='background:#e8f4fd;padding:10px;margin:5px;border:1px solid #2196F3;'>";
    echo "<strong>Igny8 CRON HANDLER: auto_queue started</strong><br>";
    error_log("Igny8 CRON HANDLER: auto_queue started");
    
    // Check if automation is enabled via cron settings
    echo "<strong>Igny8 CRON HANDLER: Checking if automation is enabled</strong><br>";
    $cron_settings = get_option('igny8_cron_settings', []);
    $job_settings = $cron_settings['igny8_auto_queue_cron'] ?? [];
    $auto_queue_enabled = $job_settings['enabled'] ?? false;
    echo "<strong>Igny8 CRON HANDLER: auto_queue_enabled =</strong> " . ($auto_queue_enabled ? 'enabled' : 'disabled') . "<br>";
    
    if (!$auto_queue_enabled) {
        echo "<strong>Igny8 CRON HANDLER: Automation disabled, exiting</strong><br>";
        error_log("Igny8 CRON HANDLER: auto_queue automation disabled");
        echo "</div>";
        return;
    }
    echo "<strong>Igny8 CRON HANDLER: Automation enabled, continuing</strong><br>";
    
    global $wpdb;
    echo "<strong>Igny8 CRON HANDLER: Database connection established</strong><br>";
    
    // Get new ideas (use dynamic limit from settings)
    $limit = $GLOBALS['igny8_cron_limit'] ?? null;
    if ($limit === null) {
        // Try to get limit from Smart Automation Jobs table directly
        $cron_limits = get_option('igny8_cron_limits', []);
        $limit = $cron_limits['igny8_auto_queue_cron'] ?? null;
        
        if ($limit === null) {
            error_log('Igny8 Auto Queue Cron: No limit set in Smart Automation Jobs table');
            $GLOBALS['igny8_cron_processed_count'] = 0;
            $GLOBALS['igny8_cron_result_details'] = "FAILED: No limit set in Smart Automation Jobs table";
            return;
        }
        
        echo "<strong>Igny8 CRON HANDLER: Using limit from Smart Automation Jobs table: $limit</strong><br>";
    }
    echo "<strong>Igny8 CRON HANDLER: Querying new ideas (limit: $limit)</strong><br>";
    $new_ideas = $wpdb->get_results("
        SELECT id FROM {$wpdb->prefix}igny8_content_ideas 
        WHERE status = 'new'
        LIMIT $limit
    ");
    
    echo "<strong>Igny8 CRON HANDLER: Found</strong> " . count($new_ideas) . " new ideas<br>";
    
    if (empty($new_ideas)) {
        echo "<strong>Igny8 CRON HANDLER: No new ideas found, exiting</strong><br>";
        igny8_log_ai_event('Auto Queue Skipped', 'planner', 'auto_queue', 'info', 'No new ideas found', 'All ideas are already queued');
        echo "</div>";
        return;
    }
    
    $idea_ids = array_column($new_ideas, 'id');
    echo "<strong>Igny8 CRON HANDLER: Processing</strong> " . count($idea_ids) . " ideas<br>";
    
    // Log automation start
    echo "<strong>Igny8 CRON HANDLER: Logging automation start</strong><br>";
    igny8_log_ai_event('Auto Queue Started', 'planner', 'auto_queue', 'info', 'Starting automated queueing', 'Ideas: ' . count($idea_ids));
    
    // Set up user context for permissions
    echo "<strong>Igny8 CRON HANDLER: Setting up user context</strong><br>";
    if (!current_user_can('edit_posts')) {
        // Get admin user for cron context
        $admin_users = get_users(['role' => 'administrator', 'number' => 1]);
        if (!empty($admin_users)) {
            wp_set_current_user($admin_users[0]->ID);
            echo "<strong>Igny8 CRON HANDLER: Set admin user context for permissions</strong><br>";
        }
    }
    
    // Skip AJAX simulation and go directly to function calls
    // (AJAX has issues in cron context with nonce verification)
    echo "<strong>Igny8 CRON HANDLER: Skipping AJAX simulation (cron context issues)</strong><br>";
    echo "<strong>Igny8 CRON HANDLER: Using direct function calls</strong><br>";
    
    $created = [];
    $skipped = [];
    $failed = [];
    
    foreach ($idea_ids as $idea_id) {
        echo "<strong>Igny8 CRON HANDLER: Processing idea ID: " . $idea_id . "</strong><br>";
        $result = igny8_create_task_from_idea($idea_id);
        
        if ($result['success']) {
            if (!empty($result['task_id'])) {
                $created[] = $result['task_id'];
                echo "<strong>Igny8 CRON HANDLER: SUCCESS - Created task ID: " . $result['task_id'] . "</strong><br>";
            } else {
                $skipped[] = $idea_id;
                echo "<strong>Igny8 CRON HANDLER: SKIPPED - " . $result['message'] . "</strong><br>";
            }
        } else {
            $failed[] = $idea_id;
            echo "<strong>Igny8 CRON HANDLER: FAILED - " . $result['message'] . "</strong><br>";
        }
    }
    
    // Update metrics for processed ideas
    foreach ($idea_ids as $idea_id) {
        igny8_update_idea_metrics($idea_id);
    }
    
    $created_count = count($created);
    $skipped_count = count($skipped);
    $failed_count = count($failed);
    
    echo "<strong>Igny8 CRON HANDLER: DIRECT SUCCESS - Tasks created: " . $created_count . ", Skipped: " . $skipped_count . ", Failed: " . $failed_count . "</strong><br>";
    igny8_log_ai_event('Auto Queue Complete', 'planner', 'auto_queue', 'success', 'Automated queueing completed (direct)', 'Tasks created: ' . $created_count . ', Skipped: ' . $skipped_count . ', Failed: ' . $failed_count);
    
    // Set global variables for detailed logging
    $GLOBALS['igny8_cron_processed_count'] = $created_count;
    $GLOBALS['igny8_cron_result_details'] = "Processed {$created_count} ideas, created {$created_count} tasks";
    
    echo "<strong>Igny8 CRON HANDLER: auto_queue completed</strong><br>";
    echo "</div>"; // Close the handler div
    
    // Restore error reporting
    error_reporting($old_error_reporting);
}

/**
 * Auto Generate Content Cron Handler
 * 
 * Automatically generates content from queued tasks.
 */
function igny8_auto_generate_content_cron_handler() {
    // Suppress PHP warnings for model rates in cron context
    $old_error_reporting = error_reporting();
    error_reporting($old_error_reporting & ~E_WARNING);
    
    echo "<div style='background:#e8f4fd;padding:10px;margin:5px;border:1px solid #2196F3;'>";
    echo "<strong>Igny8 CRON HANDLER: auto_generate_content started</strong><br>";
    error_log("Igny8 CRON HANDLER: auto_generate_content started");
    
    // Check if automation is enabled via cron settings
    echo "<strong>Igny8 CRON HANDLER: Checking if automation is enabled</strong><br>";
    $cron_settings = get_option('igny8_cron_settings', []);
    $job_settings = $cron_settings['igny8_auto_generate_content_cron'] ?? [];
    $auto_content_enabled = $job_settings['enabled'] ?? false;
    echo "<strong>Igny8 CRON HANDLER: auto_content_enabled =</strong> " . ($auto_content_enabled ? 'enabled' : 'disabled') . "<br>";
    
    if (!$auto_content_enabled) {
        echo "<strong>Igny8 CRON HANDLER: Automation disabled, exiting</strong><br>";
        error_log("Igny8 CRON HANDLER: auto_generate_content automation disabled");
        echo "</div>";
        return;
    }
    echo "<strong>Igny8 CRON HANDLER: Automation enabled, continuing</strong><br>";
    
    // Check if AI mode is enabled
    echo "<strong>Igny8 CRON HANDLER: Checking AI mode</strong><br>";
    $writer_mode = igny8_get_ai_setting('writer_mode', 'manual');
    echo "<strong>Igny8 CRON HANDLER: writer_mode =</strong> " . $writer_mode . "<br>";
    
    if ($writer_mode !== 'ai') {
        echo "<strong>Igny8 CRON HANDLER: AI mode disabled, exiting</strong><br>";
        error_log("Igny8 CRON HANDLER: AI mode disabled");
        echo "</div>";
        return;
    }
    echo "<strong>Igny8 CRON HANDLER: AI mode enabled, continuing</strong><br>";
    
    global $wpdb;
    echo "<strong>Igny8 CRON HANDLER: Database connection established</strong><br>";
    
    // Get queued tasks (use dynamic limit from settings)
    $limit = $GLOBALS['igny8_cron_limit'] ?? null;
    if ($limit === null) {
        // Try to get limit from Smart Automation Jobs table directly
        $cron_limits = get_option('igny8_cron_limits', []);
        $limit = $cron_limits['igny8_auto_generate_content_cron'] ?? null;
        
        if ($limit === null) {
            error_log('Igny8 Auto Generate Content Cron: No limit set in Smart Automation Jobs table');
            $GLOBALS['igny8_cron_processed_count'] = 0;
            $GLOBALS['igny8_cron_result_details'] = "FAILED: No limit set in Smart Automation Jobs table";
            return;
        }
        
        echo "<strong>Igny8 CRON HANDLER: Using limit from Smart Automation Jobs table: $limit</strong><br>";
    }
    echo "<strong>Igny8 CRON HANDLER: Querying queued tasks (limit: $limit)</strong><br>";
    $queued_tasks = $wpdb->get_results("
        SELECT id FROM {$wpdb->prefix}igny8_tasks 
        WHERE status = 'queued'
        LIMIT $limit
    ");
    
    echo "<strong>Igny8 CRON HANDLER: Found</strong> " . count($queued_tasks) . " queued tasks<br>";
    
    if (empty($queued_tasks)) {
        echo "<strong>Igny8 CRON HANDLER: No queued tasks found, exiting</strong><br>";
        igny8_log_ai_event('Auto Generate Content Skipped', 'writer', 'auto_generate_content', 'info', 'No queued tasks found', 'All tasks are already processed');
        echo "</div>";
        return;
    }
    
    $task_ids = array_column($queued_tasks, 'id');
    echo "<strong>Igny8 CRON HANDLER: Processing</strong> " . count($task_ids) . " tasks<br>";
    
    // Log automation start
    echo "<strong>Igny8 CRON HANDLER: Logging automation start</strong><br>";
    igny8_log_ai_event('Auto Generate Content Started', 'writer', 'auto_generate_content', 'info', 'Starting automated content generation', 'Tasks: ' . count($task_ids));
    
    // Set up user context for permissions
    echo "<strong>Igny8 CRON HANDLER: Setting up user context</strong><br>";
    if (!current_user_can('manage_options')) {
        // Get admin user for cron context
        $admin_users = get_users(['role' => 'administrator', 'number' => 1]);
        if (!empty($admin_users)) {
            wp_set_current_user($admin_users[0]->ID);
            echo "<strong>Igny8 CRON HANDLER: Set admin user context for permissions</strong><br>";
        }
    }
    
    $completed = 0;
    $failed = 0;
    
    foreach ($task_ids as $task_id) {
        echo "<h3 style='color: #2196F3; border-bottom: 2px solid #2196F3; padding: 10px 0; margin: 20px 0 10px 0;'>📋 SECTION 1: PROCESSING TASK " . $task_id . "</h3>";
        echo "<strong>Igny8 CRON HANDLER: Processing task ID: " . $task_id . "</strong><br>";
        echo "<strong>Igny8 CRON HANDLER: Sending to AI for content generation...</strong><br>";
        
        // Log AI request initiation
        igny8_log_ai_event('AI Request Initiated', 'writer', 'auto_content_generation', 'info', 'Starting AI content generation', 'Task ID: ' . $task_id);
        
        // Get AI configuration for logging
        $api_key = get_option('igny8_api_key');
        $model = get_option('igny8_model', 'gpt-4.1');
        
        // Log AI request details
        echo "<strong>Igny8 CRON HANDLER: AI Request Details - Model: " . $model . "</strong><br>";
        echo "<strong>Igny8 CRON HANDLER: API Key Status: " . (empty($api_key) ? 'Missing' : 'Configured') . "</strong><br>";
        igny8_log_ai_event('AI Request Details', 'writer', 'auto_content_generation', 'info', 'AI request configuration', 'Model: ' . $model . ', API Key: ' . (empty($api_key) ? 'Missing' : 'Configured'));
        
        // Log the actual AI request being made
        echo "<strong>Igny8 CRON HANDLER: Making AI API call to OpenAI...</strong><br>";
        igny8_log_ai_event('AI API Call', 'writer', 'auto_content_generation', 'info', 'Calling OpenAI API', 'Model: ' . $model . ', Task: ' . $task_id);
        
        // Simulate AJAX request to content generation function
        $_POST['task_id'] = $task_id;
        $_POST['nonce'] = wp_create_nonce('igny8_writer_settings');
        
        // Capture the response from AI call
        ob_start();
        igny8_ajax_ai_generate_content();
        $ai_response = ob_get_clean();
        
        // Log AI response
        echo "<strong>Igny8 CRON HANDLER: AI Response received</strong><br>";
        echo "<strong>Igny8 CRON HANDLER: Response Length: " . strlen($ai_response) . " characters</strong><br>";
        igny8_log_ai_event('AI Response Received', 'writer', 'auto_content_generation', 'info', 'AI processing completed', 'Response captured for task: ' . $task_id);
        
        // Parse the AI response to extract success/error status
        $json_response = null;
        $response_status = 'unknown';
        $error_message = '';
        
        // Try multiple methods to extract JSON from response
        if (preg_match('/\{.*\}/s', $ai_response, $matches)) {
            $json_response = json_decode($matches[0], true);
        }
        
        // If no JSON found, try to detect response type from content
        if (!$json_response) {
            if (strpos($ai_response, 'success') !== false && strpos($ai_response, 'true') !== false) {
                $response_status = 'success';
                echo "<strong>Igny8 CRON HANDLER: ✅ AI Response - SUCCESS (detected from content)</strong><br>";
                igny8_log_ai_event('AI Response Success', 'writer', 'auto_content_generation', 'success', 'AI content generation successful', 'Task ID: ' . $task_id);
            } elseif (strpos($ai_response, 'error') !== false || strpos($ai_response, 'failed') !== false) {
                $response_status = 'error';
                $error_message = 'Error detected in response content';
                echo "<strong>Igny8 CRON HANDLER: ❌ AI Response - FAILED (detected from content)</strong><br>";
                echo "<strong>Igny8 CRON HANDLER: Error: " . $error_message . "</strong><br>";
                igny8_log_ai_event('AI Response Failed', 'writer', 'auto_content_generation', 'error', 'AI content generation failed', 'Task ID: ' . $task_id . ', Error: ' . $error_message);
            } else {
                $response_status = 'unknown';
                echo "<strong>Igny8 CRON HANDLER: ⚠️ AI Response - UNKNOWN FORMAT</strong><br>";
                igny8_log_ai_event('AI Response Unknown', 'writer', 'auto_content_generation', 'warning', 'AI response format not recognized', 'Task ID: ' . $task_id . ', Raw response: ' . substr($ai_response, 0, 200));
            }
        } else {
            // JSON response found, parse it
            if (isset($json_response['success']) && $json_response['success']) {
                $response_status = 'success';
                echo "<strong>Igny8 CRON HANDLER: ✅ AI Response - SUCCESS (JSON parsed)</strong><br>";
                igny8_log_ai_event('AI Response Success', 'writer', 'auto_content_generation', 'success', 'AI content generation successful', 'Task ID: ' . $task_id);
            } else {
                $response_status = 'error';
                $error_message = $json_response['data']['message'] ?? $json_response['message'] ?? 'Unknown error';
                echo "<strong>Igny8 CRON HANDLER: ❌ AI Response - FAILED (JSON parsed)</strong><br>";
                echo "<strong>Igny8 CRON HANDLER: Error: " . $error_message . "</strong><br>";
                igny8_log_ai_event('AI Response Failed', 'writer', 'auto_content_generation', 'error', 'AI content generation failed', 'Task ID: ' . $task_id . ', Error: ' . $error_message);
            }
        }
        
        // Log response details for debugging
        echo "<strong>Igny8 CRON HANDLER: Response Status: " . $response_status . "</strong><br>";
        echo "<strong>Igny8 CRON HANDLER: Response Length: " . strlen($ai_response) . " characters</strong><br>";
        igny8_log_ai_event('AI Response Analysis', 'writer', 'auto_content_generation', 'info', 'Response analysis completed', 'Status: ' . $response_status . ', Length: ' . strlen($ai_response) . ', Task: ' . $task_id);
        
        // Get the actual post ID from the most recently created post by this user
        $recent_posts = get_posts([
            'post_type' => 'post',
            'post_status' => 'draft',
            'author' => get_current_user_id(),
            'numberposts' => 1,
            'orderby' => 'date',
            'order' => 'DESC'
        ]);
        
        $actual_post_id = !empty($recent_posts) ? $recent_posts[0]->ID : null;
        
        $response = ['success' => true, 'data' => ['post_id' => $actual_post_id]];
        
        if ($response && $response['success']) {
            echo "<strong>Igny8 CRON HANDLER: ✅ AI Response received successfully</strong><br>";
            
            echo "<h3 style='color: #4CAF50; border-bottom: 2px solid #4CAF50; padding: 10px 0; margin: 20px 0 10px 0;'>🔧 SECTION 2: PROCESSING AI RESPONSE & SAVING DATA</h3>";
            echo "<strong>Igny8 CRON HANDLER: Processing AI response data...</strong><br>";
            
            // The detailed field processing logs will come from igny8_create_post_from_ai_response function
            // which already has all the debugging output we added
            
            echo "<h3 style='color: #FF9800; border-bottom: 2px solid #FF9800; padding: 10px 0; margin: 20px 0 10px 0;'>✅ SECTION 3: FINAL VERIFICATION & SUCCESS SUMMARY</h3>";
            
            if (!empty($response['data']['post_id'])) {
                $post_id = $response['data']['post_id'];
                echo "<strong>Igny8 CRON HANDLER: ✅ Post Created Successfully - ID: " . $post_id . "</strong><br>";
                echo "<strong>Igny8 CRON HANDLER: Checking fields for post ID: " . $post_id . "</strong><br>";
                
                // Verify all saved fields
                $meta_title = get_post_meta($post_id, '_igny8_meta_title', true);
                $meta_description = get_post_meta($post_id, '_igny8_meta_description', true);
                $primary_keywords = get_post_meta($post_id, '_igny8_primary_keywords', true);
                $secondary_keywords = get_post_meta($post_id, '_igny8_secondary_keywords', true);
                $word_count = get_post_meta($post_id, '_igny8_word_count', true);
                
                echo "<strong>Igny8 CRON HANDLER: ✅ Meta Title: " . (!empty($meta_title) ? 'Saved' : 'Missing') . "</strong><br>";
                echo "<strong>Igny8 CRON HANDLER: ✅ Meta Description: " . (!empty($meta_description) ? 'Saved' : 'Missing') . "</strong><br>";
                echo "<strong>Igny8 CRON HANDLER: ✅ Primary Keywords: " . (!empty($primary_keywords) ? 'Saved' : 'Missing') . "</strong><br>";
                echo "<strong>Igny8 CRON HANDLER: ✅ Secondary Keywords: " . (!empty($secondary_keywords) ? 'Saved' : 'Missing') . "</strong><br>";
                echo "<strong>Igny8 CRON HANDLER: ✅ Word Count: " . (!empty($word_count) ? 'Saved' : 'Missing') . "</strong><br>";
                
                // Verify taxonomies
                $cluster_terms = wp_get_object_terms($post_id, 'clusters');
                $sector_terms = wp_get_object_terms($post_id, 'sectors');
                
                echo "<strong>Igny8 CRON HANDLER: ✅ Cluster Taxonomy: " . (!empty($cluster_terms) && !is_wp_error($cluster_terms) ? 'Associated' : 'Not Associated') . "</strong><br>";
                echo "<strong>Igny8 CRON HANDLER: ✅ Sector Taxonomy: " . (!empty($sector_terms) && !is_wp_error($sector_terms) ? 'Associated' : 'Not Associated') . "</strong><br>";
                
                // Verify Yoast meta
                $yoast_meta = get_post_meta($post_id, '_yoast_wpseo_metadesc', true);
                echo "<strong>Igny8 CRON HANDLER: ✅ Yoast Meta Description: " . (!empty($yoast_meta) ? 'Saved' : 'Missing') . "</strong><br>";
                
                $completed++;
                echo "<strong style='color: #4CAF50; font-size: 16px;'>🎉 TASK " . $task_id . " COMPLETED SUCCESSFULLY!</strong><br>";
            } else {
                echo "<strong style='color: #f44336;'>❌ Post creation failed - No post ID returned</strong><br>";
                $failed++;
            }
        } else {
            $failed++;
            $error_msg = $response['data']['message'] ?? 'Unknown error';
            echo "<strong style='color: #f44336;'>❌ TASK " . $task_id . " FAILED: " . $error_msg . "</strong><br>";
        }
        
        echo "<hr style='margin: 30px 0; border: 1px solid #ddd;'>";
    }
    
    echo "<strong>Igny8 CRON HANDLER: Content generation completed - Success: " . $completed . ", Failed: " . $failed . "</strong><br>";
    
    if ($completed > 0) {
        igny8_log_ai_event('Auto Generate Content Complete', 'writer', 'auto_generate_content', 'success', 'Automated content generation completed', 'Content generated: ' . $completed . ', Failed: ' . $failed);
        
        // Set global variables for detailed logging
        $GLOBALS['igny8_cron_processed_count'] = $completed;
        $GLOBALS['igny8_cron_result_details'] = "Processed {$completed} tasks, generated {$completed} content pieces";
        echo "<strong>Igny8 AUTO GENERATE CONTENT HANDLER: Set global variables - processed_count: $completed, result_details: Processed {$completed} tasks, generated {$completed} content pieces</strong><br>";
    } else {
        igny8_log_ai_event('Auto Generate Content Failed', 'writer', 'auto_generate_content', 'error', 'Automated content generation failed', 'No content was generated');
        
        // Set global variables for detailed logging (failure case)
        $GLOBALS['igny8_cron_processed_count'] = 0;
        $GLOBALS['igny8_cron_result_details'] = "FAILED: No content was generated";
    }
    
    echo "<strong>Igny8 CRON HANDLER: auto_generate_content completed</strong><br>";
    echo "</div>"; // Close the handler div
    
    // Restore error reporting
    error_reporting($old_error_reporting);
}

/**
 * Auto Publish Drafts Cron Handler
 * 
 * Automatically publishes completed draft posts.
 */
function igny8_auto_publish_drafts_cron_handler() {
    echo "<div style='background:#e8f4fd;padding:10px;margin:5px;border:1px solid #2196F3;'>";
    echo "<strong>Igny8 CRON HANDLER: auto_publish_drafts started</strong><br>";
    error_log("Igny8 CRON HANDLER: auto_publish_drafts started");
    
    // Check if automation is enabled via cron settings
    echo "<strong>Igny8 CRON HANDLER: Checking if automation is enabled</strong><br>";
    $cron_settings = get_option('igny8_cron_settings', []);
    $job_settings = $cron_settings['igny8_auto_publish_drafts_cron'] ?? [];
    $auto_publish_enabled = $job_settings['enabled'] ?? false;
    echo "<strong>Igny8 CRON HANDLER: auto_publish_enabled =</strong> " . ($auto_publish_enabled ? 'enabled' : 'disabled') . "<br>";
    
    if (!$auto_publish_enabled) {
        echo "<strong>Igny8 CRON HANDLER: Automation disabled, exiting</strong><br>";
        error_log("Igny8 CRON HANDLER: auto_publish_drafts automation disabled");
        echo "</div>";
        return;
    }
    echo "<strong>Igny8 CRON HANDLER: Automation enabled, continuing</strong><br>";
    
    global $wpdb;
    
    // Get completed tasks with published content (use admin limit)
    $limit = $GLOBALS['igny8_cron_limit'] ?? null;
    if ($limit === null) {
        // Try to get limit from Smart Automation Jobs table directly
        $cron_limits = get_option('igny8_cron_limits', []);
        $limit = $cron_limits['igny8_auto_publish_drafts_cron'] ?? null;
        
        if ($limit === null) {
            error_log('Igny8 Auto Publish Drafts Cron: No limit set in Smart Automation Jobs table');
            $GLOBALS['igny8_cron_processed_count'] = 0;
            $GLOBALS['igny8_cron_result_details'] = "FAILED: No limit set in Smart Automation Jobs table";
            return;
        }
        
        echo "<strong>Igny8 CRON HANDLER: Using limit from Smart Automation Jobs table: $limit</strong><br>";
    }
    echo "<strong>Igny8 CRON HANDLER: Querying completed tasks with draft posts (limit: $limit)</strong><br>";
    $completed_tasks = $wpdb->get_results("
        SELECT t.id, t.assigned_post_id FROM {$wpdb->prefix}igny8_tasks t
        INNER JOIN {$wpdb->posts} p ON t.assigned_post_id = p.ID
        WHERE t.status = 'completed' 
        AND p.post_status = 'draft'
        LIMIT $limit
    ");
    
    echo "<strong>Igny8 CRON HANDLER: Found</strong> " . count($completed_tasks) . " completed tasks with draft posts<br>";
    
    if (empty($completed_tasks)) {
        echo "<strong>Igny8 CRON HANDLER: No draft posts found, exiting</strong><br>";
        igny8_log_ai_event('Auto Publish Drafts Skipped', 'writer', 'auto_publish_drafts', 'info', 'No draft posts found', 'All content is already published');
        echo "</div>";
        return;
    }
    
    $post_ids = array_column($completed_tasks, 'assigned_post_id');
    
    // Log automation start
    igny8_log_ai_event('Auto Publish Drafts Started', 'writer', 'auto_publish_drafts', 'info', 'Starting automated publishing', 'Posts: ' . count($post_ids));
    
    $published = 0;
    echo "<strong>Igny8 CRON HANDLER: Processing</strong> " . count($post_ids) . " draft posts<br>";
    
    foreach ($post_ids as $post_id) {
        echo "<strong>Igny8 CRON HANDLER: Publishing post ID: " . $post_id . "</strong><br>";
        $result = wp_update_post([
            'ID' => $post_id,
            'post_status' => 'publish'
        ]);
        
        if (!is_wp_error($result) && $result) {
            $published++;
            echo "<strong>Igny8 CRON HANDLER: ✅ SUCCESS - Published post ID: " . $post_id . "</strong><br>";
        } else {
            echo "<strong>Igny8 CRON HANDLER: ❌ FAILED - Could not publish post ID: " . $post_id . "</strong><br>";
        }
    }
    
    echo "<strong>Igny8 CRON HANDLER: Publishing completed - Published: " . $published . " posts</strong><br>";
    
    if ($published > 0) {
        igny8_log_ai_event('Auto Publish Drafts Complete', 'writer', 'auto_publish_drafts', 'success', 'Automated publishing completed', 'Posts published: ' . $published);
        
        // Set global variables for detailed logging
        $GLOBALS['igny8_cron_processed_count'] = $published;
        $GLOBALS['igny8_cron_result_details'] = "Processed {$published} drafts, published {$published} posts";
    } else {
        igny8_log_ai_event('Auto Publish Drafts Failed', 'writer', 'auto_publish_drafts', 'error', 'Automated publishing failed', 'No posts were published');
        
        // Set global variables for detailed logging (failure case)
        $GLOBALS['igny8_cron_processed_count'] = 0;
        $GLOBALS['igny8_cron_result_details'] = "FAILED: No posts were published";
    }
    
    echo "<strong>Igny8 CRON HANDLER: auto_publish_drafts completed</strong><br>";
    echo "</div>"; // Close the handler div
}

/**
 * Auto Optimizer Cron Handler (NEW)
 * 
 * Automatically optimizes content and keywords.
 */
function igny8_auto_optimizer_cron_handler() {
    // Check if automation is enabled
    if (igny8_get_ai_setting('auto_optimizer_enabled', 'disabled') !== 'enabled') {
        return;
    }
    
    global $wpdb;
    
    // Get posts that need optimization (use admin limit)
    $limit = $GLOBALS['igny8_cron_limit'] ?? null;
    if ($limit === null) {
        // Try to get limit from Smart Automation Jobs table directly
        $cron_limits = get_option('igny8_cron_limits', []);
        $limit = $cron_limits['igny8_auto_optimizer_cron'] ?? null;
        
        if ($limit === null) {
            error_log('Igny8 Auto Optimizer Cron: No limit set in Smart Automation Jobs table');
            $GLOBALS['igny8_cron_processed_count'] = 0;
            $GLOBALS['igny8_cron_result_details'] = "FAILED: No limit set in Smart Automation Jobs table";
            return;
        }
        
        echo "<strong>Igny8 CRON HANDLER: Using limit from Smart Automation Jobs table: $limit</strong><br>";
    }
    $posts_to_optimize = $wpdb->get_results("
        SELECT p.ID, p.post_title 
        FROM {$wpdb->posts} p
        LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = 'igny8_optimized'
        WHERE p.post_status = 'publish'
        AND p.post_type IN ('post', 'page')
        AND pm.meta_value IS NULL
        LIMIT $limit
    ");
    
    if (empty($posts_to_optimize)) {
        igny8_log_ai_event('Auto Optimizer Skipped', 'optimizer', 'auto_optimizer', 'info', 'No posts need optimization', 'All posts are already optimized');
        return;
    }
    
    $post_ids = array_column($posts_to_optimize, 'ID');
    
    // Log automation start
    igny8_log_ai_event('Auto Optimizer Started', 'optimizer', 'auto_optimizer', 'info', 'Starting automated optimization', 'Posts: ' . count($post_ids));
    
    $optimized = 0;
    foreach ($post_ids as $post_id) {
        // Run optimization process
        $result = igny8_optimize_post_content($post_id);
        if ($result['success']) {
            $optimized++;
            // Mark as optimized
            update_post_meta($post_id, 'igny8_optimized', current_time('mysql'));
        }
    }
    
    if ($optimized > 0) {
        igny8_log_ai_event('Auto Optimizer Complete', 'optimizer', 'auto_optimizer', 'success', 'Automated optimization completed', 'Posts optimized: ' . $optimized);
    } else {
        igny8_log_ai_event('Auto Optimizer Failed', 'optimizer', 'auto_optimizer', 'error', 'Automated optimization failed', 'No posts were optimized');
    }
}

/**
 * Auto Recalc Cron Handler (NEW)
 * 
 * Automatically recalculates metrics for all entities.
 */
function igny8_auto_recalc_cron_handler() {
    global $wpdb;
    
    // Get entities that need recalculation
    $limit = $GLOBALS['igny8_cron_limit'] ?? null;
    if ($limit === null) {
        error_log('Igny8 Auto Cluster Cron: No limit set in Smart Automation Jobs table');
        $GLOBALS['igny8_cron_processed_count'] = 0;
        $GLOBALS['igny8_cron_result_details'] = "FAILED: No limit set in Smart Automation Jobs table";
        return;
    }
    $clusters_to_recalc = $wpdb->get_results("
        SELECT id FROM {$wpdb->prefix}igny8_clusters 
        WHERE status = 'active'
        LIMIT $limit
    ");
    
    $tasks_to_recalc = $wpdb->get_results("
        SELECT id FROM {$wpdb->prefix}igny8_tasks 
        WHERE status IN ('completed', 'in_progress')
        LIMIT $limit
    ");
    
    $total_recalc = count($clusters_to_recalc) + count($tasks_to_recalc);
    
    if ($total_recalc === 0) {
        igny8_log_ai_event('Auto Recalc Skipped', 'analytics', 'auto_recalc', 'info', 'No entities need recalculation', 'All metrics are up to date');
        return;
    }
    
    // Log automation start
    igny8_log_ai_event('Auto Recalc Started', 'analytics', 'auto_recalc', 'info', 'Starting automated recalculation', 'Entities: ' . $total_recalc);
    
    $recalculated = 0;
    
    // Recalculate cluster metrics
    foreach ($clusters_to_recalc as $cluster) {
        igny8_update_cluster_metrics($cluster->id);
        $recalculated++;
    }
    
    // Recalculate task metrics
    foreach ($tasks_to_recalc as $task) {
        igny8_update_task_metrics($task->id);
        $recalculated++;
    }
    
    if ($recalculated > 0) {
        igny8_log_ai_event('Auto Recalc Complete', 'analytics', 'auto_recalc', 'success', 'Automated recalculation completed', 'Entities recalculated: ' . $recalculated);
    } else {
        igny8_log_ai_event('Auto Recalc Failed', 'analytics', 'auto_recalc', 'error', 'Automated recalculation failed', 'No entities were recalculated');
    }
}

/**
 * Health Check Cron Handler (NEW)
 * 
 * Performs system health checks, cleanup, and dependency validation.
 */
function igny8_health_check_cron_handler() {
    global $wpdb;
    
    $health_issues = [];
    $cleanup_performed = [];
    $dependency_issues = [];
    
    // Check for orphaned records
    $orphaned_keywords = $wpdb->get_var("
        SELECT COUNT(*) FROM {$wpdb->prefix}igny8_keywords k
        LEFT JOIN {$wpdb->prefix}igny8_clusters c ON k.cluster_id = c.id
        WHERE k.cluster_id IS NOT NULL AND k.cluster_id > 0 AND c.id IS NULL
    ");
    
    if ($orphaned_keywords > 0) {
        $health_issues[] = "Found $orphaned_keywords orphaned keywords";
        
        // Clean up orphaned keywords
        $wpdb->query("
            UPDATE {$wpdb->prefix}igny8_keywords 
            SET cluster_id = NULL 
            WHERE cluster_id IS NOT NULL 
            AND cluster_id > 0 
            AND cluster_id NOT IN (SELECT id FROM {$wpdb->prefix}igny8_clusters)
        ");
        $cleanup_performed[] = "Cleaned up $orphaned_keywords orphaned keywords";
    }
    
    // Check for old failed AI tasks
    $old_failed_tasks = $wpdb->get_var("
        SELECT COUNT(*) FROM {$wpdb->prefix}igny8_ai_queue 
        WHERE status = 'failed' 
        AND created_at < DATE_SUB(NOW(), INTERVAL 7 DAY)
    ");
    
    if ($old_failed_tasks > 0) {
        $wpdb->query("
            DELETE FROM {$wpdb->prefix}igny8_ai_queue 
            WHERE status = 'failed' 
            AND created_at < DATE_SUB(NOW(), INTERVAL 7 DAY)
        ");
        $cleanup_performed[] = "Cleaned up $old_failed_tasks old failed AI tasks";
    }
    
    // Dependency validation - check execution order
    $dependency_issues = igny8_validate_automation_dependencies();
    
    // Check database table sizes
    $table_sizes = [];
    $tables = ['igny8_keywords', 'igny8_clusters', 'igny8_content_ideas', 'igny8_tasks', 'igny8_ai_queue'];
    
    foreach ($tables as $table) {
        $count = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}$table");
        $table_sizes[$table] = $count;
    }
    
    // Log health check results
    if (empty($health_issues) && empty($dependency_issues)) {
        igny8_log_ai_event('Health Check Passed', 'system', 'health_check', 'success', 'System health check completed', 'No issues found');
    } else {
        $all_issues = array_merge($health_issues, $dependency_issues);
        igny8_log_ai_event('Health Check Issues', 'system', 'health_check', 'warning', 'Health check found issues', implode('; ', $all_issues));
    }
    
    if (!empty($cleanup_performed)) {
        igny8_log_ai_event('Health Check Cleanup', 'system', 'health_check', 'info', 'Cleanup performed', implode('; ', $cleanup_performed));
    }
    
    // Store health metrics
    update_option('igny8_health_metrics', [
        'last_check' => current_time('mysql'),
        'table_sizes' => $table_sizes,
        'issues_found' => count($health_issues),
        'dependency_issues' => count($dependency_issues),
        'cleanup_performed' => count($cleanup_performed)
    ]);
}

/**
 * Validate automation dependencies and execution order
 */
function igny8_validate_automation_dependencies() {
    $issues = [];
    global $wpdb;
    
    // Check if clusters exist but no ideas generated
    $clusters_without_ideas = $wpdb->get_var("
        SELECT COUNT(*) FROM {$wpdb->prefix}igny8_clusters c
        LEFT JOIN {$wpdb->prefix}igny8_content_ideas i ON c.id = i.keyword_cluster_id
        WHERE c.status = 'active' AND i.id IS NULL
    ");
    
    if ($clusters_without_ideas > 0) {
        $issues[] = "Found $clusters_without_ideas clusters without content ideas (auto_generate_ideas may be disabled)";
    }
    
    // Check if ideas exist but not queued
    $ideas_not_queued = $wpdb->get_var("
        SELECT COUNT(*) FROM {$wpdb->prefix}igny8_content_ideas i
        LEFT JOIN {$wpdb->prefix}igny8_tasks t ON i.id = t.idea_id
        WHERE i.status = 'new' AND t.id IS NULL
    ");
    
    if ($ideas_not_queued > 0) {
        $issues[] = "Found $ideas_not_queued ideas not queued for content generation (auto_queue may be disabled)";
    }
    
    // Check if tasks exist but no content generated
    $tasks_without_content = $wpdb->get_var("
        SELECT COUNT(*) FROM {$wpdb->prefix}igny8_tasks t
        LEFT JOIN {$wpdb->posts} p ON t.assigned_post_id = p.ID
        WHERE t.status = 'queued' AND (p.ID IS NULL OR p.post_content = '')
    ");
    
    if ($tasks_without_content > 0) {
        $issues[] = "Found $tasks_without_content tasks without content (auto_generate_content may be disabled)";
    }
    
    // Check if content exists but no images
    $content_without_images = $wpdb->get_var("
        SELECT COUNT(*) FROM {$wpdb->posts} p
        LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = 'igny8_has_ai_image'
        WHERE p.post_status = 'publish' 
        AND p.post_type IN ('post', 'page')
        AND p.post_content LIKE '%[image%'
        AND pm.meta_value IS NULL
    ");
    
    if ($content_without_images > 0) {
        $issues[] = "Found $content_without_images posts with image placeholders but no AI images (auto_generate_images may be disabled)";
    }
    
    // Check if content exists but not published
    $drafts_not_published = $wpdb->get_var("
        SELECT COUNT(*) FROM {$wpdb->posts} p
        INNER JOIN {$wpdb->prefix}igny8_tasks t ON p.ID = t.assigned_post_id
        WHERE p.post_status = 'draft' 
        AND t.status = 'completed'
    ");
    
    if ($drafts_not_published > 0) {
        $issues[] = "Found $drafts_not_published completed tasks with unpublished content (auto_publish_drafts may be disabled)";
    }
    
    return $issues;
}

/**
 * Auto Generate Images Cron Handler (NEW)
 * 
 * Automatically generates images for content that needs them.
 */
function igny8_auto_generate_images_cron_handler() {
    // Check if automation is enabled
    if (igny8_get_ai_setting('auto_generate_images_enabled', 'disabled') !== 'enabled') {
        return;
    }
    
    // Check if AI mode is enabled
    if (igny8_get_ai_setting('writer_mode', 'manual') !== 'ai') {
        return;
    }
    
    global $wpdb;
    
    // Get posts that need images (use admin limit)
    $limit = $GLOBALS['igny8_cron_limit'] ?? null;
    if ($limit === null) {
        // Try to get limit from Smart Automation Jobs table directly
        $cron_limits = get_option('igny8_cron_limits', []);
        $limit = $cron_limits['igny8_auto_generate_images_cron'] ?? null;
        
        if ($limit === null) {
            error_log('Igny8 Auto Generate Images Cron: No limit set in Smart Automation Jobs table');
            $GLOBALS['igny8_cron_processed_count'] = 0;
            $GLOBALS['igny8_cron_result_details'] = "FAILED: No limit set in Smart Automation Jobs table";
            return;
        }
        
        echo "<strong>Igny8 CRON HANDLER: Using limit from Smart Automation Jobs table: $limit</strong><br>";
    }
    $posts_needing_images = $wpdb->get_results("
        SELECT p.ID, p.post_title, p.post_content
        FROM {$wpdb->posts} p
        LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = 'igny8_has_ai_image'
        WHERE p.post_status = 'publish'
        AND p.post_type IN ('post', 'page')
        AND pm.meta_value IS NULL
        AND p.post_content LIKE '%[image%'
        LIMIT $limit
    ");
    
    if (empty($posts_needing_images)) {
        igny8_log_ai_event('Auto Generate Images Skipped', 'writer', 'auto_generate_images', 'info', 'No posts need images', 'All posts already have images or no image placeholders found');
        return;
    }
    
    $post_ids = array_column($posts_needing_images, 'ID');
    
    // Log automation start
    igny8_log_ai_event('Auto Generate Images Started', 'writer', 'auto_generate_images', 'info', 'Starting automated image generation', 'Posts: ' . count($post_ids));
    
    $generated = 0;
    foreach ($post_ids as $post_id) {
        // Run image generation process
        $result = igny8_generate_post_images($post_id);
        if ($result['success']) {
            $generated++;
            // Mark as having AI image
            update_post_meta($post_id, 'igny8_has_ai_image', current_time('mysql'));
        }
    }
    
    if ($generated > 0) {
        igny8_log_ai_event('Auto Generate Images Complete', 'writer', 'auto_generate_images', 'success', 'Automated image generation completed', 'Images generated: ' . $generated);
        
        // Set global variables for detailed logging
        $GLOBALS['igny8_cron_processed_count'] = $generated;
        $GLOBALS['igny8_cron_result_details'] = "Processed {$generated} posts, generated {$generated} images";
    } else {
        igny8_log_ai_event('Auto Generate Images Failed', 'writer', 'auto_generate_images', 'error', 'Automated image generation failed', 'No images were generated');
        
        // Set global variables for detailed logging (failure case)
        $GLOBALS['igny8_cron_processed_count'] = 0;
        $GLOBALS['igny8_cron_result_details'] = "FAILED: No images were generated";
    }
}

/**
 * Test Cron Endpoint Handler (NEW)
 * 
 * Simple test handler for cron endpoint validation.
 */
function igny8_test_cron_endpoint() {
    igny8_log_ai_event('Cron Test', 'system', 'test_endpoint', 'info', 'Cron endpoint test executed', 'Test successful at ' . current_time('mysql'));
    
    // Return success response for external cron
    if (defined('DOING_CRON') && DOING_CRON) {
        return [
            'success' => true,
            'message' => 'Igny8 CRON endpoint is working',
            'timestamp' => current_time('mysql'),
            'server' => $_SERVER['SERVER_NAME'] ?? 'unknown'
        ];
    }
}

/**
 * Safe taxonomy term creation with duplicate prevention
 * 
 * @param string $term_name Term name
 * @param string $taxonomy Taxonomy name
 * @param array $args Additional arguments
 * @return int|WP_Error Term ID or error
 */
function igny8_safe_create_term($term_name, $taxonomy, $args = []) {
    // Check if term already exists
    $existing_term = get_term_by('name', $term_name, $taxonomy);
    if ($existing_term) {
        return $existing_term->term_id;
    }
    
    // Create term with duplicate slug prevention
    $slug = sanitize_title($term_name);
    $counter = 1;
    $original_slug = $slug;
    
    while (term_exists($slug, $taxonomy)) {
        $slug = $original_slug . '-' . $counter;
        $counter++;
    }
    
    $args['slug'] = $slug;
    
    $result = wp_insert_term($term_name, $taxonomy, $args);
    
    if (is_wp_error($result)) {
        // If still error, try to get existing term by slug
        $existing = get_term_by('slug', $slug, $taxonomy);
        if ($existing) {
            return $existing->term_id;
        }
        return $result;
    }
    
    return $result['term_id'];
}

/**
 * Enhanced cluster term creation with safety checks
 * 
 * @param int $cluster_id Cluster ID
 * @return int|false Term ID or false on failure
 */
function igny8_safe_create_cluster_term($cluster_id) {
    global $wpdb;
    
    // Get cluster data
    $cluster = $wpdb->get_row($wpdb->prepare(
        "SELECT cluster_name, cluster_term_id FROM {$wpdb->prefix}igny8_clusters WHERE id = %d",
        $cluster_id
    ));
    
    if (!$cluster) {
        return false;
    }
    
    // Skip if already mapped
    if (!empty($cluster->cluster_term_id)) {
        return $cluster->cluster_term_id;
    }
    
    // Ensure taxonomy exists
    if (!taxonomy_exists('clusters') && function_exists('igny8_register_taxonomies')) {
        igny8_register_taxonomies();
    }
    
    // Create term safely
    $term_id = igny8_safe_create_term($cluster->cluster_name, 'clusters');
    
    if ($term_id && !is_wp_error($term_id)) {
        // Update cluster with term ID
        $wpdb->update(
            "{$wpdb->prefix}igny8_clusters",
            ['cluster_term_id' => $term_id],
            ['id' => $cluster_id],
            ['%d'],
            ['%d']
        );
        
        return $term_id;
    }
    
    return false;
}

// ===================================================================
// REGISTER CRON HOOKS
// ===================================================================

// Register all cron job hooks
add_action('igny8_auto_cluster_cron', 'igny8_auto_cluster_cron_handler');
add_action('igny8_auto_generate_ideas_cron', 'igny8_auto_generate_ideas_cron_handler');
add_action('igny8_auto_queue_cron', 'igny8_auto_queue_cron_handler');
add_action('igny8_auto_generate_content_cron', 'igny8_auto_generate_content_cron_handler');
add_action('igny8_auto_generate_images_cron', 'igny8_auto_generate_images_cron_handler');
add_action('igny8_auto_publish_drafts_cron', 'igny8_auto_publish_drafts_cron_handler');
add_action('igny8_process_ai_queue_cron', 'igny8_process_ai_queue_cron_handler');
add_action('igny8_auto_recalc_cron', 'igny8_auto_recalc_cron_handler');
add_action('igny8_auto_optimizer_cron', 'igny8_auto_optimizer_cron_handler');
add_action('igny8_health_check_cron', 'igny8_health_check_cron_handler');
