<?php
/**
 * Plugin Core
 *
 * @package AIContentGenerator
 */

namespace AICG;

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

/**
 * Core plugin class - orchestrates all modules
 */
class Plugin_Core
{

    /**
     * AI Client instance
     */
    private $ai_client;

    /**
     * Pexels API instance
     */
    private $pexels;

    /**
     * Keyword Manager instance
     */
    private $keyword_manager;

    /**
     * Content Generator instance
     */
    private $content_generator;

    /**
     * Scheduler instance
     */
    private $scheduler;

    /**
     * Quality Checker instance
     */
    private $quality_checker;

    /**
     * Admin Settings instance
     */
    private $admin_settings;

    /**
     * Initialize the plugin
     */
    public function init()
    {
        $this->load_dependencies();
        $this->init_modules();
        $this->register_hooks();
    }

    /**
     * Load required dependencies
     */
    private function load_dependencies()
    {
        require_once ROIDAICO_PLUGIN_DIR . 'includes/class-license-manager.php';
        require_once ROIDAICO_PLUGIN_DIR . 'includes/class-openrouter-api.php';
        require_once ROIDAICO_PLUGIN_DIR . 'includes/class-ai-client.php';
        require_once ROIDAICO_PLUGIN_DIR . 'includes/class-pexels-api.php';
        require_once ROIDAICO_PLUGIN_DIR . 'includes/class-keyword-manager.php';
        require_once ROIDAICO_PLUGIN_DIR . 'includes/class-content-generator.php';
        require_once ROIDAICO_PLUGIN_DIR . 'includes/class-scheduler.php';
        require_once ROIDAICO_PLUGIN_DIR . 'includes/class-logger.php';
        require_once ROIDAICO_PLUGIN_DIR . 'includes/class-quality-checker.php';
        require_once ROIDAICO_PLUGIN_DIR . 'includes/class-alternate-cron.php';
        require_once ROIDAICO_PLUGIN_DIR . 'includes/class-system-diagnostics.php';

        if (is_admin()) {
            require_once ROIDAICO_PLUGIN_DIR . 'includes/class-admin-settings.php';
        }
    }

    /**
     * Initialize all modules
     */
    private function init_modules()
    {
        $this->ai_client = new Ai_Client();
        $this->pexels = new Pexels_Api();
        $this->keyword_manager = new Keyword_Manager();
        $this->quality_checker = new Quality_Checker();
        $this->content_generator = new Content_Generator(
            $this->ai_client,
            $this->pexels,
            $this->quality_checker
        );
        $this->scheduler = new Scheduler(
            $this->keyword_manager,
            $this->content_generator
        );

        if (is_admin()) {
            $this->admin_settings = new Admin_Settings(
                $this->ai_client,
                $this->pexels,
                $this->keyword_manager,
                $this->scheduler
            );
        }
    }

    /**
     * Register WordPress hooks
     */
    public function register_hooks()
    {
        // Cron hooks
        add_action('roidaico_scheduled_publish', array($this->scheduler, 'process_scheduled_publish'));
        add_action('roidaico_buffer_check', array($this->scheduler, 'process_buffer_queue'));
        add_action('roidaico_keyword_check', array($this->scheduler, 'check_keyword_queue'));

        // Custom cron schedules
        add_filter('cron_schedules', array($this, 'add_cron_schedules'));

        // Initialize self-triggering cron (works without server crontab)
        Alternate_Cron::init();

        // Admin notices for health check
        add_action('admin_notices', array($this, 'admin_cron_health_notice'));

        // AJAX handlers
        add_action('wp_ajax_roidaico_generate_keywords', array($this, 'ajax_generate_keywords'));
        add_action('wp_ajax_roidaico_generate_content', array($this, 'ajax_generate_content'));
        add_action('wp_ajax_roidaico_test_api', array($this, 'ajax_test_api'));
        add_action('wp_ajax_roidaico_get_models', array($this, 'ajax_get_models'));
        add_action('wp_ajax_roidaico_add_keyword', array($this, 'ajax_add_keyword'));
        add_action('wp_ajax_roidaico_translate_keyword_ai', array($this, 'ajax_translate_keyword_ai'));
        add_action('wp_ajax_roidaico_bulk_translate_keywords', array($this, 'ajax_bulk_translate_keywords'));
        add_action('wp_ajax_roidaico_delete_keyword', array($this, 'ajax_delete_keyword'));
        add_action('wp_ajax_roidaico_save_schedule', array($this, 'ajax_save_schedule'));
        add_action('wp_ajax_roidaico_delete_schedule', array($this, 'ajax_delete_schedule'));
        add_action('wp_ajax_roidaico_toggle_schedule', array($this, 'ajax_toggle_schedule'));
        add_action('wp_ajax_roidaico_run_schedule_now', array($this, 'ajax_run_schedule_now'));
        add_action('wp_ajax_roidaico_activate_license', array($this, 'ajax_activate_license'));

        // Initialize cron if not scheduled
        if (!wp_next_scheduled('roidaico_scheduled_publish')) {
            wp_schedule_event(time(), 'roidaico_five_minutes', 'roidaico_scheduled_publish');
        }

        if (!wp_next_scheduled('roidaico_buffer_check')) {
            wp_schedule_event(time(), 'roidaico_five_minutes', 'roidaico_buffer_check');
        }

        // Ensure tables exist (one-time check on admin)
        if (is_admin()) {
            $this->ensure_tables_exist();
        }
    }

