<?php
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

// Allow quick release-time hiding of the SEO Settings subtab.
// Set this constant to true in wp-config.php or the plugin bootstrap to enable hiding.
// If it's not defined by the environment, default to hiding for this release per request.
if (!defined('BLOGIBOT_HIDE_SEO_TAB')) {
    define('BLOGIBOT_HIDE_SEO_TAB', true);
}

use Blogibot\Dependencies\Parsedown;

// Include Toastr Helper
require_once __DIR__ . '/Components/Toastr/BlogiBotToastr.php';

// Include API Routes
require_once __DIR__ . '/API/Routes.php';

// Initialize Toastr
BlogiBotToastr::init();

// Minimal Blogibot loader: Only show AI Blog Dashboard in admin
add_action('admin_menu', function () {
    add_menu_page(
        'Blogibot',
        'Blogibot',
        'manage_options',
        'blogibot',
        function() {
            if (!current_user_can('manage_options')) wp_die('Unauthorized');
            include_once WP_PLUGIN_DIR . '/blogibot/src/AIBlog/Dashboard/Dashboard.php';
        },
        // Use the plugin main file as reference to reliably build the URL to assets
        plugins_url('assets/images/blogyboot_grayscale.png', __DIR__ . '/../blogibot.php'),
        26
    );
});


// Enqueue dashboard CSS/JS only for Blogibot admin page
add_action('admin_enqueue_scripts', function($hook) {
    if ($hook !== 'toplevel_page_blogibot') return;
    
    // Determine current tab and subtab
    $current_tab = isset($_GET['tab']) ? sanitize_key($_GET['tab']) : 'license';
    $current_subtab = isset($_GET['subtab']) ? sanitize_key($_GET['subtab']) : 'dashboard';
    
    // Always enqueue main dashboard styles and WordPress icons
    wp_enqueue_style('dashicons');
    wp_enqueue_style('blogibot-dashboard', plugins_url('../assets/css/aiblog/blog82ai-dashboard.css', __DIR__ . '/..'), [], '1.0.3');
    wp_enqueue_script('blogibot-dashboard', plugins_url('../assets/js/aiblog/blog82ai-dashboard.js', __DIR__ . '/..'), [], '1.0.0', true);
    
    // Enqueue shared modal system
    wp_enqueue_script('blog82ai-modal', plugins_url('../assets/js/shared/blog82ai-modal.js', __DIR__ . '/..'), [], '1.0.0', true);
    
    // Localize script with AJAX data
    wp_localize_script('blogibot-dashboard', 'blog82aiApiData', [
        'ajax_nonce' => wp_create_nonce('blog82ai_ajax_nonce'),
        'ajaxurl' => admin_url('admin-ajax.php')
    ]);
    
    // Localize feed nonce for feed operations
    wp_localize_script('blogibot-dashboard', 'blogibotFeed', [
        'ajax_url' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('blogibot_feed_nonce'),
    ]);
    
    // Enqueue tab-specific styles
    if ($current_tab === 'license') {
        $css_url = plugins_url('../assets/css/license/blog82ai-license.css', __DIR__ . '/..');
        
        wp_enqueue_style(
            'blog82ai-license',
            $css_url,
            [],
            '6.0.2'
        );
    } elseif ($current_tab === 'feed') {
        if ($current_subtab === 'dashboard') {
            wp_enqueue_style('blog82ai-feed-dashboard', plugins_url('../assets/css/feed/blog82ai-feed-dashboard.css', __DIR__ . '/..'), [], '1.0.0');
        } elseif ($current_subtab === 'add_feed_source') {
            wp_enqueue_style('blog82ai-add-feed-source', plugins_url('../assets/css/feed/blog82ai-add-feed-source.css', __DIR__ . '/..'), [], '1.0.0');
        } elseif ($current_subtab === 'manage_feeds') {
            wp_enqueue_style('blog82ai-manage-feed-source', plugins_url('../assets/css/feed/blog82ai-manage-feed-source.css', __DIR__ . '/..'), [], time());
            wp_enqueue_script('blog82ai-manage-feeds', plugins_url('../assets/js/feed/blog82ai-manage-feeds.js', __DIR__ . '/..'), ['jquery'], '1.0.0', true);
        } elseif ($current_subtab === 'fetched_posts') {
            wp_enqueue_style('blog82ai-fetch-posts-log', plugins_url('../assets/css/feed/blog82ai-fetch-posts-log.css', __DIR__ . '/..'), [], '1.0.0');
        }
        // Import Settings tab hidden for now - will be implemented in future version
        // } elseif ($current_subtab === 'import_settings') {
        //     wp_enqueue_style('blog82ai-import-settings', plugins_url('../assets/css/feed/blog82ai-import-settings.css', __DIR__ . '/..'), [], '1.0.0');
        // }
        // Add other feed subtab styles here as needed
    } else {
        // AI Blog tab - enqueue component-specific styles
        switch ($current_subtab) {
            case 'generate_new_blog':
                wp_enqueue_style('blog82ai-generate-new-blog', plugins_url('../assets/css/aiblog/blog82ai-generate-new-blog.css', __DIR__ . '/..'), [], '1.0.0');
                
                // Enqueue JavaScript for generate new blog
                wp_enqueue_script('jquery');
                
                // Enqueue reusable Toastr component first
                wp_enqueue_script(
                    'blogibot-toastr',
                    plugins_url('../assets/js/aiblog/toastr/toastr.js', __DIR__ . '/..'),
                    array('jquery'),
                    '1.0.0',
                    true
                );
                
                wp_enqueue_script(
                    'blogibot-blog-actions',
                    plugins_url('../assets/js/aiblog/generate-new-blog/blog-actions.js', __DIR__ . '/..'),
                    array('jquery', 'blogibot-toastr'),
                    '1.0.0',
                    true
                );
                
                wp_enqueue_script(
                    'blogibot-image-handler',
                    plugins_url('../assets/js/aiblog/generate-new-blog/blog-image-handler.js', __DIR__ . '/..'),
                    array('jquery', 'blogibot-toastr'),
                    '1.0.0',
                    true
                );
                
                wp_enqueue_script(
                    'blogibot-blog-generation',
                    plugins_url('../assets/js/aiblog/generate-new-blog/blog-generation.js', __DIR__ . '/..'),
                    array('jquery', 'blogibot-toastr', 'blogibot-blog-actions', 'blogibot-image-handler'),
                    '1.0.0',
                    true
                );
                
                // Localize script
                wp_localize_script(
                    'blogibot-blog-generation',
                    'blogibotAjax',
                    array(
                        'ajaxurl' => admin_url('admin-ajax.php'),
                        'nonces' => array(
                            'generate_blog' => wp_create_nonce('blogibot_generate_blog'),
                            'save_draft' => wp_create_nonce('blogibot_save_draft'),
                            'publish_post' => wp_create_nonce('blogibot_publish_post'),
                            'generate_image' => wp_create_nonce('blogibot_generate_image'),
                            'content_scan' => wp_create_nonce('blogibot_content_scan')
                        )
                    )
                );
                break;
            case 'scheduled_blogs':
                wp_enqueue_style(
                    'blog82ai-scheduled-blogs',
                    plugins_url('../assets/css/aiblog/blog82ai-scheduled-blogs.css', __DIR__ . '/..'),
                    [],
                    '1.2.3'
                );
                
                // Enqueue scheduled blogs JavaScript
                wp_enqueue_script(
                    'blog82ai-scheduled-blogs-js',
                    plugins_url('../assets/js/aiblog/scheduled-blogs.js', __DIR__ . '/..'),
                    array('jquery'),
                    '1.0.0',
                    true
                );
                
                // Localize script with AJAX data
                wp_localize_script(
                    'blog82ai-scheduled-blogs-js',
                    'scheduledBlogsAjax',
                    array(
                        'ajaxurl' => admin_url('admin-ajax.php'),
                        'nonce' => wp_create_nonce('blog82ai_scheduled_blog_nonce')
                    )
                );
                break;
            case 'generated_blogs_history':
                wp_enqueue_style(
                    'blog82ai-generated-blog-history',
                    plugins_url('../assets/css/aiblog/blog82ai-generated-blog-history.css', __DIR__ . '/..'),
                    [],
                    '1.0.1'
                );
                break;
            case 'site_content_analyzer':
                // Enqueue Site Content Analyzer CSS
                wp_enqueue_style(
                    'blog82ai-site-content-analyzer',
                    plugins_url('../assets/css/aiblog/site-content-analyzer.css', __DIR__ . '/..'),
                    [],
                    '1.0.0'
                );
                
                // Enqueue shared modal system
                wp_enqueue_script(
                    'blog82ai-modal',
                    plugins_url('../assets/js/shared/blog82ai-modal.js', __DIR__ . '/..'),
                    array('jquery'),
                    '1.0.0',
                    true
                );
                
                // Enqueue toastr for notifications
                wp_enqueue_script(
                    'blogibot-toastr',
                    plugins_url('../assets/js/aiblog/toastr/toastr.js', __DIR__ . '/..'),
                    array('jquery'),
                    '1.0.0',
                    true
                );
                
                // Enqueue toastr CSS
                wp_enqueue_style(
                    'blogibot-toastr-css',
                    plugins_url('../assets/js/aiblog/toastr/toastr.css', __DIR__ . '/..'),
                    [],
                    '1.0.0'
                );
                
                // Enqueue Site Content Analyzer JS
                wp_enqueue_script(
                    'blog82ai-site-content-analyzer',
                    plugins_url('../assets/js/aiblog/site-content-analyzer.js', __DIR__ . '/..'),
                    array('jquery', 'blog82ai-modal', 'blogibot-toastr'),
                    '1.0.0',
                    true
                );
                
                // Localize script for content analyzer
                wp_localize_script(
                    'blog82ai-site-content-analyzer',
                    'blogibotAjax',
                    array(
                        'ajaxurl' => admin_url('admin-ajax.php'),
                        'nonces' => array(
                            'content_scan' => wp_create_nonce('blogibot_content_scan')
                        )
                    )
                );
                break;
            case 'seo_settings':
                wp_enqueue_style(
                    'blog82ai-seo-settings',
                    plugins_url('../assets/css/aiblog/blog82ai-seo-settings.css', __DIR__ . '/..'),
                    [],
                    '1.0.0'
                );
                break;
            default:
                // Dashboard
                wp_enqueue_style('blog82ai-dashboard', plugins_url('../assets/css/aiblog/blog82ai-dashboard.css', __DIR__ . '/..'), [], '1.0.0');
                break;
        }
    }
});