    /**
     * Admin notice for Cron health
     */
    public function admin_cron_health_notice()
    {
        $screen = get_current_screen();
        if (strpos($screen->id, 'aicg') === false) {
            return;
        }

        if (defined('DISABLE_WP_CRON') && DISABLE_WP_CRON) {
            echo '<div class="notice notice-warning"><p>' .
                wp_kses_post(__('<strong>Warning:</strong> DISABLE_WP_CRON is set to true in your wp-config.php. Scheduled articles will only be generated if you have a real server cron job set up.', 'roidnet-ai-content-generator')) .
                '</p></div>';
        }

        // Check if cron has run in last 30 mins
        $last_run = get_option('roidaico_last_cron_check');
        if (!$last_run || (time() - $last_run) > 3600) {
            echo '<div class="notice notice-info is-dismissible"><p>' .
                wp_kses_post(__('<strong>Tip:</strong> If scheduled articles are not generating, make sure your site has visitors or set up a real server cron job.', 'roidnet-ai-content-generator')) .
                '</p></div>';
        }
    }

    /**
     * Ensure tables exist (Lazy loading/Auto-fix)
     */
    private function ensure_tables_exist()
    {
        global $wpdb;
        $table = $wpdb->prefix . 'roidaico_logs';
        if ($wpdb->get_var("SHOW TABLES LIKE '$table'") != $table) {
            Activator::activate(); // Re-run creation
        }

        // Dynamic schema updates for existing tables
        $keywords_table = $wpdb->prefix . 'roidaico_keywords';
        if ($wpdb->get_var("SHOW TABLES LIKE '$keywords_table'") == $keywords_table) {
            $column_exists = $wpdb->get_results("SHOW COLUMNS FROM `$keywords_table` LIKE 'error_message'");
            if (empty($column_exists)) {
                $wpdb->query("ALTER TABLE `$keywords_table` ADD `error_message` text DEFAULT NULL AFTER `retries`");
            }
            
            $lang_exists = $wpdb->get_results("SHOW COLUMNS FROM `$keywords_table` LIKE 'language'");
            if (empty($lang_exists)) {
                $wpdb->query("ALTER TABLE `$keywords_table` ADD `language` varchar(10) NOT NULL DEFAULT 'en' AFTER `error_message`");
            }
            
            $translation_exists = $wpdb->get_results("SHOW COLUMNS FROM `$keywords_table` LIKE 'translation_of'");
            if (empty($translation_exists)) {
                $wpdb->query("ALTER TABLE `$keywords_table` ADD `translation_of` bigint(20) DEFAULT NULL AFTER `language`");
                $wpdb->query("ALTER TABLE `$keywords_table` ADD KEY `translation_of` (`translation_of`)");
            }
        }
    }