// Backwards compatibility redirect for older direct links to generated blog history
add_action('admin_init', function() {
    if (!is_admin()) return;
    if (!empty($_GET['page']) && $_GET['page'] === 'blogibot-generated-blog-history') {
        // Preserve known filter params
        $allowed = ['filter_category','filter_status','filter_date','search_blogs','paged'];
        $q = [];
        foreach ($allowed as $k) {
            if (isset($_GET[$k]) && $_GET[$k] !== '') {
                $q[$k] = sanitize_text_field($_GET[$k]);
            }
        }
        $q['page'] = 'blogibot';
        $q['tab'] = 'ai_blog';
        $q['subtab'] = 'generated_blogs_history';

        $url = admin_url('admin.php') . '?' . http_build_query($q);
        wp_safe_redirect($url, 302);
        exit;
    }
});

// Temporary debug logging: record generated history filter accesses
add_action('admin_init', function() {
    if (!is_admin()) return;
    $is_main_page = (!empty($_GET['page']) && $_GET['page'] === 'blogibot');
    $is_target_tab = (isset($_GET['tab']) && $_GET['tab'] === 'ai_blog' && isset($_GET['subtab']) && $_GET['subtab'] === 'generated_blogs_history');
    if ($is_main_page && $is_target_tab && !empty($_GET['filter_category'])) {
        $user_id = get_current_user_id();
        $can_manage = current_user_can('manage_options') ? 'yes' : 'no';
        $uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field($_SERVER['REQUEST_URI']) : 'unknown';
        error_log("Blog82AI: GeneratedBlogHistory filter access - user_id={$user_id} can_manage={$can_manage} uri={$uri} filter_category=" . sanitize_text_field($_GET['filter_category']));
    }
});

// AJAX handler for refreshing dashboard widgets
add_action('wp_ajax_blog82ai_refresh_dashboard', function() {
    // Verify nonce
    if (!wp_verify_nonce($_POST['security'] ?? '', 'blog82ai_ajax_nonce')) {
        wp_die(json_encode(['success' => false, 'data' => ['message' => 'Security check failed']]));
    }
    
    // Check user capabilities
    if (!current_user_can('manage_options')) {
        wp_die(json_encode(['success' => false, 'data' => ['message' => 'Insufficient permissions']]));
    }
    
    // Load dashboard widgets class
    require_once WP_PLUGIN_DIR . '/blogibot/src/AIBlog/Dashboard/DashboardWidgets.php';
    
    // Get fresh data
    $metrics = Blog82AI_Dashboard_Widgets::get_metrics();
    $categories = Blog82AI_Dashboard_Widgets::get_top_categories();
    $keyphrases = Blog82AI_Dashboard_Widgets::get_top_keyphrases();
    $system_status = Blog82AI_Dashboard_Widgets::get_system_status();
    $recent_blogs = Blog82AI_Dashboard_Widgets::get_recent_blogs(5);
    
    wp_die(json_encode([
        'success' => true,
        'data' => [
            'metrics' => $metrics,
            'categories' => $categories,
            'keyphrases' => $keyphrases,
            'system_status' => $system_status,
            'recent_blogs' => $recent_blogs,
            'message' => 'Dashboard data refreshed successfully'
        ]
    ]));
});

// AJAX handler for creating sample data
add_action('wp_ajax_blog82ai_create_sample_data', function() {
    // Verify nonce
    if (!wp_verify_nonce($_POST['security'] ?? '', 'blog82ai_ajax_nonce')) {
        wp_die(json_encode(['success' => false, 'data' => ['message' => 'Security check failed']]));
    }
    
    // Check user capabilities
    if (!current_user_can('manage_options')) {
        wp_die(json_encode(['success' => false, 'data' => ['message' => 'Insufficient permissions']]));
    }
    
    // Only allow in debug mode
    if (!defined('WP_DEBUG') || !WP_DEBUG) {
        wp_die(json_encode(['success' => false, 'data' => ['message' => 'Sample data creation only available in debug mode']]));
    }
    
    // Load dashboard widgets class
    require_once WP_PLUGIN_DIR . '/blogibot/src/AIBlog/Dashboard/DashboardWidgets.php';
    
    // Create sample data
    Blog82AI_Dashboard_Widgets::create_sample_data();
    
    wp_die(json_encode([
        'success' => true,
        'data' => [
            'message' => 'Sample AI blog data created successfully'
        ]
    ]));
});

// AJAX handler for pausing schedule
add_action('wp_ajax_blog82ai_pause_schedule', function() {
    // Verify nonce
    if (!wp_verify_nonce($_POST['nonce'] ?? '', 'blog82ai_scheduled_blog_nonce')) {
        wp_send_json_error('Security check failed');
    }
    
    // Check user capabilities
    if (!current_user_can('manage_options')) {
        wp_send_json_error('Insufficient permissions');
    }
    
    $schedule_id = sanitize_text_field($_POST['schedule_id'] ?? '');
    if (empty($schedule_id)) {
        wp_send_json_error('Schedule ID required');
    }
    
    // Get schedule details
    $scheduled = get_option('blog82ai_scheduled_blogs', []);
    $target_schedule = null;
    $schedule_index = -1;
    
    foreach ($scheduled as $index => $item) {
        if ($item['id'] === $schedule_id) {
            $target_schedule = $item;
            $schedule_index = $index;
            break;
        }
    }
    
    if (!$target_schedule) {
        wp_send_json_error('Schedule not found');
    }
    
    // Update schedule status
    $scheduled[$schedule_index]['status'] = 'paused';
    
    // Clear WordPress cron event
    $args = [
        'category' => $target_schedule['category'],
        'schedule_id' => $schedule_id
    ];
    
    wp_clear_scheduled_hook('blogibot_generate_blog', $args);
    
    // Save updated schedule
    if (update_option('blog82ai_scheduled_blogs', $scheduled)) {
        wp_send_json_success('Schedule paused successfully');
    } else {
        wp_send_json_error('Failed to pause schedule');
    }
});

// AJAX handler for resuming schedule
add_action('wp_ajax_blog82ai_resume_schedule', function() {
    // Verify nonce
    if (!wp_verify_nonce($_POST['nonce'] ?? '', 'blog82ai_scheduled_blog_nonce')) {
        wp_send_json_error('Security check failed');
    }
    
    // Check user capabilities
    if (!current_user_can('manage_options')) {
        wp_send_json_error('Insufficient permissions');
    }
    
    $schedule_id = sanitize_text_field($_POST['schedule_id'] ?? '');
    if (empty($schedule_id)) {
        wp_send_json_error('Schedule ID required');
    }
    
    // Get schedule details
    $scheduled = get_option('blog82ai_scheduled_blogs', []);
    $target_schedule = null;
    $schedule_index = -1;
    
    foreach ($scheduled as $index => $item) {
        if ($item['id'] === $schedule_id) {
            $target_schedule = $item;
            $schedule_index = $index;
            break;
        }
    }
    
    if (!$target_schedule) {
        wp_send_json_error('Schedule not found');
    }
    
    // Update schedule status
    $scheduled[$schedule_index]['status'] = 'active';
    
    // Calculate next run time
    $run_time = $target_schedule['run_time'];
    $now = current_time('timestamp');
    $today_date = date('Y-m-d', $now);
    $next_run = strtotime($today_date . ' ' . $run_time);
    
    if ($next_run <= $now) {
        $next_run = strtotime('+1 day', $next_run);
    }
    
    // Schedule WordPress cron event
    $args = [
        'category' => $target_schedule['category'],
        'schedule_id' => $schedule_id
    ];
    
    wp_schedule_event($next_run, 'blog82ai_daily', 'blogibot_generate_blog', $args);
    
    // Save updated schedule
    if (update_option('blog82ai_scheduled_blogs', $scheduled)) {
        wp_send_json_success('Schedule resumed successfully');
    } else {
        wp_send_json_error('Failed to resume schedule');
    }
});

// AJAX handler for deleting schedule
add_action('wp_ajax_blog82ai_delete_schedule', function() {
    // Verify nonce
    if (!wp_verify_nonce($_POST['nonce'] ?? '', 'blog82ai_scheduled_blog_nonce')) {
        wp_send_json_error('Security check failed');
    }
    
    // Check user capabilities
    if (!current_user_can('manage_options')) {
        wp_send_json_error('Insufficient permissions');
    }
    
    $schedule_id = sanitize_text_field($_POST['schedule_id'] ?? '');
    if (empty($schedule_id)) {
        wp_send_json_error('Schedule ID required');
    }
    
    // Get schedule details
    $scheduled = get_option('blog82ai_scheduled_blogs', []);
    $target_schedule = null;
    $schedule_index = -1;
    
    foreach ($scheduled as $index => $item) {
        if ($item['id'] === $schedule_id) {
            $target_schedule = $item;
            $schedule_index = $index;
            break;
        }
    }
    
    if (!$target_schedule) {
        wp_send_json_error('Schedule not found');
    }
    
    // Clear WordPress cron event
    $args = [
        'category' => $target_schedule['category'],
        'schedule_id' => $schedule_id
    ];
    
    wp_clear_scheduled_hook('blogibot_generate_blog', $args);
    
    // Remove from schedules array
    array_splice($scheduled, $schedule_index, 1);
    
    // Save updated schedules
    if (update_option('blog82ai_scheduled_blogs', $scheduled)) {
        wp_send_json_success('Schedule deleted successfully');
    } else {
        wp_send_json_error('Failed to delete schedule');
    }
});

// AJAX handler for creating schedule
add_action('wp_ajax_blog82ai_create_schedule', function() {
    // Verify nonce
    if (!wp_verify_nonce($_POST['nonce'] ?? '', 'blog82ai_scheduled_blog_nonce')) {
        wp_send_json_error('Security check failed');
    }
    
    // Check user capabilities
    if (!current_user_can('manage_options')) {
        wp_send_json_error('Insufficient permissions');
    }
    
    $category = sanitize_text_field($_POST['category'] ?? '');
    $start_date = sanitize_text_field($_POST['start_date'] ?? '');
    $run_time = sanitize_text_field($_POST['run_time'] ?? '');
    $frequency = sanitize_text_field($_POST['frequency'] ?? 'daily');
    
    if (empty($category) || empty($start_date) || empty($run_time)) {
        wp_send_json_error('All fields are required');
    }
    
    // Load scheduled blog widgets class
    require_once WP_PLUGIN_DIR . '/blogibot/src/AIBlog/ScheduledBlog/ScheduledBlogWidgets.php';
    
    // Check if category already has a schedule
    if (Blog82AI_ScheduledBlog_Widgets::category_has_schedule($category)) {
        wp_send_json_error('This category already has a scheduled blog');
    }
    
    // Create new schedule
    $scheduled = get_option('blog82ai_scheduled_blogs', []);
    $schedule_id = 'schedule_' . time() . '_' . rand(1000, 9999);
    $timestamp = strtotime($start_date . ' ' . $run_time);
    
    $new_schedule = [
        'id' => $schedule_id,
        'category' => $category,
        'start_date' => $start_date,
        'time' => $start_date, // For legacy compatibility
        'run_time' => $run_time,
        'frequency' => $frequency,
        'status' => 'active',
        'created_at' => current_time('mysql'),
        'timestamp' => $timestamp
    ];
    
    // Schedule WordPress cron event
    $cron_frequency = ($frequency === 'daily') ? 'blog82ai_daily' : 'daily'; // Default to daily if not supported
    $args = [
        'category' => $category,
        'schedule_id' => $schedule_id
    ];
    
    if (!wp_next_scheduled('blogibot_generate_blog', $args)) {
        wp_schedule_event($timestamp, $cron_frequency, 'blogibot_generate_blog', $args);
    }
    
    $scheduled[] = $new_schedule;
    
    if (update_option('blog82ai_scheduled_blogs', $scheduled)) {
        wp_send_json_success('Schedule created successfully');
    } else {
        wp_send_json_error('Failed to create schedule');
    }
});

// AJAX handler for fetch now
add_action('wp_ajax_blog82ai_fetch_now', function() {
    error_log('Blog82AI: Fetch now handler called - POST data: ' . print_r($_POST, true));
    
    // Verify nonce
    if (!wp_verify_nonce($_POST['nonce'] ?? '', 'blog82ai_scheduled_blog_nonce')) {
        error_log('Blog82AI: Fetch now - Security check failed');
        wp_send_json_error('Security check failed');
    }
    
    // Check user capabilities
    if (!current_user_can('manage_options')) {
        error_log('Blog82AI: Fetch now - Insufficient permissions');
        wp_send_json_error('Insufficient permissions');
    }
    
    $category = sanitize_text_field($_POST['category'] ?? '');
    if (empty($category)) {
        error_log('Blog82AI: Fetch now - Category required');
        wp_send_json_error('Category required');
    }
    
    error_log('Blog82AI: Fetch now initiated for category: ' . $category);
    
    try {
        // Check license first
        // Ensure LicenseManager is loaded (some contexts may not have it autoloaded)
        if (!class_exists('Blog82AI_License_Manager')) {
            require_once WP_PLUGIN_DIR . '/blogibot/src/License/LicenseManager.php';
        }
        $license_data = Blog82AI_License_Manager::get_license_data();
        if (empty($license_data['license_key']) || $license_data['status'] !== 'active') {
            error_log('Blog82AI: Fetch now - Invalid or inactive license');
            wp_send_json_error('License not active. Please activate your license first.');
            return;
        }
        
        // Generate a unique schedule ID for this manual generation
        $manual_schedule_id = 'fetch_now_' . time() . '_' . wp_generate_password(6, false);
        
        // Prepare arguments for blog generation using simple format
        $args = [
            'category' => $category,
            'schedule_id' => $manual_schedule_id
        ];
        
        error_log('Blog82AI: Calling blog generation handler with args: ' . json_encode($args));
        
        // Call the blog generation handler directly (this uses /generate-blog endpoint)
        $result = blogibot_generate_blog_handler($args);
        
        // Check if result indicates success or failure
        if ($result === false) {
            error_log('Blog82AI: Blog generation handler returned false');
            wp_send_json_error('Blog generation failed. Please check your license and API connectivity.');
            return;
        }

        // If handler returned structured post data, return that to the UI for preview
        if (is_array($result) && isset($result['post_id'])) {
            error_log('Blog82AI: Fetch now completed and returned post data for category: ' . $category);
            wp_send_json_success($result);
            return;
        }

        error_log('Blog82AI: Fetch now completed successfully for category: ' . $category);
        wp_send_json_success('Blog post generated successfully for category: ' . $category);
        
    } catch (\Throwable $e) {
        error_log('Blog82AI: Fetch now error: ' . $e->getMessage() . "\n" . $e->getTraceAsString());
        $msg = 'Error generating blog post: ' . $e->getMessage();
        if (defined('WP_DEBUG') && WP_DEBUG) {
            wp_send_json_error(['message' => $msg, 'trace' => $e->getTraceAsString()]);
        } else {
            wp_send_json_error($msg);
        }
    }
});

// AJAX handler for bulk actions
add_action('wp_ajax_blog82ai_bulk_action', function() {
    // Verify nonce
    if (!wp_verify_nonce($_POST['nonce'] ?? '', 'blog82ai_scheduled_blog_nonce')) {
        wp_send_json_error('Security check failed');
    }

    // Check user capabilities
    if (!current_user_can('manage_options')) {
        wp_send_json_error('Insufficient permissions');
    }

    try {
        $action = sanitize_text_field($_POST['bulk_action'] ?? '');

        // Normalize schedule IDs: accept array or comma-separated string
        $raw_schedule_ids = $_POST['schedule_ids'] ?? [];
        if (!is_array($raw_schedule_ids)) {
            if (is_string($raw_schedule_ids)) {
                $raw_schedule_ids = array_filter(array_map('trim', explode(',', $raw_schedule_ids)));
            } else {
                $raw_schedule_ids = [];
            }
        }
        $schedule_ids = array_map('sanitize_text_field', $raw_schedule_ids);

        if (empty($action) || empty($schedule_ids)) {
            wp_send_json_error('Action and schedule IDs required');
        }

        // Load scheduled blog widgets class
        require_once WP_PLUGIN_DIR . '/blogibot/src/AIBlog/ScheduledBlog/ScheduledBlogWidgets.php';

        $success_count = 0;
        $total_count = count($schedule_ids);

        foreach ($schedule_ids as $schedule_id) {
            $result = false;

            switch ($action) {
                case 'pause':
                    $result = Blog82AI_ScheduledBlog_Widgets::update_schedule_status($schedule_id, 'paused');
                    break;
                case 'resume':
                    $result = Blog82AI_ScheduledBlog_Widgets::update_schedule_status($schedule_id, 'active');
                    break;
                case 'delete':
                    $result = Blog82AI_ScheduledBlog_Widgets::delete_schedule($schedule_id);
                    break;
            }

            if ($result) $success_count++;
        }

        if ($success_count === $total_count) {
            wp_send_json_success("All {$total_count} schedules processed successfully");
        } else {
            wp_send_json_error("Only {$success_count} of {$total_count} schedules processed successfully");
        }
    } catch (\Throwable $e) {
        error_log('Blog82AI: Bulk action error: ' . $e->getMessage() . "\n" . $e->getTraceAsString());
        $errMsg = 'Bulk action failed: ' . $e->getMessage();
        if (defined('WP_DEBUG') && WP_DEBUG) {
            wp_send_json_error(['message' => $errMsg, 'trace' => $e->getTraceAsString()]);
        } else {
            wp_send_json_error($errMsg);
        }
    }
});

// AJAX handler for updating schedule
add_action('wp_ajax_blog82ai_update_schedule', function() {
    // Verify nonce
    if (!wp_verify_nonce($_POST['nonce'] ?? '', 'blog82ai_scheduled_blog_nonce')) {
        wp_send_json_error('Security check failed');
    }
    
    // Check user capabilities
    if (!current_user_can('manage_options')) {
        wp_send_json_error('Insufficient permissions');
    }
    
    $schedule_id = sanitize_text_field($_POST['schedule_id'] ?? '');
    $category = sanitize_text_field($_POST['category'] ?? '');
    $start_date = sanitize_text_field($_POST['start_date'] ?? '');
    $run_time = sanitize_text_field($_POST['run_time'] ?? '');
    $frequency = sanitize_text_field($_POST['frequency'] ?? '');
    
    if (empty($schedule_id) || empty($category) || empty($start_date) || empty($run_time)) {
        wp_send_json_error('All fields are required');
    }
    
    // Load scheduled blog widgets class
    require_once WP_PLUGIN_DIR . '/blogibot/src/AIBlog/ScheduledBlog/ScheduledBlogWidgets.php';
    
    $result = Blog82AI_ScheduledBlog_Widgets::update_schedule($schedule_id, [
        'category' => $category,
        'start_date' => $start_date,
        'run_time' => $run_time,
        'frequency' => $frequency
    ]);
    
    if ($result) {
        wp_send_json_success('Schedule updated successfully');
    } else {
        wp_send_json_error('Failed to update schedule');
    }
});

// AJAX handler for refreshing schedule components
add_action('wp_ajax_blog82ai_refresh_schedules', function() {
    // Verify nonce
    if (!wp_verify_nonce($_POST['nonce'] ?? '', 'blog82ai_scheduled_blog_nonce')) {
        wp_send_json_error('Security check failed');
    }
    
    // Check user capabilities
    if (!current_user_can('manage_options')) {
        wp_send_json_error('Insufficient permissions');
    }
    
    // Load scheduled blog widgets class
    require_once WP_PLUGIN_DIR . '/blogibot/src/AIBlog/ScheduledBlog/ScheduledBlogWidgets.php';
    
    // Get fresh data
    $schedules = Blog82AI_ScheduledBlog_Widgets::get_all_schedules();
    $categories = Blog82AI_ScheduledBlog_Widgets::get_categories_for_dropdown();
    $stats = Blog82AI_ScheduledBlog_Widgets::get_schedule_stats();
    
    // Debug logging
    error_log('Refresh schedules called - Stats: ' . json_encode($stats));
    error_log('Refresh schedules called - Schedule count: ' . count($schedules));
    error_log('Refresh schedules called - Category count: ' . count($categories));
    
    wp_send_json_success([
        'schedules' => $schedules,
        'categories' => $categories,
        'stats' => $stats
    ]);
});