    /**
     * Add custom cron schedules
     */
    public function add_cron_schedules($schedules)
    {
        $schedules['roidaico_fifteen_minutes'] = array(
            'interval' => 15 * MINUTE_IN_SECONDS,
            'display' => __('Every 15 Minutes', 'roidnet-ai-content-generator'),
        );

        $schedules['roidaico_five_minutes'] = array(
            'interval' => 5 * MINUTE_IN_SECONDS,
            'display' => __('Every 5 Minutes', 'roidnet-ai-content-generator'),
        );

        return $schedules;
    }

    /**
     * AJAX: Generate keywords
     */
    public function ajax_generate_keywords()
    {
        check_ajax_referer('roidaico_nonce', 'nonce');

        if (!current_user_can('edit_posts')) {
            wp_send_json_error(__('Permission denied.', 'roidnet-ai-content-generator'));
        }

        // Check AI keywords limit for free users
        if ( ! License_Manager::can_generate_ai_keywords() ) {
            $remaining = License_Manager::get_remaining_ai_keywords();
            wp_send_json_error(
                sprintf(
                    __('AI keyword generation limit reached (10 keywords). You have %s remaining. Upgrade to Pro for unlimited AI keyword generation!', 'roidnet-ai-content-generator'),
                    $remaining
                )
            );
        }

        $topic = sanitize_text_field($_POST['topic'] ?? '');
        $category_id = absint($_POST['category_id'] ?? 0);
        $count = min(absint($_POST['count'] ?? 10), 50);
        $language = sanitize_text_field($_POST['language'] ?? '');

        // For free users, limit to remaining quota
        if ( ! License_Manager::is_pro() ) {
            $remaining = License_Manager::get_remaining_ai_keywords();
            if ( is_numeric( $remaining ) ) {
                $count = min( $count, (int) $remaining );
            }
        }

        if (empty($topic)) {
            wp_send_json_error(__('Topic is required.', 'roidnet-ai-content-generator'));
        }

        $keywords = $this->ai_client->generate_keywords($topic, $count, $language);

        if (is_wp_error($keywords)) {
            wp_send_json_error($keywords->get_error_message());
        }

        // Track AI-generated keywords count for free users
        if ( ! License_Manager::is_pro() ) {
            License_Manager::increment_ai_keywords_count( count( $keywords ) );
        }

        $message = sprintf(__('Generated %d keywords.', 'roidnet-ai-content-generator'), count($keywords));
        
        // Show remaining quota for free users
        if ( ! License_Manager::is_pro() ) {
            $remaining = License_Manager::get_remaining_ai_keywords();
            $message .= ' ' . sprintf(__('(%s AI keywords remaining)', 'roidnet-ai-content-generator'), $remaining);
        }

        wp_send_json_success(array(
            'keywords' => $keywords,
            'message' => $message,
        ));
    }

    /**
     * AJAX: Generate content for a keyword
     */
    public function ajax_generate_content()
    {
        check_ajax_referer('roidaico_nonce', 'nonce');

        if (!current_user_can('edit_posts')) {
            wp_send_json_error(__('Permission denied.', 'roidnet-ai-content-generator'));
        }

        $keyword_id = absint($_POST['keyword_id'] ?? 0);

        if (!$keyword_id) {
            wp_send_json_error(__('Keyword ID is required.', 'roidnet-ai-content-generator'));
        }

        $result = $this->content_generator->generate_from_keyword($keyword_id);

        if (is_wp_error($result)) {
            wp_send_json_error($result->get_error_message());
        }

        wp_send_json_success(array(
            'post_id' => $result,
            'message' => __('Content generated successfully.', 'roidnet-ai-content-generator'),
            'edit_url' => get_edit_post_link($result, 'raw'),
        ));
    }

    /**
     * AJAX: Test API connection
     */
    public function ajax_test_api()
    {
        check_ajax_referer('roidaico_nonce', 'nonce');

        if (!current_user_can('manage_options')) {
            wp_send_json_error(__('Permission denied.', 'roidnet-ai-content-generator'));
        }

        $api_type = sanitize_text_field($_POST['api_type'] ?? '');
        $api_key = sanitize_text_field($_POST['api_key'] ?? '');

        if ($api_type === 'openrouter' || $api_type === 'wp_ai_client') {
            $result = $this->ai_client->test_connection($api_key);
        } elseif ($api_type === 'pexels') {
            $result = $this->pexels->test_connection($api_key);
        } else {
            wp_send_json_error(__('Invalid API type.', 'roidnet-ai-content-generator'));
        }

        if (is_wp_error($result)) {
            wp_send_json_error($result->get_error_message());
        }

        wp_send_json_success(__('Connection successful!', 'roidnet-ai-content-generator'));
    }