// AJAX handlers for Generated Blog History
add_action('wp_ajax_regenerate_blog_title', function() {
    if (!wp_verify_nonce($_POST['_wpnonce'] ?? '', 'regenerate_blog_title')) {
        wp_send_json_error('Security check failed');
        return;
    }
    
    if (!current_user_can('edit_posts')) {
        wp_send_json_error('Insufficient permissions');
        return;
    }
    
    $blog_id = intval($_POST['blog_id'] ?? 0);
    $new_title = isset($_POST['new_title']) ? sanitize_text_field($_POST['new_title']) : '';

    if (!$blog_id || !get_post($blog_id)) {
        wp_send_json_error('Invalid blog ID');
        return;
    }

    // Defensive check: ensure this is an existing post type we expect
    $post_obj = get_post($blog_id);
    if (!$post_obj || $post_obj->post_type !== 'post') {
        wp_send_json_error('Target is not a standard post');
        return;
    }

    // Log incoming regenerate request for debugging
    error_log(sprintf('Blog82AI: regenerate_blog_title called - blog_id=%d new_title="%s" user_id=%d', $blog_id, $new_title, get_current_user_id()));

    if (empty($new_title)) {
        wp_send_json_error('No new title provided');
        return;
    }

    // Use WP_Error on failure to get detailed errors
    $result = wp_update_post([
        'ID' => $blog_id,
        'post_title' => $new_title
    ], true);

    if (is_wp_error($result)) {
        error_log('Blog82AI: regenerate_blog_title - wp_update_post error: ' . $result->get_error_message());
        wp_send_json_error('Failed to update title: ' . $result->get_error_message());
        return;
    }

    // wp_update_post returns the post ID on success; verify it matches
    if (intval($result) !== intval($blog_id)) {
        error_log(sprintf('Blog82AI: regenerate_blog_title - unexpected wp_update_post return value: %s (expected %d)', print_r($result, true), $blog_id));
    }

    wp_send_json_success([ 'message' => 'Title updated successfully', 'new_title' => $new_title ]);
});

// AJAX handler to call external regenerate API and return suggested titles
add_action('wp_ajax_blog82ai_fetch_regenerated_titles', function() {
    // Verify nonce for AJAX operations
    if (!wp_verify_nonce($_POST['security'] ?? '', 'blog82ai_ajax_nonce')) {
        wp_send_json_error('Security check failed');
        return;
    }

    if (!current_user_can('edit_posts')) {
        wp_send_json_error('Insufficient permissions');
        return;
    }

    $blog_id = intval($_POST['blog_id'] ?? 0);
    $title = sanitize_text_field($_POST['title'] ?? '');

    if (!$blog_id || !get_post($blog_id)) {
        wp_send_json_error('Invalid blog ID');
        return;
    }

    // Load LicenseManager to obtain API credentials
    if (!class_exists('Blog82AI_License_Manager')) {
        require_once WP_PLUGIN_DIR . '/blogibot/src/License/LicenseManager.php';
    }
    
    // Check if user has access to title regeneration feature
    if (!Blog82AI_License_Manager::has_feature_access('title_regeneration')) {
        wp_send_json_error('Title regeneration is only available for paid users. Please upgrade your plan to access this feature.');
        return;
    }
    
    $license_data = Blog82AI_License_Manager::get_license_data();
    $api_key = $license_data['license_key'] ?? '';
    $domain = $license_data['domain'] ?? '';

    if (empty($api_key) || empty($domain) || ($license_data['status'] ?? '') !== 'active') {
        wp_send_json_error('License not active or missing credentials');
        return;
    }

    // Use centralized API Routes
    $api_url = Blog82AI_API_Routes::get_endpoint_url('blog_regenerate');

    $payload = [
        'api_key' => $api_key,
        'domain' => $domain,
        'action' => 'title',
        'title' => $title
    ];

    $response = wp_remote_post($api_url, [
        'headers' => ['Content-Type' => 'application/json'],
        'body' => json_encode($payload),
        'timeout' => 30,
        'sslverify' => false
    ]);

    if (is_wp_error($response)) {
        wp_send_json_error('API request failed: ' . $response->get_error_message());
        return;
    }

    $body = wp_remote_retrieve_body($response);
    // Dev-only: log the raw API response when WP_DEBUG is enabled to help debugging
    if (defined('WP_DEBUG') && WP_DEBUG) {
        try {
            $clipped = is_string($body) ? substr($body, 0, 20000) : '';
            error_log('Blog82AI: raw regenerate-blog API response for blog_id=' . intval($blog_id) . ' => ' . $clipped);
        } catch (\Throwable $e) {
            error_log('Blog82AI: failed to log raw API response: ' . $e->getMessage());
        }
    }
    // Also store the full raw response in a transient for quick admin retrieval during debugging
    if (defined('WP_DEBUG') && WP_DEBUG) {
        try {
            set_transient('blog82ai_last_api_response', $body, 300); // keep 5 minutes
        } catch (\Throwable $e) {
            error_log('Blog82AI: failed to set transient for raw API response: ' . $e->getMessage());
        }
    }
    $data = json_decode($body, true);

    if (!$data || !isset($data['generated_titles']) || !is_array($data['generated_titles'])) {
        // Fallback: create simple variations locally so UI can continue to function during development
        $fallback = [];
        $fallback[] = $title . ' — Mastering the Essentials';
        $fallback[] = 'Background Processing in Laravel: ' . $title;
        $fallback[] = 'Boost Laravel Performance: ' . $title;
        $fallback[] = $title . ' — A Practical Guide';
        $fallback[] = 'Unlocking Laravel: ' . $title;

        wp_send_json_success(['generated_titles' => $fallback, 'original_title' => $title, 'note' => 'Fallback suggestions used']);
        return;
    }

    wp_send_json_success(['generated_titles' => $data['generated_titles'], 'original_title' => $data['original_title'] ?? $title]);
});

// AJAX handler to call external regenerate API and return regenerated content for a post
add_action('wp_ajax_blog82ai_fetch_regenerated_content', function() {
    // Verify nonce for AJAX operations
    if (!wp_verify_nonce($_POST['security'] ?? '', 'blog82ai_ajax_nonce')) {
        wp_send_json_error('Security check failed');
        return;
    }

    if (!current_user_can('edit_posts')) {
        wp_send_json_error('Insufficient permissions');
        return;
    }

    $blog_id = intval($_POST['blog_id'] ?? 0);
    $title = sanitize_text_field($_POST['title'] ?? '');

    if (!$blog_id || !get_post($blog_id)) {
        wp_send_json_error('Invalid blog ID');
        return;
    }

    // Load LicenseManager to obtain API credentials
    if (!class_exists('Blog82AI_License_Manager')) {
        require_once WP_PLUGIN_DIR . '/blogibot/src/License/LicenseManager.php';
    }
    
    // Check if user has access to content regeneration feature
    if (!Blog82AI_License_Manager::has_feature_access('content_regeneration')) {
        wp_send_json_error('Content regeneration is only available for paid users. Please upgrade your plan to access this feature.');
        return;
    }
    
    $license_data = Blog82AI_License_Manager::get_license_data();
    $api_key = $license_data['license_key'] ?? '';
    $domain = $license_data['domain'] ?? '';

    if (empty($api_key) || empty($domain) || ($license_data['status'] ?? '') !== 'active') {
        wp_send_json_error('License not active or missing credentials');
        return;
    }

    // Use centralized API Routes
    $api_url = Blog82AI_API_Routes::get_endpoint_url('blog_regenerate');

    $payload = [
        'api_key' => $api_key,
        'domain' => $domain,
        'action' => 'content',
        'title' => $title
    ];

    $response = wp_remote_post($api_url, [
        'headers' => ['Content-Type' => 'application/json'],
        'body' => json_encode($payload),
        'timeout' => 60,
        'sslverify' => false
    ]);

    if (is_wp_error($response)) {
        wp_send_json_error('API request failed: ' . $response->get_error_message());
        return;
    }

    $body = wp_remote_retrieve_body($response);
    $http_code = wp_remote_retrieve_response_code($response);
    $data = json_decode($body, true);

    // Check for API errors
    if ($http_code !== 200) {
        wp_send_json_error('API returned error code: ' . $http_code);
        return;
    }

    if (!is_array($data)) {
        wp_send_json_error('API returned invalid JSON');
        return;
    }

    // Check if API returned an error status
    if (isset($data['status']) && $data['status'] !== 'success') {
        $error_msg = $data['message'] ?? 'API returned error status';
        wp_send_json_error($error_msg);
        return;
    }

    // Extract blog_content from data.blog_content
    if (!isset($data['data']) || !is_array($data['data'])) {
        wp_send_json_error('API response missing data object');
        return;
    }

    if (!isset($data['data']['blog_content']) || empty($data['data']['blog_content'])) {
        wp_send_json_error('API response missing blog_content');
        return;
    }

    $blog_content = $data['data']['blog_content'];
    $out = $data['data'];
    
    wp_send_json_success([
        'blog_content' => $blog_content,
        'meta_title' => $out['meta_title'] ?? $title,
        'meta_description' => $out['meta_description'] ?? '',
        'focus_keywords' => $out['focus_keywords'] ?? ($out['focus_keyphrase'] ?? ''),
        'tags' => is_array($out['tags'] ?? null) ? implode(',', $out['tags']) : ($out['tags'] ?? ''),
        'original_title' => $title
    ]);
});