    /**
     * AJAX: Get available models
     */
    public function ajax_get_models()
    {
        check_ajax_referer('roidaico_nonce', 'nonce');

        if (!current_user_can('manage_options')) {
            wp_send_json_error(__('Permission denied.', 'roidnet-ai-content-generator'));
        }

        $api_key = sanitize_text_field($_POST['api_key'] ?? '');
        $models = $this->ai_client->get_models($api_key);

        if (is_wp_error($models)) {
            wp_send_json_error($models->get_error_message());
        }

        wp_send_json_success($models);
    }

    /**
     * AJAX: Add keyword to queue
     */
    public function ajax_add_keyword()
    {
        check_ajax_referer('roidaico_nonce', 'nonce');

        if (!current_user_can('edit_posts')) {
            wp_send_json_error(__('Permission denied.', 'roidnet-ai-content-generator'));
        }

        $keyword = sanitize_text_field($_POST['keyword'] ?? '');
        $category_id = absint($_POST['category_id'] ?? 0);
        $language = sanitize_text_field($_POST['language'] ?? '');
        $translation_of = isset($_POST['translation_of']) && $_POST['translation_of'] !== '' ? absint($_POST['translation_of']) : null;

        if (empty($keyword)) {
            wp_send_json_error(__('Keyword is required.', 'roidnet-ai-content-generator'));
        }

        if ($translation_of && $category_id) {
            $category_id = $this->get_translated_category_id($category_id, $language);
        }

        $result = $this->keyword_manager->add_keyword($keyword, $category_id, $language, $translation_of);

        if (is_wp_error($result)) {
            wp_send_json_error($result->get_error_message());
        }

        // Trigger buffer processing immediately (don't wait for cron)
        Alternate_Cron::spawn_buffer_now();

        wp_send_json_success(array(
            'id' => $result,
            'message' => __('Keyword added to queue. Content generation will follow your scheduled interval.', 'roidnet-ai-content-generator'),
        ));
    }

    /**
     * AJAX: Translate keyword using AI
     */
    public function ajax_translate_keyword_ai()
    {
        check_ajax_referer('roidaico_nonce', 'nonce');

        if (!current_user_can('edit_posts')) {
            wp_send_json_error(__('Permission denied.', 'roidnet-ai-content-generator'));
        }

        $keyword_id = absint($_POST['keyword_id'] ?? 0);
        $target_lang = sanitize_text_field($_POST['target_lang'] ?? '');

        if (!$keyword_id) {
            wp_send_json_error(__('Keyword ID is required.', 'roidnet-ai-content-generator'));
        }

        if (empty($target_lang)) {
            wp_send_json_error(__('Target language is required.', 'roidnet-ai-content-generator'));
        }

        $keyword_data = $this->keyword_manager->get_keyword($keyword_id);
        if (!$keyword_data) {
            wp_send_json_error(__('Keyword not found.', 'roidnet-ai-content-generator'));
        }

        // Get language name from code or keep it
        $target_lang_name = $this->get_language_name($target_lang);

        $translated_text = $this->ai_client->translate_keyword($keyword_data->keyword, $target_lang_name);

        if (is_wp_error($translated_text)) {
            wp_send_json_error($translated_text->get_error_message());
        }

        if (empty($translated_text)) {
            wp_send_json_error(__('AI returned an empty translation.', 'roidnet-ai-content-generator'));
        }

        // Add the translated keyword to the queue
        $translated_category_id = $this->get_translated_category_id($keyword_data->category_id, $target_lang);
        $result = $this->keyword_manager->add_keyword(
            $translated_text,
            $translated_category_id,
            $target_lang,
            $keyword_id
        );

        if (is_wp_error($result)) {
            wp_send_json_error($result->get_error_message());
        }

        // Trigger buffer processing immediately
        Alternate_Cron::spawn_buffer_now();

        wp_send_json_success(array(
            'id' => $result,
            'translated_keyword' => $translated_text,
            'message' => sprintf(__('Keyword translated and added to queue: "%s"', 'roidnet-ai-content-generator'), $translated_text),
        ));
    }