// AJAX handler: Fetch regenerated image
add_action('wp_ajax_blog82ai_fetch_regenerated_image', function() {
    // Verify nonce for AJAX operations
    $nonce = $_POST['security'] ?? $_REQUEST['security'] ?? '';
    if (!wp_verify_nonce($nonce, 'blog82ai_ajax_nonce')) {
        wp_send_json_error('Security check failed');
        return;
    }

    if (!current_user_can('edit_posts')) {
        wp_send_json_error('Insufficient permissions');
        return;
    }

    $blog_id = intval($_POST['blog_id'] ?? 0);
    $title = sanitize_text_field($_POST['title'] ?? '');

    if (!$blog_id || !get_post($blog_id)) {
        wp_send_json_error('Invalid blog ID');
        return;
    }

    // Load LicenseManager to obtain API credentials and check feature access
    if (!class_exists('Blog82AI_License_Manager')) {
        require_once WP_PLUGIN_DIR . '/blogibot/src/License/LicenseManager.php';
    }
    
    // Check if user has access to image regeneration feature
    if (!Blog82AI_License_Manager::has_feature_access('image_regeneration')) {
        error_log('Blogibot: Free user attempted to regenerate image');
        wp_send_json_error('Image regeneration is only available for paid users. Please upgrade your plan.');
        return;
    }
    
    $license_data = Blog82AI_License_Manager::get_license_data();
    $api_key = $license_data['license_key'] ?? '';
    $domain = $license_data['domain'] ?? '';

    if (empty($api_key) || empty($domain) || ($license_data['status'] ?? '') !== 'active') {
        wp_send_json_error('License not active or missing credentials');
        return;
    }

    // Load API Routes class
    if (!class_exists('Blog82AI_API_Routes')) {
        require_once WP_PLUGIN_DIR . '/blogibot/src/API/Routes.php';
    }
    
    // Use centralized API Routes
    $api_url = Blog82AI_API_Routes::get_endpoint_url('blog_regenerate');

    $payload = [
        'api_key' => $api_key,
        'domain' => $domain,
        'action' => 'image',
        'title' => $title
    ];

    $response = wp_remote_post($api_url, [
        'headers' => ['Content-Type' => 'application/json'],
        'body' => json_encode($payload),
        'timeout' => 60,
        'sslverify' => false
    ]);

    if (is_wp_error($response)) {
        wp_send_json_error('API request failed: ' . $response->get_error_message());
        return;
    }

    $body = wp_remote_retrieve_body($response);
    $http_code = wp_remote_retrieve_response_code($response);

    // Check for API errors with specific messages
    if ($http_code !== 200) {
        // Try to parse error message from response body
        $error_data = json_decode($body, true);
        if (is_array($error_data) && isset($error_data['message'])) {
            wp_send_json_error($error_data['message']);
            return;
        }
        
        $error_messages = [
            429 => 'API rate limit exceeded. Please wait a few minutes and try again.',
            401 => 'API authentication failed. Please check your license key.',
            403 => 'API access forbidden. Please verify your license is active.',
            500 => 'API server error. Please try again later.',
            503 => 'API service temporarily unavailable. Please try again later.'
        ];
        
        $error_msg = $error_messages[$http_code] ?? 'API returned error code: ' . $http_code;
        wp_send_json_error($error_msg);
        return;
    }

    // Check if response is JSON
    $data = json_decode($body, true);
    
    if (!is_array($data)) {
        wp_send_json_error('Invalid JSON response from API');
        return;
    }
    
    // Check for API error status
    $status = isset($data['status']) ? strtolower($data['status']) : '';
    if ($status && $status !== 'success') {
        $error_msg = $data['message'] ?? 'API returned error status';
        wp_send_json_error($error_msg);
        return;
    }

    // API response structure for action=image:
    // {
    //   "image": {
    //     "description": "...",
    //     "mime_type": "image/png",
    //     "generated_at": "...",
    //     "model": "...",
    //     "base64_data": "..."
    //   }
    // }
    
    if (isset($data['image']) && is_array($data['image'])) {
        $image_info = $data['image'];
        $base64_data = $image_info['base64_data'] ?? '';
        
        if (empty($base64_data)) {
            wp_send_json_error('API response missing base64_data in image object');
            return;
        }
        
        $description = $image_info['description'] ?? $title;
        $mime_type = $image_info['mime_type'] ?? 'image/png';
        $filename = sanitize_file_name($title) . '-' . time() . '.png';
        
        wp_send_json_success([
            'image_url' => 'data:' . $mime_type . ';base64,' . $base64_data,
            'image_description' => $description,
            'mime_type' => $mime_type,
            'filename' => $filename,
            'size' => strlen(base64_decode($base64_data)),
            'is_temporary' => true,
            'base64_image' => $base64_data,
            'original_title' => $title,
            'generated_at' => $image_info['generated_at'] ?? '',
            'model' => $image_info['model'] ?? ''
        ]);
        return;
    }
    
    // Fallback: check for legacy response formats
    if (isset($data['base64_image'])) {
        $base64_image = $data['base64_image'];
        $filename = sanitize_file_name($title) . '-' . time() . '.png';
        
        wp_send_json_success([
            'image_url' => 'data:image/png;base64,' . $base64_image,
            'image_description' => $title,
            'mime_type' => 'image/png',
            'filename' => $filename,
            'size' => strlen(base64_decode($base64_image)),
            'is_temporary' => true,
            'base64_image' => $base64_image,
            'original_title' => $title
        ]);
        return;
    }
    
    // No valid image data found
    $available_keys = implode(', ', array_keys($data));
    wp_send_json_error("API response missing image data. Available keys: $available_keys");
});

// AJAX handler to process bulk actions from Generated Blog History (trash/publish/draft)
    add_action('wp_ajax_blog82ai_generated_bulk_action', function() {
        // Verify nonce
        if (!wp_verify_nonce($_POST['security'] ?? '', 'blog82ai_ajax_nonce')) {
            wp_send_json_error('Security check failed');
            return;
        }

        if (!current_user_can('edit_posts')) {
            wp_send_json_error('Insufficient permissions');
            return;
        }

        $bulk_action = sanitize_text_field($_POST['bulk_action'] ?? '');
        $raw_ids = $_POST['post_ids'] ?? '';

        // Normalize post IDs: accept JSON array or comma-separated string
        $ids = [];
        if (is_string($raw_ids) && strlen($raw_ids) > 0) {
            $decoded = json_decode(wp_unslash($raw_ids), true);
            if (is_array($decoded)) {
                $ids = $decoded;
            } else {
                $ids = array_filter(array_map('intval', array_map('trim', explode(',', $raw_ids))));
            }
        } elseif (is_array($raw_ids)) {
            $ids = $raw_ids;
        }

        $ids = array_map('intval', $ids);
        $ids = array_values(array_filter($ids));

        if (empty($ids)) {
            wp_send_json_error('No posts selected');
            return;
        }

        $success_count = 0;
        $errors = [];

        foreach ($ids as $pid) {
            if (!get_post($pid)) {
                $errors[] = "Invalid post ID: {$pid}";
                continue;
            }

            switch ($bulk_action) {
                case 'trash':
                    $res = wp_trash_post($pid);
                    if ($res === false) {
                        $errors[] = "Failed to trash post {$pid}";
                    } else {
                        $success_count++;
                    }
                    break;
                case 'publish':
                    $updated = wp_update_post(['ID' => $pid, 'post_status' => 'publish'], true);
                    if (is_wp_error($updated)) {
                        $errors[] = "Failed to publish post {$pid}";
                    } else {
                        $success_count++;
                    }
                    break;
                case 'draft':
                    $updated = wp_update_post(['ID' => $pid, 'post_status' => 'draft'], true);
                    if (is_wp_error($updated)) {
                        $errors[] = "Failed to set draft for post {$pid}";
                    } else {
                        $success_count++;
                    }
                    break;
                default:
                    $errors[] = "Unsupported action: {$bulk_action}";
                    break;
            }
        }

        if (!empty($errors) && $success_count === 0) {
            wp_send_json_error(['message' => 'No posts processed', 'errors' => $errors]);
            return;
        }

        $message = sprintf('Processed %d of %d posts', $success_count, count($ids));
        wp_send_json_success(['message' => $message, 'processed' => $success_count, 'errors' => $errors]);
    });

add_action('wp_ajax_regenerate_blog_image', function() {
    if (!wp_verify_nonce($_POST['_wpnonce'] ?? '', 'regenerate_blog_image')) {
        wp_send_json_error('Security check failed');
        return;
    }
    
    if (!current_user_can('edit_posts')) {
        wp_send_json_error('Insufficient permissions');
        return;
    }
    
    $blog_id = intval($_POST['blog_id'] ?? 0);
    if (!$blog_id || !get_post($blog_id)) {
        wp_send_json_error('Invalid blog ID');
        return;
    }
    
    // Here you would implement the actual AI image generation
    // For now, we'll simulate it
    wp_send_json_success('Featured image regenerated successfully');
});

add_action('wp_ajax_regenerate_blog_content', function() {
    if (!wp_verify_nonce($_POST['_wpnonce'] ?? '', 'regenerate_blog_content')) {
        wp_send_json_error('Security check failed');
        return;
    }
    
    if (!current_user_can('edit_posts')) {
        wp_send_json_error('Insufficient permissions');
        return;
    }
    
    $blog_id = intval($_POST['blog_id'] ?? 0);
    if (!$blog_id || !get_post($blog_id)) {
        wp_send_json_error('Invalid blog ID');
        return;
    }
    // If new_content is provided, use it; otherwise return error (we expect client to fetch first)
    $new_content = isset($_POST['new_content']) ? wp_kses_post(wp_unslash($_POST['new_content'])) : '';
    $meta_title = isset($_POST['meta_title']) ? sanitize_text_field($_POST['meta_title']) : '';
    $meta_description = isset($_POST['meta_description']) ? sanitize_textarea_field($_POST['meta_description']) : '';
    $focus_keywords = isset($_POST['focus_keywords']) ? sanitize_text_field($_POST['focus_keywords']) : '';
    $tags = isset($_POST['tags']) ? sanitize_text_field($_POST['tags']) : '';

    if (empty($new_content)) {
        wp_send_json_error('No new content provided');
        return;
    }

    // Update post content
    $update = wp_update_post([
        'ID' => $blog_id,
        'post_content' => $new_content
    ], true);

    if (is_wp_error($update)) {
        wp_send_json_error('Failed to update content: ' . $update->get_error_message());
        return;
    }

    // Update meta: meta title/description, focus keywords, tags
    if (!empty($meta_title)) {
        update_post_meta($blog_id, '_blogibot_meta_title', $meta_title);
        if (class_exists('WPSEO_Meta')) update_post_meta($blog_id, '_yoast_wpseo_title', $meta_title);
    }
    if (!empty($meta_description)) {
        update_post_meta($blog_id, '_blogibot_meta_description', $meta_description);
        if (class_exists('WPSEO_Meta')) update_post_meta($blog_id, '_yoast_wpseo_metadesc', $meta_description);
    }
    if (!empty($focus_keywords)) {
        update_post_meta($blog_id, '_blogibot_focus_keywords', $focus_keywords);
        if (class_exists('WPSEO_Meta')) update_post_meta($blog_id, '_yoast_wpseo_focuskw', $focus_keywords);
    }
    if (!empty($tags)) {
        // Accept comma-separated tags
        $tag_array = array_filter(array_map('trim', explode(',', $tags)));
        if (!empty($tag_array)) wp_set_post_tags($blog_id, $tag_array, false);
    }

    wp_send_json_success(['message' => 'Content updated successfully']);
});

// AJAX handler: Save regenerated image to media library and set as featured image
add_action('wp_ajax_blog82ai_save_regenerated_image', function() {
    if (!wp_verify_nonce($_POST['security'] ?? '', 'blog82ai_ajax_nonce')) {
        wp_send_json_error('Security check failed');
        return;
    }
    
    if (!current_user_can('edit_posts')) {
        wp_send_json_error('Insufficient permissions');
        return;
    }
    
    $blog_id = intval($_POST['blog_id'] ?? 0);
    $image_url = $_POST['image_url'] ?? '';
    $filename = sanitize_file_name($_POST['filename'] ?? '');
    $mime_type = sanitize_text_field($_POST['mime_type'] ?? 'image/png');
    $description = sanitize_text_field($_POST['description'] ?? '');
    $base64_image = $_POST['base64_image'] ?? '';
    
    if (!$blog_id || !get_post($blog_id)) {
        wp_send_json_error('Invalid blog ID');
        return;
    }
    
    if (empty($image_url) && empty($base64_image)) {
        wp_send_json_error('No image data provided');
        return;
    }
    
    // Handle base64 image or URL-based image
    if (!empty($base64_image)) {
        // Decode base64 image and save to temp file
        $image_data = base64_decode($base64_image);
        if ($image_data === false) {
            wp_send_json_error('Failed to decode base64 image');
            return;
        }
        
        $upload_dir = wp_upload_dir();
        $tmp = $upload_dir['path'] . '/' . wp_unique_filename($upload_dir['path'], $filename);
        
        if (file_put_contents($tmp, $image_data) === false) {
            wp_send_json_error('Failed to save temporary image file');
            return;
        }
    } else {
        // Download image from URL
        $tmp = download_url(esc_url_raw($image_url));
        
        if (is_wp_error($tmp)) {
            wp_send_json_error('Failed to download image: ' . $tmp->get_error_message());
            return;
        }
    }
    
    // Prepare file array for media_handle_sideload
    $file_array = [
        'name' => $filename ?: 'ai-generated-image-' . time() . '.png',
        'tmp_name' => $tmp
    ];
    
    // Import image into media library
    $attachment_id = media_handle_sideload($file_array, $blog_id, $description);
    
    // Clean up temporary file (only if it's not a base64 temp file we created)
    if (file_exists($tmp)) {
        @unlink($tmp);
    }
    
    if (is_wp_error($attachment_id)) {
        wp_send_json_error('Failed to save image: ' . $attachment_id->get_error_message());
        return;
    }
    
    // Set as featured image
    $result = set_post_thumbnail($blog_id, $attachment_id);
    
    if (!$result) {
        wp_send_json_error('Image saved but failed to set as featured image');
        return;
    }
    
    // Get the thumbnail URL to return
    $thumbnail_url = get_the_post_thumbnail_url($blog_id, 'thumbnail');
    
    wp_send_json_success([
        'message' => 'Image saved and set as featured image',
        'attachment_id' => $attachment_id,
        'thumbnail_url' => $thumbnail_url
    ]);
});

// AJAX handler for license management
add_action('wp_ajax_blog82ai_manage_license', function() {
    if (!wp_verify_nonce($_POST['_wpnonce'] ?? '', 'blog82ai_license_nonce')) {
        wp_send_json_error('Security check failed');
        return;
    }
    
    if (!current_user_can('manage_options')) {
        wp_send_json_error('Insufficient permissions');
        return;
    }
    
    require_once WP_PLUGIN_DIR . '/blogibot/src/License/LicenseManager.php';
    
    $action = sanitize_text_field($_POST['license_action'] ?? '');
    
    if ($action === 'activate') {
        $license_key = sanitize_text_field($_POST['license_key'] ?? '');
        $domain = sanitize_text_field($_POST['domain'] ?? '');
        
        if (empty($license_key) || empty($domain)) {
            wp_send_json_error('License key and domain are required');
            return;
        }
        
        // Register license with API
        $registration = Blog82AI_License_Manager::register_license($license_key, $domain);
        
        if ($registration['valid']) {
            // Return license data for UI update
            $license_data = Blog82AI_License_Manager::get_license_data();
            wp_send_json_success([
                'message' => $registration['message'],
                'license_key' => $license_data['license_key'],
                'domain' => $license_data['domain'],
                'status' => $license_data['status'],
                'activated_at' => $license_data['activated_at']
            ]);
        } else {
            wp_send_json_error($registration['message']);
        }
        
    } elseif ($action === 'remove') {
        $removal_result = Blog82AI_License_Manager::remove_license();
        
        if ($removal_result['success']) {
            wp_send_json_success([
                'message' => $removal_result['message'],
                'local_cleanup' => $removal_result['local_cleanup']
            ]);
        } else {
            wp_send_json_error($removal_result['message']);
        }
        
    } elseif ($action === 'validate') {
        $license_key = sanitize_text_field($_POST['license_key'] ?? '');
        $domain = sanitize_text_field($_POST['domain'] ?? '');
        
        if (empty($license_key) || empty($domain)) {
            wp_send_json_error('License key and domain are required');
            return;
        }
        
        $validation = Blog82AI_License_Manager::validate_license($license_key, $domain);
        
        if ($validation['valid']) {
            wp_send_json_success($validation['message']);
        } else {
            wp_send_json_error($validation['message']);
        }
        
    } else {
        wp_send_json_error('Invalid action');
    }
});

// AJAX handler for API debug information
add_action('wp_ajax_blog82ai_get_debug_info', function() {
    if (!wp_verify_nonce($_POST['_wpnonce'] ?? '', 'blog82ai_license_nonce')) {
        wp_send_json_error('Security check failed');
        return;
    }
    
    if (!current_user_can('manage_options')) {
        wp_send_json_error('Insufficient permissions');
        return;
    }
    
    // Only allow in debug mode
    if (!defined('WP_DEBUG') || !WP_DEBUG) {
        wp_send_json_error('Debug information only available in debug mode');
        return;
    }
    
    require_once WP_PLUGIN_DIR . '/blogibot/src/License/LicenseManager.php';
    
    $debug_info = Blog82AI_License_Manager::get_api_debug_info();
    
    if ($debug_info) {
        wp_send_json_success($debug_info);
    } else {
        wp_send_json_error('Debug information not available');
    }
});

// AJAX handler to save SEO settings from the Admin SEO Settings form
add_action('wp_ajax_blog82ai_save_seo_settings', function() {
    if (!wp_verify_nonce($_POST['_wpnonce'] ?? '', 'blog82ai_seo_settings')) {
        wp_send_json_error('Security check failed');
    }

    if (!current_user_can('manage_options')) {
        wp_send_json_error('Insufficient permissions');
    }

    // Build sanitized settings array from submitted form fields
    $settings = [];
    $settings['default_focus_keyphrase'] = sanitize_text_field($_POST['default_focus_keyphrase'] ?? 'auto');
    $settings['keyphrase_density'] = floatval($_POST['keyphrase_density'] ?? 1.5);
    $settings['auto_meta_title'] = filter_var($_POST['auto_meta_title'] ?? false, FILTER_VALIDATE_BOOLEAN);
    $settings['auto_meta_description'] = filter_var($_POST['auto_meta_description'] ?? false, FILTER_VALIDATE_BOOLEAN);
    $settings['meta_title_template'] = sanitize_text_field($_POST['meta_title_template'] ?? '{title} | {site_name}');
    $settings['meta_description_template'] = sanitize_textarea_field($_POST['meta_description_template'] ?? '{excerpt}');

    $settings['auto_headings'] = filter_var($_POST['auto_headings'] ?? false, FILTER_VALIDATE_BOOLEAN);
    $settings['auto_internal_links'] = filter_var($_POST['auto_internal_links'] ?? false, FILTER_VALIDATE_BOOLEAN);
    $settings['auto_alt_text'] = filter_var($_POST['auto_alt_text'] ?? false, FILTER_VALIDATE_BOOLEAN);
    $settings['auto_schema_markup'] = filter_var($_POST['auto_schema_markup'] ?? false, FILTER_VALIDATE_BOOLEAN);
    $settings['content_structure'] = sanitize_text_field($_POST['content_structure'] ?? 'introduction-body-conclusion');
    $settings['readability_target'] = sanitize_text_field($_POST['readability_target'] ?? 'medium');

    $settings['enable_keyword_research'] = filter_var($_POST['enable_keyword_research'] ?? false, FILTER_VALIDATE_BOOLEAN);
    $settings['keyword_sources'] = array_map('sanitize_text_field', (array)($_POST['keyword_sources'] ?? []));
    $settings['long_tail_keywords'] = sanitize_text_field($_POST['long_tail_keywords'] ?? 'moderate');

    $settings['yoast_auto_analysis'] = filter_var($_POST['yoast_auto_analysis'] ?? false, FILTER_VALIDATE_BOOLEAN);
    $settings['yoast_auto_optimize'] = filter_var($_POST['yoast_auto_optimize'] ?? false, FILTER_VALIDATE_BOOLEAN);
    $settings['yoast_score_target'] = sanitize_text_field($_POST['yoast_score_target'] ?? 'good');

    $settings['canonical_urls'] = filter_var($_POST['canonical_urls'] ?? false, FILTER_VALIDATE_BOOLEAN);
    $settings['open_graph'] = filter_var($_POST['open_graph'] ?? false, FILTER_VALIDATE_BOOLEAN);
    $settings['twitter_cards'] = filter_var($_POST['twitter_cards'] ?? false, FILTER_VALIDATE_BOOLEAN);
    $settings['breadcrumbs'] = filter_var($_POST['breadcrumbs'] ?? false, FILTER_VALIDATE_BOOLEAN);
    $settings['robots_meta'] = sanitize_text_field($_POST['robots_meta'] ?? 'index,follow');

    $settings['seo_monitoring'] = filter_var($_POST['seo_monitoring'] ?? false, FILTER_VALIDATE_BOOLEAN);
    $settings['weekly_seo_reports'] = filter_var($_POST['weekly_seo_reports'] ?? false, FILTER_VALIDATE_BOOLEAN);
    $settings['report_email'] = sanitize_email($_POST['report_email'] ?? get_option('admin_email'));

    // Category rules may be submitted as arrays; normalize and sanitize
    $raw_rules = $_POST['category_rules'] ?? [];
    $rules = [];
    if (is_array($raw_rules)) {
        foreach ($raw_rules as $idx => $rule) {
            if (!is_array($rule)) continue;
            $rules[$idx] = [
                'category' => sanitize_text_field($rule['category'] ?? ''),
                'keyphrase_suffix' => sanitize_text_field($rule['keyphrase_suffix'] ?? ''),
                'title_prefix' => sanitize_text_field($rule['title_prefix'] ?? '')
            ];
        }
    }
    $settings['category_rules'] = $rules;

    // Persist the sanitized settings
    update_option('blog82ai_seo_settings', $settings);

    wp_send_json_success(['message' => 'SEO settings saved']);
});