    /**
     * AJAX: Translate multiple keywords using AI
     */
    public function ajax_bulk_translate_keywords()
    {
        check_ajax_referer('roidaico_nonce', 'nonce');

        if (!current_user_can('edit_posts')) {
            wp_send_json_error(__('Permission denied.', 'roidnet-ai-content-generator'));
        }

        $keyword_ids = isset($_POST['keyword_ids']) ? array_map('absint', $_POST['keyword_ids']) : array();
        $target_lang = sanitize_text_field($_POST['target_lang'] ?? '');

        if (empty($keyword_ids)) {
            wp_send_json_error(__('No keywords selected.', 'roidnet-ai-content-generator'));
        }

        if (empty($target_lang)) {
            wp_send_json_error(__('Target language is required.', 'roidnet-ai-content-generator'));
        }

        $active_languages = $this->get_active_languages();
        
        $translated_count = 0;
        $failed_count = 0;
        $errors = array();

        foreach ($keyword_ids as $keyword_id) {
            $keyword_data = $this->keyword_manager->get_keyword($keyword_id);
            if (!$keyword_data) {
                $failed_count++;
                continue;
            }

            // Determine target languages to translate to
            $languages_to_translate = array();
            if ($target_lang === 'all') {
                foreach (array_keys($active_languages) as $lang_code) {
                    if ($lang_code !== $keyword_data->language) {
                        $languages_to_translate[] = $lang_code;
                    }
                }
            } else {
                if ($target_lang !== $keyword_data->language) {
                    $languages_to_translate[] = $target_lang;
                }
            }

            if (empty($languages_to_translate)) {
                continue;
            }

            foreach ($languages_to_translate as $lang) {
                $parent_id = !empty($keyword_data->translation_of) ? $keyword_data->translation_of : $keyword_data->id;
                
                // Check if a translation of this parent already exists in this target language
                global $wpdb;
                $table = $wpdb->prefix . 'roidaico_keywords';
                $exists = $wpdb->get_var($wpdb->prepare(
                    "SELECT COUNT(*) FROM $table WHERE (id = %d OR translation_of = %d) AND language = %s",
                    $parent_id,
                    $parent_id,
                    $lang
                ));
                
                if ($exists > 0) {
                    $failed_count++;
                    continue; 
                }

                $target_lang_name = $this->get_language_name($lang);
                $translated_text = $this->ai_client->translate_keyword($keyword_data->keyword, $target_lang_name);

                if (is_wp_error($translated_text)) {
                    $failed_count++;
                    $errors[] = sprintf(__('Failed to translate "%s" to %s: %s', 'roidnet-ai-content-generator'), $keyword_data->keyword, $target_lang_name, $translated_text->get_error_message());
                    continue;
                }

                if (empty($translated_text)) {
                    $failed_count++;
                    $errors[] = sprintf(__('AI returned an empty translation for "%s" in %s', 'roidnet-ai-content-generator'), $keyword_data->keyword, $target_lang_name);
                    continue;
                }

                $translated_category_id = $this->get_translated_category_id($keyword_data->category_id, $lang);
                $result = $this->keyword_manager->add_keyword(
                    $translated_text,
                    $translated_category_id,
                    $lang,
                    $parent_id
                );

                if (is_wp_error($result)) {
                    $failed_count++;
                    $errors[] = sprintf(__('Failed to save translation for "%s": %s', 'roidnet-ai-content-generator'), $keyword_data->keyword, $result->get_error_message());
                } else {
                    $translated_count++;
                }
            }
        }

        Alternate_Cron::spawn_buffer_now();

        if ($translated_count === 0 && !empty($errors)) {
            wp_send_json_error(implode("\n", $errors));
        }

        $message = sprintf(_n('Successfully created %d translation.', 'Successfully created %d translations.', $translated_count, 'roidnet-ai-content-generator'), $translated_count);
        if ($failed_count > 0) {
            $message .= ' ' . sprintf(__('(%d translations skipped or failed)', 'roidnet-ai-content-generator'), $failed_count);
        }

        wp_send_json_success(array(
            'message' => $message,
            'errors' => $errors,
        ));
    }

    /**
     * Get active site languages
     */
    private function get_active_languages()
    {
        $langs = array();
        
        if (function_exists('pll_languages_list')) {
            $slugs = pll_languages_list(array('fields' => 'slug')) ?: array();
            $names = pll_languages_list(array('fields' => 'name')) ?: array();
            if (count($slugs) === count($names) && !empty($slugs)) {
                $langs = array_combine($slugs, $names);
            } else {
                foreach ($slugs as $slug) {
                    $langs[$slug] = strtoupper($slug);
                }
            }
        }
        elseif (function_exists('wpml_get_active_languages_filter') || has_filter('wpml_active_languages')) {
            $wpml_langs = apply_filters('wpml_active_languages', null, array('skip_missing' => 0));
            if (is_array($wpml_langs)) {
                foreach ($wpml_langs as $lang) {
                    $langs[$lang['code']] = $lang['english_name'];
                }
            }
        }
        
        if (empty($langs)) {
            $locale = get_locale();
            $lang_code = substr($locale, 0, 2);
            $lang_name = strtoupper($lang_code);
            if ($lang_code === 'en') {
                $lang_name = __('English', 'roidnet-ai-content-generator');
            } elseif ($lang_code === 'ar') {
                $lang_name = __('Arabic', 'roidnet-ai-content-generator');
            } elseif ($lang_code === 'tr') {
                $lang_name = __('Turkish', 'roidnet-ai-content-generator');
            }
            $langs = array(
                $lang_code => $lang_name
            );
        }
        
        return $langs;
    }

    /**
     * Map language code to human-readable name for translation prompt context
     */
    private function get_language_name($code)
    {
        $languages = array(
            'en' => 'English',
            'ar' => 'Arabic',
            'tr' => 'Turkish',
            'fr' => 'French',
            'de' => 'German',
            'es' => 'Spanish',
            'it' => 'Italian',
            'ru' => 'Russian',
            'zh' => 'Chinese',
            'ja' => 'Japanese',
            'pt' => 'Portuguese',
            'nl' => 'Dutch',
            'pl' => 'Polish',
            'fa' => 'Persian',
        );

        return isset($languages[$code]) ? $languages[$code] : $code;
    }

    /**
     * AJAX: Delete keyword from queue
     */
    public function ajax_delete_keyword()
    {
        check_ajax_referer('roidaico_nonce', 'nonce');

        if (!current_user_can('edit_posts')) {
            wp_send_json_error(__('Permission denied.', 'roidnet-ai-content-generator'));
        }

        $keyword_id = absint($_POST['keyword_id'] ?? 0);

        if (!$keyword_id) {
            wp_send_json_error(__('Keyword ID is required.', 'roidnet-ai-content-generator'));
        }

        $result = $this->keyword_manager->delete_keyword($keyword_id);

        if (!$result) {
            wp_send_json_error(__('Failed to delete keyword.', 'roidnet-ai-content-generator'));
        }

        wp_send_json_success(__('Keyword deleted.', 'roidnet-ai-content-generator'));
    }