// AJAX handler to test SEO settings (sanity checks)
add_action('wp_ajax_blog82ai_test_seo_settings', function() {
    if (!wp_verify_nonce($_POST['_wpnonce'] ?? '', 'blog82ai_seo_settings')) {
        wp_send_json_error('Security check failed');
    }

    if (!current_user_can('manage_options')) {
        wp_send_json_error('Insufficient permissions');
    }

    // Accept posted settings (if provided) or fallback to saved option
    $input = $_POST;
    $settings = [];
    if (!empty($input)) {
        // mirror fields used in save
        $settings['meta_title_template'] = sanitize_text_field($input['meta_title_template'] ?? '');
        $settings['meta_description_template'] = sanitize_textarea_field($input['meta_description_template'] ?? '');
        $settings['keyphrase_density'] = floatval($input['keyphrase_density'] ?? 1.5);
        $settings['enable_keyword_research'] = filter_var($input['enable_keyword_research'] ?? false, FILTER_VALIDATE_BOOLEAN);
        $settings['keyword_sources'] = array_map('sanitize_text_field', (array)($input['keyword_sources'] ?? []));
        $settings['yoast_score_target'] = sanitize_text_field($input['yoast_score_target'] ?? 'good');
        $settings['content_structure'] = sanitize_text_field($input['content_structure'] ?? 'introduction-body-conclusion');
    } else {
        $settings = get_option('blog82ai_seo_settings', []);
    }

    // Prepare checks
    $checks = [];

    // Meta title template tokens check
    $allowed_tokens = ['{title}', '{category}', '{keyphrase}', '{site_name}'];
    $title_template = $settings['meta_title_template'] ?? '';
    preg_match_all('/\{[^}]+\}/', $title_template, $matches);
    $unknown_tokens = [];
    if (!empty($matches[0])) {
        foreach ($matches[0] as $t) {
            if (!in_array($t, $allowed_tokens, true)) $unknown_tokens[] = $t;
        }
    }
    if (!empty($unknown_tokens)) {
        $checks[] = ['status' => 'warning', 'message' => 'Meta title template contains unknown tokens: ' . implode(', ', $unknown_tokens)];
    } else {
        $checks[] = ['status' => 'ok', 'message' => 'Meta title template tokens look fine'];
    }

    // Meta description length check (estimate)
    $sample_replace = [
        '{excerpt}' => str_repeat('Example excerpt ', 3),
        '{keyphrase}' => 'example keyphrase',
        '{category}' => 'Example Category',
        '{title}' => 'Example Title'
    ];
    $desc_template = $settings['meta_description_template'] ?? '';
    $rendered = strtr($desc_template, $sample_replace);
    $len = mb_strlen(strip_tags($rendered));
    if ($len < 50) {
        $checks[] = ['status' => 'warning', 'message' => "Meta description appears short ({$len} chars). Recommend 50-160 chars."];
    } elseif ($len > 320) {
        $checks[] = ['status' => 'warning', 'message' => "Meta description appears long ({$len} chars). Try keeping it under 160 chars."];
    } else {
        $checks[] = ['status' => 'ok', 'message' => "Meta description length estimate: {$len} chars"];
    }

    // Keyphrase density basic validation
    $density = floatval($settings['keyphrase_density'] ?? 1.5);
    if ($density < 0.1 || $density > 10) {
        $checks[] = ['status' => 'error', 'message' => 'Keyphrase density is out of sensible range (0.1 - 10%).'];
    } else {
        $checks[] = ['status' => 'ok', 'message' => 'Keyphrase density set to ' . $density . '%'];
    }

    // Keyword research sources
    if (!empty($settings['enable_keyword_research']) && empty($settings['keyword_sources'])) {
        $checks[] = ['status' => 'warning', 'message' => 'Keyword research enabled but no sources selected.'];
    } else {
        $checks[] = ['status' => 'ok', 'message' => 'Keyword research configuration looks fine'];
    }

    // Yoast target check
    $valid_targets = ['good','ok','any'];
    $target = $settings['yoast_score_target'] ?? 'good';
    if (!in_array($target, $valid_targets, true)) {
        $checks[] = ['status' => 'error', 'message' => 'Yoast score target invalid'];
    } else {
        $checks[] = ['status' => 'ok', 'message' => 'Yoast score target: ' . $target];
    }

    // Content structure check
    $valid_structures = ['introduction-body-conclusion','problem-solution','listicle','how-to','comparison'];
    if (!in_array($settings['content_structure'] ?? '', $valid_structures, true)) {
        $checks[] = ['status' => 'warning', 'message' => 'Content structure looks unusual or unsupported'];
    } else {
        $checks[] = ['status' => 'ok', 'message' => 'Content structure: ' . ($settings['content_structure'] ?? 'default')];
    }

    wp_send_json_success(['checks' => $checks]);
});

// AJAX handler for blog generation
add_action('wp_ajax_blogibot_generate_blog', function() {
    error_log('Blogibot: AJAX handler called for blog generation');
    
    try {
        require_once WP_PLUGIN_DIR . '/blogibot/src/Handlers/BlogGenerationHandler.php';
        \Blogibot\Handlers\BlogGenerationHandler::handle_generate_request();
    } catch (Exception $e) {
        error_log('Blogibot: Error in AJAX handler: ' . $e->getMessage());
        
        if (!headers_sent()) {
            header('Content-Type: application/json');
        }
        
        // Clean any output buffers
        while (ob_get_level()) {
            ob_end_clean();
        }
        
        echo json_encode([
            'success' => false,
            'message' => 'Handler error: ' . $e->getMessage()
        ]);
        wp_die();
    }
});

// AJAX handler for saving blog as draft
add_action('wp_ajax_blogibot_save_draft', function() {
    require_once WP_PLUGIN_DIR . '/blogibot/src/Handlers/BlogGenerationHandler.php';
    \Blogibot\Handlers\BlogGenerationHandler::handle_save_draft();
});

// AJAX handler for publishing blog
add_action('wp_ajax_blogibot_publish_post', function() {
    require_once WP_PLUGIN_DIR . '/blogibot/src/Handlers/BlogGenerationHandler.php';
    \Blogibot\Handlers\BlogGenerationHandler::handle_publish_post();
});

// AJAX handler for AI image generation
add_action('wp_ajax_blogibot_generate_image', function() {
    require_once WP_PLUGIN_DIR . '/blogibot/src/Handlers/BlogGenerationHandler.php';
    \Blogibot\Handlers\BlogGenerationHandler::handle_generate_image();
});

// AJAX handler for starting content scan
add_action('wp_ajax_blogibot_start_content_scan', function() {
    require_once WP_PLUGIN_DIR . '/blogibot/src/Handlers/ContentAnalyzerHandler.php';
    \Blogibot\Handlers\ContentAnalyzerHandler::handle_start_scan();
});

// AJAX handler for getting scan progress
add_action('wp_ajax_blogibot_get_scan_progress', function() {
    require_once WP_PLUGIN_DIR . '/blogibot/src/Handlers/ContentAnalyzerHandler.php';
    \Blogibot\Handlers\ContentAnalyzerHandler::handle_get_progress();
});

// AJAX handler for getting scan log
add_action('wp_ajax_blogibot_get_scan_log', function() {
    require_once WP_PLUGIN_DIR . '/blogibot/src/Handlers/ContentAnalyzerHandler.php';
    \Blogibot\Handlers\ContentAnalyzerHandler::handle_get_log();
});

// AJAX handler for processing individual scan batch
add_action('wp_ajax_blogibot_process_batch', function() {
    require_once WP_PLUGIN_DIR . '/blogibot/src/Handlers/ContentAnalyzerHandler.php';
    \Blogibot\Handlers\ContentAnalyzerHandler::handle_process_batch();
});

// AJAX handler for resetting stuck scan
add_action('wp_ajax_blogibot_reset_scan', function() {
    require_once WP_PLUGIN_DIR . '/blogibot/src/Handlers/ContentAnalyzerHandler.php';
    \Blogibot\Handlers\ContentAnalyzerHandler::handle_reset_scan();
});