    /**
     * AJAX: Save schedule
     */
    public function ajax_save_schedule()
    {
        check_ajax_referer('roidaico_nonce', 'nonce');

        if (!current_user_can('manage_options')) {
            wp_send_json_error(__('Permission denied.', 'roidnet-ai-content-generator'));
        }

        // Get and validate times JSON
        $times_raw = wp_unslash($_POST['times'] ?? '[]');
        $times_array = json_decode($times_raw, true);
        if (!is_array($times_array)) {
            $times_raw = '[]';
            $times_array = array();
        }

        // Get and validate options JSON
        $options_raw = wp_unslash($_POST['options'] ?? '{}');
        $options_array = json_decode($options_raw, true);
        if (!is_array($options_array)) {
            $options_raw = '{}';
        }

        // Check weekly slots limit for free users (days × times ≤ 4)
        $days_string = sanitize_text_field($_POST['days'] ?? '');
        $days_array = array_filter(explode(',', $days_string));
        $total_weekly_slots = count($days_array) * count($times_array);
        
        if ( ! License_Manager::is_pro() && $total_weekly_slots > 4 ) {
            wp_send_json_error(
                sprintf(
                    __('Free version limit: Maximum 4 publish slots per week. You selected %d days × %d times = %d slots. Upgrade to Pro for unlimited scheduling!', 'roidnet-ai-content-generator'),
                    count($days_array),
                    count($times_array),
                    $total_weekly_slots
                )
            );
        }

        $schedule_data = array(
            'id' => absint($_POST['id'] ?? 0),
            'name' => sanitize_text_field($_POST['name'] ?? ''),
            'category_id' => absint($_POST['category_id'] ?? 0),
            'days' => sanitize_text_field($_POST['days'] ?? ''),
            'times' => $times_raw,
            'post_type' => sanitize_text_field($_POST['post_type'] ?? 'post'),
            'author_id' => absint($_POST['author_id'] ?? 0),
            'options' => $options_raw,
            'enabled' => absint($_POST['enabled'] ?? 1),
        );

        $result = $this->scheduler->save_schedule($schedule_data);

        if (is_wp_error($result)) {
            wp_send_json_error($result->get_error_message());
        }

        wp_send_json_success(array(
            'id' => $result,
            'message' => __('Schedule saved.', 'roidnet-ai-content-generator'),
        ));
    }

    /**
     * AJAX: Delete schedule
     */
    public function ajax_delete_schedule()
    {
        check_ajax_referer('roidaico_nonce', 'nonce');

        if (!current_user_can('manage_options')) {
            wp_send_json_error(__('Permission denied.', 'roidnet-ai-content-generator'));
        }

        $schedule_id = absint($_POST['schedule_id'] ?? 0);

        $result = $this->scheduler->delete_schedule($schedule_id);

        if (!$result) {
            wp_send_json_error(__('Failed to delete schedule.', 'roidnet-ai-content-generator'));
        }

        wp_send_json_success(__('Schedule deleted.', 'roidnet-ai-content-generator'));
    }

    /**
     * AJAX: Toggle schedule enabled/disabled
     */
    public function ajax_toggle_schedule()
    {
        check_ajax_referer('roidaico_nonce', 'nonce');

        if (!current_user_can('manage_options')) {
            wp_send_json_error(__('Permission denied.', 'roidnet-ai-content-generator'));
        }

        $schedule_id = absint($_POST['schedule_id'] ?? 0);
        $enabled = absint($_POST['enabled'] ?? 0);

        $result = $this->scheduler->toggle_schedule($schedule_id, $enabled);

        if (!$result) {
            wp_send_json_error(__('Failed to update schedule.', 'roidnet-ai-content-generator'));
        }

        wp_send_json_success(__('Schedule updated.', 'roidnet-ai-content-generator'));
    }

    /**
     * AJAX: Run schedule now (manual trigger)
     */
    public function ajax_run_schedule_now()
    {
        check_ajax_referer('roidaico_nonce', 'nonce');

        if (!current_user_can('manage_options')) {
            wp_send_json_error(__('Permission denied.', 'roidnet-ai-content-generator'));
        }

        $schedule_id = absint($_POST['schedule_id'] ?? 0);

        if (!$schedule_id) {
            wp_send_json_error(__('Schedule ID is required.', 'roidnet-ai-content-generator'));
        }

        // Get the schedule
        $schedule = $this->scheduler->get_schedule($schedule_id);

        if (!$schedule) {
            wp_send_json_error(__('Schedule not found.', 'roidnet-ai-content-generator'));
        }

        // Get next keyword from queue (use null if category_id is 0 to get any pending)
        $category_id = $schedule->category_id > 0 ? $schedule->category_id : null;
        $keyword = $this->keyword_manager->get_next_pending($category_id);

        if (!$keyword) {
            wp_send_json_error(__('No pending keywords found. Please add keywords to the queue first.', 'roidnet-ai-content-generator'));
        }

        // Parse options
        $options = json_decode($schedule->options, true) ?: array();
        $options['category_id'] = $schedule->category_id;
        $options['post_type'] = $schedule->post_type;
        $options['author_id'] = $schedule->author_id;
        $options['schedule_id'] = $schedule->id;
        $options['post_status'] = 'draft'; // Create as draft for manual review

        // Generate content
        $result = $this->content_generator->generate_from_keyword($keyword->id, $options);

        if (is_wp_error($result)) {
            wp_send_json_error($result->get_error_message());
        }

        wp_send_json_success(array(
            'post_id' => $result,
            'message' => sprintf(__('Article generated successfully! Keyword: %s', 'roidnet-ai-content-generator'), $keyword->keyword),
            'edit_url' => get_edit_post_link($result, 'raw'),
        ));
    }