// Register the cron hook for processing content scan
add_action('init', function() {
    require_once WP_PLUGIN_DIR . '/blogibot/src/Handlers/ContentAnalyzerHandler.php';
    add_action('blogibot_process_content_scan', ['\\Blogibot\\Handlers\\ContentAnalyzerHandler', 'process_content_scan']);
    
    // Fallback cron hook in case the main one fails
    add_action('blogibot_process_content_scan_fallback', function($license_data) {
        // Only run if the scan is still in progress and no progress has been made
        $progress = get_option('blogibot_scan_progress', []);
        if (isset($progress['status']) && $progress['status'] === 'in_progress' && 
            isset($progress['posts_processed']) && $progress['posts_processed'] === 0) {
            error_log('Blogibot: Fallback cron triggered - main cron may have failed');
            \Blogibot\Handlers\ContentAnalyzerHandler::process_content_scan($license_data);
        }
    });
});

// Utility function for category hierarchy display (used by backup system)
function blog82ai_get_category_hierarchy($category_name)
{
    $category = get_term_by('name', $category_name, 'category');
    if (!$category) return $category_name;
    $names = [$category->name];
    while ($category->parent != 0) {
        $category = get_term($category->parent, 'category');
        array_unshift($names, $category->name);
    }
    return implode(' → ', $names);
}

// Register a custom interval for daily blog generation
add_filter('cron_schedules', function($schedules) {
    $schedules['blog82ai_daily'] = [
        'interval' => 24 * 60 * 60, // 1 day
        'display' => __('Blog82ai Daily', 'blogibot')
    ];
    return $schedules;
});

// Blog Generate for CRON (recurring) - Core blog generation handler
function blogibot_generate_blog_handler($args) {
    // Only consider schedules that are not paused
    $scheduled = get_option('blog82ai_scheduled_blogs', []);
    $active_schedule = null;
    if (!is_array($args)) {
        $args = ['category' => $args];
    }
    // Find the schedule for this category and schedule_id, and check if it's paused
    foreach ($scheduled as $item) {
        if (
            isset($item['category'], $item['id']) &&
            $item['category'] === $args['category'] &&
            (empty($args['schedule_id']) || $item['id'] === $args['schedule_id'])
        ) {
            if (isset($item['status']) && $item['status'] === 'paused') {
                // If paused, do not run cron job
                return false;
            }
            $active_schedule = $item;
            break;
        }
    }
    if (!isset($args['schedule_id'])) {
        $args['schedule_id'] = 'manual_' . time();
    }
    
    // Get API credentials from license data
    $license_data = Blog82AI_License_Manager::get_license_data();
    $api_key = $license_data['license_key'] ?? '';
    $domain = $license_data['domain'] ?? '';
    
    if (empty($api_key) || empty($domain) || $license_data['status'] !== 'active') {
        error_log('Blog82AI: Invalid or inactive license data');
        return false;
    }
    
    $api_base = (defined('BLOGIBOT_API_ENV') && BLOGIBOT_API_ENV === 'production')
        ? rtrim(BLOGIBOT_API_PRODUCTION, '/')
        : rtrim(BLOGIBOT_API_SANDBOX, '/');
    $max_retries = 5;
    $retry_count = 0;
    do {
        // Fetch blog from API
        $api_payload = [
            'api_key' => $api_key,
            'category' => $args['category'],
            'domain' => $domain,
            'schedule_id' => $args['schedule_id']
        ];
        $api_url = $api_base . '/generate-blog';
        $response = wp_remote_post($api_url, [
            'headers' => ['Content-Type' => 'application/json'],
            'body' => json_encode($api_payload),
            'sslverify' => false,
            'timeout' => 60
        ]);
        
        if (is_wp_error($response)) {
            // Send email to admin if API error occurs
            $admin_email = get_option('admin_email');
            $subject = '[Blogibot] Scheduled Post API Error';
            $message = "A scheduled post failed due to an API error.\n\nCategory: {$args['category']}\nDate: " . date('Y-m-d H:i:s') . "\nError: " . $response->get_error_message();
            wp_mail($admin_email, $subject, $message);
            return false;
        }
        
        $api_response_body = wp_remote_retrieve_body($response);
        $body = json_decode($api_response_body, true);
        
        error_log('Blog82AI: API Response: ' . $api_response_body);
        
        if (!$body || !isset($body['title']) || !isset($body['content'])) {
            // Send email to admin if API response is invalid
            $admin_email = get_option('admin_email');
            $subject = '[Blogibot] Scheduled Post API Error';
            $message = "A scheduled post failed due to an invalid API response.\n\nCategory: {$args['category']}\nDate: " . date('Y-m-d H:i:s') . "\nReceived data: " . $api_response_body;
            wp_mail($admin_email, $subject, $message);
            return false;
        }
        
        $title = sanitize_text_field($body['title']);
        $category = $args['category'];
        $slug = sanitize_title($title);
        // Check for duplicate post by slug and category
        $existing = get_posts([
            'name' => $slug,
            'category_name' => $category,
            'post_type' => 'post',
            'post_status' => 'publish',
            'posts_per_page' => 1,
            'fields' => 'ids',
        ]);
        if (empty($existing)) {
            break;
        }
        $retry_count++;
    } while ($retry_count < $max_retries);
    
    if (!empty($existing)) {
        // Send email to admin if could not get a unique post
        $admin_email = get_option('admin_email');
        $subject = '[Blogibot] Scheduled Post Duplicate Error';
        $message = "A scheduled post could not be created after several attempts due to duplicate titles.\n\nCategory: {$args['category']}\nDate: " . date('Y-m-d H:i:s');
        wp_mail($admin_email, $subject, $message);
        return false;
    }
    
    $Parsedown = new Parsedown();
    $Parsedown->setSafeMode(true);
    // Always use the scheduled category for the post
    $term = get_term_by('name', $category, 'category');
    if (!$term) {
        $term = wp_insert_term($category, 'category');
        $term_id = is_array($term) ? $term['term_id'] : null;
    } else {
        $term_id = $term->term_id;
    }
    // Get first admin user as default author
    $admin_user = get_users([
        'role'    => 'administrator',
        'number'  => 1,
        'orderby' => 'ID',
        'order'   => 'ASC',
        'fields'  => ['ID']
    ]);
    $default_author = !empty($admin_user) ? $admin_user[0]->ID : 1;
    $post_data = [
        'post_title'    => $title,
        'post_content'  => $Parsedown->text($body['content']),
        'post_status'   => 'publish',
        'post_category' => $term_id ? [$term_id] : [],
        'post_author'   => $default_author
    ];
    $post_id = wp_insert_post($post_data);
    if ($post_id && !is_wp_error($post_id)) {
        // Yoast SEO Integration only if the plugin is active
        if (class_exists('WPSEO_Meta')) {
            update_post_meta($post_id, '_yoast_wpseo_title', sanitize_text_field($body['meta_title'] ?? ''));
            update_post_meta($post_id, '_yoast_wpseo_metadesc', sanitize_text_field($body['meta_description'] ?? ''));
        }
        // Blogibot Starter Plan Features (overwrite if present)
        if (!empty($body['tags'])) {
            $new_tags = $body['tags'];
            if (is_string($new_tags)) {
                $new_tags = array_map('trim', explode(',', $new_tags));
            }
            if (is_array($new_tags) && !empty($new_tags)) {
                wp_set_post_tags($post_id, $new_tags, false);
            }
        }
        if (!empty($body['focus_keywords'])) {
            // Overwrite Yoast focus keyword with API focus keyword
            $focus = trim($body['focus_keywords']);
            update_post_meta($post_id, '_blogibot_focus_keywords', $focus);
            if (class_exists('WPSEO_Meta')) {
                update_post_meta($post_id, '_yoast_wpseo_focuskw', $focus);
            }
        }
        if (!empty($body['featured_snippet'])) {
            update_post_meta($post_id, '_blogibot_featured_snippet', $body['featured_snippet']);
        }
    }
    // Mark post as AI-generated for dashboard and reporting
    if ($post_id && !is_wp_error($post_id)) {
        try {
            add_post_meta($post_id, '_blog82ai_generated', true, true);
            // Backwards compatibility key
            add_post_meta($post_id, '_blogibot_generated', true, true);
            // Add generation timestamp for ordering in dashboard
            add_post_meta($post_id, '_blog82ai_generated_at', current_time('mysql'), true);
        } catch (\Throwable $e) {
            error_log('Blog82AI: Failed to add generated meta for post ' . $post_id . ': ' . $e->getMessage());
        }
    }
    // Email notification
    $admin_email = get_option('admin_email');
    $subject_success = '[Blogibot] Scheduled Post Created Successfully';
    $subject_fail = '[Blogibot] Scheduled Post Creation Failed';
    $category = isset($args['category']) ? $args['category'] : '';
    $post_title = $title;
    $post_created = ($post_id && !is_wp_error($post_id));
    if ($post_created) {
        $message = "A scheduled post was created successfully.\n\nTitle: $post_title\nCategory: $category\nDate: " . date('Y-m-d H:i:s');
        wp_mail($admin_email, $subject_success, $message);

        // Return structured result for programmatic callers
        $permalink = get_permalink($post_id);
        $excerpt = wp_trim_words(strip_tags($body['content'] ?? ''), 40, '...');

        return [
            'post_id' => $post_id,
            'title' => $post_title,
            'content' => $body['content'] ?? '',
            'excerpt' => $excerpt,
            'permalink' => $permalink
        ];
    } else {
        $message = "A scheduled post failed to be created.\n\nCategory: $category\nDate: " . date('Y-m-d H:i:s');
        wp_mail($admin_email, $subject_fail, $message);
        return false; // Failure
    }
}
add_action('blogibot_generate_blog', 'blogibot_generate_blog_handler', 10, 1);

// Dev-only endpoint to fetch last raw API response (only when WP_DEBUG true and admin)
add_action('wp_ajax_blog82ai_get_last_api_response', function() {
    if (!current_user_can('manage_options')) {
        wp_send_json_error('Insufficient permissions');
    }

    if (!defined('WP_DEBUG') || !WP_DEBUG) {
        wp_send_json_error('Debugging not enabled');
    }

    $raw = get_transient('blog82ai_last_api_response');
    if ($raw === false || $raw === null) {
        wp_send_json_error('No recent API response cached');
    }

    // Return raw payload (do not log or expose publicly)
    wp_send_json_success(['raw' => $raw]);
});