    /**
     * AJAX: Activate license key via Freemius SDK.
     *
     * Uses the SDK's public opt_in() method which handles both:
     * - Registered users: Activates the license on the existing install.
     * - Unregistered users: Creates a new install + activates the license in one step.
     *
     * Note: The SDK's built-in fs_activate_license_{id} AJAX action is NOT registered
     * in the free version without a license (see _add_license_activation() guard at line ~13229),
     * so we must use our own custom handler.
     */
    public function ajax_activate_license()
    {
        check_ajax_referer('roidaico_nonce', 'nonce');

        if (!current_user_can('manage_options')) {
            wp_send_json_error(__('Permission denied.', 'roidnet-ai-content-generator'));
        }

        if (!function_exists('roidaico_fs')) {
            wp_send_json_error(__('Freemius SDK not available.', 'roidnet-ai-content-generator'));
        }

        $license_key = sanitize_text_field(wp_unslash($_POST['license_key'] ?? ''));

        if (empty($license_key)) {
            wp_send_json_error(__('Please enter a license key.', 'roidnet-ai-content-generator'));
        }

        $fs = roidaico_fs();

        // Use the SDK's public opt_in() method with the license key.
        // This handles BOTH registered and unregistered users:
        // - For unregistered users: creates install + activates license via Freemius API
        // - For registered users: same API call updates the existing install with the license
        $result = $fs->opt_in(
            false,          // $email — auto-detect from current WP user
            false,          // $first — auto-detect
            false,          // $last — auto-detect
            $license_key,   // $license_key — the key to activate
            false,          // $is_uninstall
            false,          // $trial_plan_id
            false,          // $is_disconnected
            null,           // $is_marketing_allowed
            array(),        // $sites
            true,           // $redirect — true = return result instead of redirecting
            null            // $license_owner_id
        );

        // Check for errors in the result.
        if (is_object($result) && isset($result->error)) {
            $error_message = is_object($result->error) && isset($result->error->message)
                ? $result->error->message
                : (is_string($result->error) ? $result->error : __('License activation failed.', 'roidnet-ai-content-generator'));
            wp_send_json_error($error_message);
        }

        // opt_in() returns false on empty API response.
        if (false === $result) {
            wp_send_json_error(__('License activation failed. Please check your license key and try again.', 'roidnet-ai-content-generator'));
        }

        // opt_in() returns a string (URL) on success when $redirect=false for some flows,
        // or an object with install data. Either way, if no error, it succeeded.
        //
        // Single-build model: Pro features activate immediately in-place.
        // No separate premium version download is needed.
        wp_send_json_success( array(
            'message' => __( 'License activated! Your Pro features are now unlocked. Reloading...', 'roidnet-ai-content-generator' ),
        ) );
    }

    /**
     * Get the translated category ID for a given target language using Polylang or WPML
     */
    private function get_translated_category_id($category_id, $target_lang)
    {
        if (empty($category_id)) {
            return 0;
        }

        // Polylang
        if (function_exists('pll_get_term')) {
            $translated_id = pll_get_term($category_id, $target_lang);
            if ($translated_id) {
                return (int) $translated_id;
            }
        }
        // WPML
        elseif (has_filter('wpml_object_id')) {
            $translated_id = apply_filters('wpml_object_id', $category_id, 'category', true, $target_lang);
            if ($translated_id) {
                return (int) $translated_id;
            }
        }

        return $category_id;
    }
}
