<?php

if (!defined('ABSPATH')) {
    exit;
}

define('AIEO_CHAT_VERSION', '4.1');
define('AIEO_CHAT_FILE', __FILE__);
define('AIEO_CHAT_DIR', plugin_dir_path(__FILE__));
define('AIEO_CHAT_URI', plugin_dir_url(__FILE__));

class AI_eShop_Chat {

    
    private static $instance = null;

    
    public static function get_instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    
    private function __construct() {
        $this->init_hooks();

        
        
        if (get_option('aieo_chat_split_loader', 0)) {
            return;
        }

        
        
        
        
        
        
        
        
        if ($this->context_needs_engine()) {
            $this->load_dependencies();
        } else {
            $this->load_frontend_only();
        }
    }

    
    private function context_needs_engine() {
        if (is_admin()
            || (defined('DOING_CRON') && DOING_CRON)
            || (defined('DOING_AJAX') && DOING_AJAX)
            || (defined('WP_CLI') && WP_CLI)) {
            return true;
        }

        $uri = isset($_SERVER['REQUEST_URI']) ? (string) wp_unslash($_SERVER['REQUEST_URI']) : '';

        
        return ($uri !== '' && strpos($uri, 'aieo-chat/') !== false);
    }

    
    private function load_frontend_only() {
        require_once AIEO_CHAT_DIR . 'includes/chat/class-shortcode-handler.php';
        AI_eShop_Chat_Shortcode::get_instance();
    }

    
    private function init_hooks() {
        
        
        
        
        register_activation_hook(AIEO_CHAT_FILE, array($this, 'activate'));
        register_deactivation_hook(AIEO_CHAT_FILE, array($this, 'deactivate'));

        
        
        
        
        add_action('admin_init', array($this, 'heal_auto_event_scheduling'));

        if (get_option('aieo_chat_split_loader', 0)) {
            $this->init_hooks_split();
            return;
        }

        
        add_action('init', array($this, 'load_textdomain'), 0);
        add_action('admin_menu', array($this, 'add_admin_menu'), 60);
        add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_assets'));
        add_action('wp_enqueue_scripts', array($this, 'enqueue_frontend_assets'));
        add_action('wp_footer', array($this, 'render_floating_widget'), 999);
        add_action('wp_ajax_aieo_chat_save_content_selection', array($this, 'ajax_save_content_selection'));
        add_action('wp_ajax_aieo_chat_save_settings', array($this, 'ajax_save_settings'));
        add_action('admin_init', array($this, 'check_tables'));
        add_filter('admin_footer_text', array($this, 'aieo_chat_footer_text'), 11);
        add_filter('cron_schedules', array($this, 'add_cron_schedules'));
        add_action('aieo_auto_analytics_event', array($this, 'run_auto_analytics'));
        add_action('aieo_auto_embeddings_event', array($this, 'run_auto_embeddings'));
    }

    
    private function init_hooks_split() {
        $context = class_exists('AIEO_Module_Manifest')
            ? AIEO_Module_Manifest::resolve_context()
            : 'other_frontend';

        $loaders = array();
        switch ($context) {
            case 'admin':
            case 'admin_ajax':
                $loaders[] = 'admin-loader.php';
                break;
            case 'rest_api':
                $loaders[] = 'rest-loader.php';
                break;
            case 'cron':
                $loaders[] = 'cron-loader.php';
                break;
            default:
                
                $loaders[] = 'frontend-loader.php';
                break;
        }

        foreach ($loaders as $loader) {
            $path = AIEO_CHAT_DIR . 'includes/chat/loaders/' . $loader;
            if (!file_exists($path)) { continue; }
            $register = include $path;
            if (is_callable($register)) { $register($this); }
        }
    }

    
    public function load_dependencies_public() {
        $this->load_dependencies();
    }

    
    public function check_tables() {
        global $wpdb;
        $embeddings_table = $wpdb->prefix . 'aieo_chat_embeddings';
        $history_table = $wpdb->prefix . 'aieo_chat_history';
        $business_info_table = $wpdb->prefix . 'aieo_chat_business_info';

        
        
        $embeddings_exists = $wpdb->get_var("SHOW TABLES LIKE '$embeddings_table'") === $embeddings_table;
        
        $history_exists = $wpdb->get_var("SHOW TABLES LIKE '$history_table'") === $history_table;
        
        $business_info_exists = $wpdb->get_var("SHOW TABLES LIKE '$business_info_table'") === $business_info_table;

        if (!$embeddings_exists || !$history_exists) {
            $this->load_dependencies(); 
            AI_eShop_Chat_Database_Manager::get_instance()->create_tables();
        }

        if (!$business_info_exists) {
            $this->load_dependencies(); 
            AI_eShop_Chat_Business_Info_Manager::get_instance()->create_table();
        }
    }

    
    private function load_dependencies() {
        
        require_once AIEO_CHAT_DIR . 'includes/chat/class-anthropic-api.php';
        require_once AIEO_CHAT_DIR . 'includes/chat/class-openai-api.php';
        require_once AIEO_CHAT_DIR . 'includes/chat/class-database-manager.php';
        require_once AIEO_CHAT_DIR . 'includes/chat/class-product-vitals-helper.php';
        require_once AIEO_CHAT_DIR . 'includes/chat/class-embedding-manager.php';
        require_once AIEO_CHAT_DIR . 'includes/chat/class-chat-api.php';
        require_once AIEO_CHAT_DIR . 'includes/chat/class-content-extractor.php';
        require_once AIEO_CHAT_DIR . 'includes/chat/class-shortcode-handler.php';
        require_once AIEO_CHAT_DIR . 'includes/chat/class-rest-api.php';
        require_once AIEO_CHAT_DIR . 'includes/chat/class-model-registry.php';
        require_once AIEO_CHAT_DIR . 'includes/chat/class-business-info-manager.php';

        
        AI_eShop_Chat_Database_Manager::get_instance();
        AI_eShop_Chat_Embedding_Manager::get_instance();
        AI_eShop_Chat_API::get_instance();
        AI_eShop_Chat_Shortcode::get_instance();
        AI_eShop_Chat_REST_API::get_instance();
        AI_eShop_Chat_Model_Registry::get_instance();
        AI_eShop_Chat_Business_Info_Manager::get_instance();
    }

    
    public function load_textdomain() {
        $domain = 'ai-eshop-optimizer';
        $locale = determine_locale();

        
        $mofile = WP_LANG_DIR . '/plugins/' . $domain . '-' . $locale . '.mo';
        if (file_exists($mofile)) {
            load_textdomain($domain, $mofile);
            return;
        }

        
        $plugin_mofile = dirname(__FILE__) . '/languages/' . $domain . '-' . $locale . '.mo';
        if (file_exists($plugin_mofile)) {
            load_textdomain($domain, $plugin_mofile);
            return;
        }

        
        
        load_plugin_textdomain(
            $domain,
            false,
            dirname(plugin_basename(__FILE__)) . '/languages'
        );
    }

    
    public function add_admin_menu() {
        global $menu;

        
        $parent_exists = false;
        if (!empty($menu)) {
            foreach ($menu as $item) {
                if (isset($item[2]) && $item[2] === 'ai-eshop-optimizer') {
                    $parent_exists = true;
                    break;
                }
            }
        }

        if ($parent_exists) {
            
            add_submenu_page(
                'ai-eshop-optimizer',                      
                __('AI Chat', 'ai-eshop-optimizer'),       
                __('🤖 AI Chat', 'ai-eshop-optimizer'),    
                'manage_options',                          
                'ai-eshop-chat',                          
                array($this, 'render_admin_page')         
            );
        } else {
            
            add_menu_page(
                __('AI Chat', 'ai-eshop-optimizer'),       
                __('AI Chat', 'ai-eshop-optimizer'),       
                'manage_options',                          
                'ai-eshop-chat',                          
                array($this, 'render_admin_page'),        
                'dashicons-format-chat',                   
                58                                         
            );
        }
    }

    
    public function render_admin_page() {
        require_once AIEO_CHAT_DIR . 'assets/pages/ai-eshop-chat.php';
    }

    
    public function aieo_chat_footer_text($content) {
        
        
        if (isset($_GET['page']) && $_GET['page'] === 'ai-eshop-chat') {
            
            if (class_exists('WooCommerce')) {
                return "Thank you for choosing <a href='https://eshop-optimizer.com'>AI eShop Optimizer</a> for Woocommerce by <i><a href='https://oxfordmetadata.co.uk'>Oxford Metadata Ltd</a></i>";
            } else {
                return "Thank you for choosing <a href='https://eshop-optimizer.com'>AI eShop Optimizer</a> for Wordpress by <i><a href='https://oxfordmetadata.co.uk'>Oxford Metadata Ltd</a></i>";
            }
        }

        return $content;
    }

    
    public function enqueue_admin_assets($hook) {
        
        
        if ('ai-eshop-optimizer_page_ai-eshop-chat' !== $hook &&
            (!isset($_GET['page']) || $_GET['page'] !== 'ai-eshop-chat')) {
            return;
        }

        
        wp_enqueue_style(
            'aieo-admin-panel',
            AIEO_URI . 'assets/css/aieo-admin-panel.css',
            array(),
            AIEO_VERSION
        );

        
        wp_enqueue_style(
            'aieo-chat-admin',
            AIEO_CHAT_URI . 'assets/css/chat-admin.css',
            array('aieo-admin-panel'),
            AIEO_CHAT_VERSION
        );

        
        wp_enqueue_style('wp-color-picker');
        wp_enqueue_script('wp-color-picker');

        
        wp_enqueue_media();

        
        
    }

    
    public function enqueue_frontend_assets() {
        
        $floating_enabled = get_option('aieo_chat_floating_enabled', '0') === '1';
        $has_shortcode = $this->page_has_chat_shortcode();

        
        if (!$floating_enabled && !$has_shortcode) {
            return;
        }

        wp_enqueue_style(
            'aieo-chat-frontend',
            AIEO_CHAT_URI . 'assets/css/chat-frontend.css',
            array(),
            AIEO_CHAT_VERSION
        );

        wp_enqueue_script(
            'aieo-chat-frontend',
            AIEO_CHAT_URI . 'assets/js/chat-frontend.js',
            array('jquery'),
            AIEO_CHAT_VERSION,
            true
        );

        
        $current_category = '';
        $current_blog_category = '';
        $current_cpt_category = '';

        
        if (class_exists('WooCommerce')) {
            if (is_product_category()) {
                $term = get_queried_object();
                if ($term && !is_wp_error($term)) {
                    $current_category = $this->get_top_category_for_term($term);
                }
            } elseif (is_product()) {
                global $post;
                if ($post) {
                    $current_category = $this->get_top_category_for_product($post->ID);
                }
            }
        }

        
        if (is_category()) {
            $term = get_queried_object();
            if ($term && !is_wp_error($term)) {
                $current_blog_category = $this->get_top_blog_category_for_term($term);
            }
        } elseif (is_single() && get_post_type() === 'post') {
            global $post;
            if ($post) {
                $current_blog_category = $this->get_top_blog_category_for_post($post->ID);
            }
        }

        
        $cpt_post_type = get_option('aieo_chat_cpt_post_type_slug', '');
        $cpt_taxonomy = get_option('aieo_chat_cpt_taxonomy_slug', '');
        if (!empty($cpt_post_type) && !empty($cpt_taxonomy)) {
            if (is_tax($cpt_taxonomy)) {
                $term = get_queried_object();
                if ($term && !is_wp_error($term)) {
                    $current_cpt_category = $this->get_top_cpt_category_for_term($term, $cpt_taxonomy);
                }
            } elseif (is_single() && get_post_type() === $cpt_post_type) {
                global $post;
                if ($post) {
                    $current_cpt_category = $this->get_top_cpt_category_for_post($post->ID, $cpt_taxonomy);
                }
            }
        }

        wp_localize_script('aieo-chat-frontend', 'aieoChatConfig', array(
            'restUrl' => rest_url('aieo-chat/v1/'),
            'restNonce' => wp_create_nonce('wp_rest'),
            'chatEnabled' => get_option('aieo_chat_enabled', '0'),
            'floatingEnabled' => get_option('aieo_chat_floating_enabled', '0'),
            'floatingPosition' => get_option('aieo_chat_floating_position', 'bottom-right'),
            'botName' => get_option('aieo_chat_bot_name', __('AI Assistant by Oxford Metadata', 'ai-eshop-optimizer')),
            'welcomeMessage' => get_option('aieo_chat_welcome_message', __('Hello! How can I help you find the perfect product today?', 'ai-eshop-optimizer')),
            'inputPlaceholder' => get_option('aieo_chat_input_placeholder', __('Ask about anything...', 'ai-eshop-optimizer')),
            'maxResults' => get_option('aieo_chat_max_results', 10),
            'hideImages' => get_option('aieo_chat_hide_images', '0'),
            'requireLogin' => get_option('aieo_chat_require_login', '0'),
            'showTerms' => get_option('aieo_chat_show_terms', '0'),
            'category_filter_enabled' => get_option('aieo_chat_category_filter_enabled', '0'),
            'blog_category_filter_enabled' => get_option('aieo_chat_blog_category_filter_enabled', '0'),
            'cpt_category_filter_enabled' => get_option('aieo_chat_cpt_category_filter_enabled', '0'),
            'cpt_post_type_slug' => $cpt_post_type,
            'cpt_taxonomy_slug' => $cpt_taxonomy,
            'currentCategory' => $current_category,
            'currentBlogCategory' => $current_blog_category,
            'currentCptCategory' => $current_cpt_category,
            'theme' => get_option('aieo_chat_theme', 'rounded'),
            'i18n' => array(
                'categoryPrompt' => __('Please select a product category to get started:', 'ai-eshop-optimizer'),
                'selectedCategory' => __('Selected category', 'ai-eshop-optimizer'),
                'categoryConfirm' => __('Great! I\'ll help you find products in the {category} category. What are you looking for?', 'ai-eshop-optimizer'),
                'changeCategoryHint' => __('Type "menu" or "μενού" to change category', 'ai-eshop-optimizer'),
                'categoryChangeHint' => __('Click a different category to change, or start chatting about {category} products', 'ai-eshop-optimizer'),
                'categorySwitched' => __('Switched to {category} category. I\'ll help you find products in this category.', 'ai-eshop-optimizer'),
                'allCategoriesSwitched' => __('Now searching across all categories. I\'ll help you find any product from our entire catalog.', 'ai-eshop-optimizer'),
                'helpingWithAllCategories' => __('I\'ll help you find any product from our entire catalog. What are you looking for?', 'ai-eshop-optimizer'),
                'menuReminder' => __('You can change categories anytime using the menu at the top of the chat.', 'ai-eshop-optimizer'),
                'helpingWithCategory' => __('I\'ll help you find products in the {category} category. If you need something else, please select a different category.', 'ai-eshop-optimizer'),
                'blogCategoryPrompt' => __('Please select a blog post category to get started:', 'ai-eshop-optimizer'),
                'blogCategoryConfirm' => __('Great! I\'ll help you find blog posts in the {category} category. What are you looking for?', 'ai-eshop-optimizer'),
                'blogCategorySwitched' => __('Switched to {category} category. I\'ll help you find blog posts in this category.', 'ai-eshop-optimizer'),
                'helpingWithBlogCategory' => __('I\'ll help you find blog posts in the {category} category. If you need something else, please select a different category.', 'ai-eshop-optimizer'),
                'cptCategoryPrompt' => __('Please select a category to get started:', 'ai-eshop-optimizer'),
                'cptCategoryConfirm' => __('Great! I\'ll help you find content in the {category} category. What are you looking for?', 'ai-eshop-optimizer'),
                'cptCategorySwitched' => __('Switched to {category} category. I\'ll help you find content in this category.', 'ai-eshop-optimizer'),
                'helpingWithCptCategory' => __('I\'ll help you find content in the {category} category. If you need something else, please select a different category.', 'ai-eshop-optimizer'),
                'feedbackPrompt' => __('Help me improve! Rate this answer:', 'ai-eshop-optimizer'),
                'feedbackSaved' => __('Thanks for your feedback!', 'ai-eshop-optimizer'),
                'feedbackError' => __('Could not save feedback', 'ai-eshop-optimizer')
            )
        ));
    }

    
    public function render_floating_widget() {
        
        $floating_enabled = get_option('aieo_chat_floating_enabled', '0');
        if ($floating_enabled !== '1') {
            return;
        }

        
        if (is_admin()) {
            return;
        }

        
        $position = get_option('aieo_chat_floating_position', 'bottom-right');
        $mobile_position = get_option('aieo_chat_floating_mobile_position', 'bottom-right');
        $bot_name = get_option('aieo_chat_bot_name', 'AI Assistant by Oxford Metadata');
        $custom_icon_id = intval(get_option('aieo_chat_floating_custom_icon', 0));
        $welcome_bubble = get_option('aieo_chat_floating_welcome_bubble', 'Hi! How can I help you?');
        $popup_width_raw = get_option('aieo_chat_floating_popup_width', '390');
        $popup_height_raw = get_option('aieo_chat_floating_popup_height', '600');
        $button_color = sanitize_hex_color(get_option('aieo_chat_floating_button_color', '#03163C'));
        $primary_color = sanitize_hex_color(get_option('aieo_chat_primary_color', '#47ACFE'));
        
        $aieo_fs = function ($opt, $def) {
            $v = trim((string) get_option($opt, ''));
            if ($v === '') { return $def; }
            return is_numeric($v) ? $v . 'px' : $v;
        };
        $btn_fs_d  = $aieo_fs('aieo_chat_btn_font_size_d', '13px');
        $btn_fs_m  = $aieo_fs('aieo_chat_btn_font_size_m', '12px');
        $text_fs_d = $aieo_fs('aieo_chat_text_font_size_d', '15px');
        $text_fs_m = $aieo_fs('aieo_chat_text_font_size_m', '14px');
        $chat_theme = get_option('aieo_chat_theme', 'rounded');

        
        if (empty($button_color)) {
            $button_color = '#03163C';
        }
        if (empty($primary_color)) {
            $primary_color = '#47ACFE';
        }

        
        $popup_width = $this->sanitize_dimension($popup_width_raw, '390px', 320, 800);
        $popup_height = $this->sanitize_dimension($popup_height_raw, '600px', 400, 900);

        
        $custom_icon_url = $custom_icon_id ? wp_get_attachment_image_url($custom_icon_id, 'thumbnail') : '';
        $use_custom_icon = !empty($custom_icon_url);

        
        $primary_rgb = sscanf($primary_color, "#%02x%02x%02x");
        $primary_color_light = sprintf('rgba(%d, %d, %d, 0.1)', $primary_rgb[0], $primary_rgb[1], $primary_rgb[2]);

        
        $button_rgb = sscanf($button_color, "#%02x%02x%02x");
        
        $button_rgb_dark = array(
            max(0, $button_rgb[0] * 0.85),
            max(0, $button_rgb[1] * 0.85),
            max(0, $button_rgb[2] * 0.85)
        );
        $button_color_dark = sprintf('#%02x%02x%02x', $button_rgb_dark[0], $button_rgb_dark[1], $button_rgb_dark[2]);
        $button_gradient = sprintf('linear-gradient(135deg, %s 0%%, %s 100%%)', $button_color, $button_color_dark);
        $button_shadow = sprintf('rgba(%d, %d, %d, 0.3)', $button_rgb[0], $button_rgb[1], $button_rgb[2]);

        ?>
        <!-- Custom Button and Primary Color Styles -->
        <style>
            :root {
                --aieo-chat-button-color: <?php echo esc_attr($button_color); ?>;
                --aieo-chat-button-gradient: <?php echo esc_attr($button_gradient); ?>;
                --aieo-chat-button-shadow: <?php echo esc_attr($button_shadow); ?>;
                --aieo-chat-primary-color: <?php echo esc_attr($primary_color); ?>;
                --aieo-chat-primary-color-light: <?php echo esc_attr($primary_color_light); ?>;
                --aieo-chat-btn-fs-d: <?php echo esc_attr($btn_fs_d); ?>;
                --aieo-chat-btn-fs-m: <?php echo esc_attr($btn_fs_m); ?>;
                --aieo-chat-text-fs-d: <?php echo esc_attr($text_fs_d); ?>;
                --aieo-chat-text-fs-m: <?php echo esc_attr($text_fs_m); ?>;
                --aieo-chat-btn-fs: var(--aieo-chat-btn-fs-d);
                --aieo-chat-text-fs: var(--aieo-chat-text-fs-d);
            }
            @media (max-width: 720px) {
                :root {
                    --aieo-chat-btn-fs: var(--aieo-chat-btn-fs-m, var(--aieo-chat-btn-fs-d));
                    --aieo-chat-text-fs: var(--aieo-chat-text-fs-m, var(--aieo-chat-text-fs-d));
                }
            }

            /* Use button color for trigger, header, and send button */
            .aieo-floating-trigger {
                background: var(--aieo-chat-button-gradient) !important;
                box-shadow: 0 4px 20px var(--aieo-chat-button-shadow) !important;
            }

            .aieo-floating-trigger:hover {
                box-shadow: 0 6px 30px var(--aieo-chat-button-shadow) !important;
            }

            .aieo-chat-header,
            .aieo-floating-chat-window .aieo-chat-header {
                background: var(--aieo-chat-button-gradient) !important;
                box-shadow: 0 2px 10px var(--aieo-chat-button-shadow) !important;
            }

            .aieo-chat-send-btn,
            #aieo-floating-chat-send {
                background: var(--aieo-chat-button-gradient) !important;
                box-shadow: 0 2px 8px var(--aieo-chat-button-shadow) !important;
            }

            .aieo-chat-send-btn:hover:not(:disabled),
            #aieo-floating-chat-send:hover:not(:disabled) {
                box-shadow: 0 4px 12px var(--aieo-chat-button-shadow) !important;
            }

            /* Chat input area - prevent theme interference */
            .aieo-chat-input-area {
                line-height: 1.5 !important;
                padding: 20px !important;
            }

            /* Ensure floating wrapper inherits all chat-wrapper styles */
            .aieo-floating-wrapper {
                display: block;
                width: 100%;
                height: 100%;
            }

            /* Floating chat message styling */
            #aieo-floating-chat-messages .aieo-chat-message {
                display: flex;
                flex-direction: column;
                gap: 0;
                margin-bottom: 16px;
                animation: slideIn 0.3s ease-out;
            }

            #aieo-floating-chat-messages .aieo-message-content {
                background: white;
                padding: 12px 16px;
                border-radius: 12px;
                box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
                flex: 1;
                line-height: 1.6;
                word-wrap: break-word;
                font-size: var(--aieo-chat-text-fs, 15px);
            }
            /* Operator text/button font-size — ID-scoped so it wins over the
               base chat-frontend.css class rules inside the floating widget. */
            #aieo-floating-chat-messages .aieo-message-content p {
                font-size: inherit;
            }
            #aieo-floating-chat-messages .aieo-chat-category-bubble {
                font-size: var(--aieo-chat-btn-fs, 13px);
            }

            #aieo-floating-chat-messages .aieo-message-content p {
                margin: 0 0 8px 0;
            }

            #aieo-floating-chat-messages .aieo-message-content p:last-child {
                margin-bottom: 0;
            }

            #aieo-floating-chat-messages .aieo-message-content strong {
                font-weight: 600;
                color: var(--aieo-chat-button-color, #03163C);
            }

            #aieo-floating-chat-messages .aieo-message-content em {
                font-style: italic;
            }

            #aieo-floating-chat-messages .aieo-message-content a {
                color: var(--aieo-chat-primary-color, #47ACFE);
                text-decoration: none;
                border-bottom: 1px solid var(--aieo-chat-primary-color, #47ACFE);
            }

            #aieo-floating-chat-messages .aieo-message-content a:hover {
                color: var(--aieo-chat-button-color, #03163C);
                border-bottom-color: var(--aieo-chat-button-color, #03163C);
            }

            #aieo-floating-chat-messages .aieo-chat-message-user .aieo-message-content {
                background: #F3F4F6;
            }

            /* Typing indicator */
            .aieo-chat-typing {
                display: flex;
                flex-direction: row;
                align-items: center;
                gap: 8px;
            }

            .aieo-chat-typing .aieo-chat-avatar-small {
                width: 36px;
                height: 36px;
                border-radius: 50%;
                background: #F3F4F6;
                display: flex;
                align-items: center;
                justify-content: center;
                font-size: 20px;
                flex-shrink: 0;
            }

            .aieo-chat-typing .aieo-chat-message-content {
                background: white;
                padding: 12px 16px;
                border-radius: 12px;
                box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
            }

            .aieo-chat-typing-dots {
                display: flex;
                align-items: center;
                gap: 6px;
            }

            .aieo-chat-typing-dots span {
                width: 10px;
                height: 10px;
                border-radius: 50%;
                background: var(--aieo-chat-primary-color, #47ACFE);
                animation: typing-bounce 1.4s infinite ease-in-out;
            }

            .aieo-chat-typing-dots span:nth-child(1) {
                animation-delay: -0.32s;
            }

            .aieo-chat-typing-dots span:nth-child(2) {
                animation-delay: -0.16s;
            }

            @keyframes typing-bounce {
                0%, 80%, 100% {
                    transform: scale(0.8);
                    opacity: 0.5;
                }
                40% {
                    transform: scale(1.2);
                    opacity: 1;
                }
            }

            /* Product slider - appears below AI response */
            .aieo-chat-products {
                display: flex;
                gap: 8px;
                overflow-x: auto;
                overflow-y: hidden;
                scroll-snap-type: x mandatory;
                -webkit-overflow-scrolling: touch;
                scrollbar-width: thin;
                scrollbar-color: var(--aieo-chat-primary-color, #47ACFE) #F3F4F6;
                padding: 8px 0;
                margin-top: 12px;
                width: 100%;
            }

            .aieo-chat-products::-webkit-scrollbar {
                height: 4px;
            }

            .aieo-chat-products::-webkit-scrollbar-track {
                background: #F3F4F6;
                border-radius: 2px;
            }

            .aieo-chat-products::-webkit-scrollbar-thumb {
                background: var(--aieo-chat-primary-color, #47ACFE);
                border-radius: 2px;
            }

            .aieo-chat-products::-webkit-scrollbar-thumb:hover {
                background: var(--aieo-chat-button-color, #03163C);
            }

            .aieo-chat-product {
                min-width: 160px;
                max-width: 160px;
                flex-shrink: 0;
                scroll-snap-align: start;
                background: white;
                border-radius: 8px;
                box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
                overflow: hidden;
                transition: transform 0.2s ease;
                display: flex;
                flex-direction: column;
            }

            .aieo-chat-product:hover {
                transform: scale(1.05);
                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
            }

            .aieo-chat-product-image {
                width: 100%;
                height: 100px;
                overflow: hidden;
                flex-shrink: 0;
            }

            .aieo-chat-product img {
                width: 100%;
                height: 100%;
                object-fit: cover;
                display: block;
            }

            .aieo-chat-product-info {
                background: var(--aieo-chat-button-color);
                padding: 8px;
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                gap: 4px;
                flex: 1;
                min-height: 60px;
            }

            .aieo-chat-product h4 {
                margin: 0;
                padding: 0;
                color: white;
                font-size: 11px;
                line-height: 1.3;
                text-align: center;
                font-weight: 600;
                overflow: hidden;
                text-overflow: ellipsis;
                display: -webkit-box;
                -webkit-line-clamp: 2;
                -webkit-box-orient: vertical;
                max-height: 2.6em;
                width: 100%;
            }

            .aieo-chat-product h4 a {
                color: white;
                text-decoration: none;
            }

            .aieo-chat-product .price {
                margin: 0;
                padding: 0;
                font-size: 13px;
                font-weight: bold;
                color: white;
                text-align: center;
                display: flex;
                align-items: center;
                justify-content: center;
                gap: 6px;
                flex-wrap: wrap;
            }

            .aieo-chat-product .price * {
                margin: 0 !important;
                padding: 0 !important;
                line-height: 1.2 !important;
            }

            .aieo-chat-product .price br {
                display: none;
            }

            .aieo-chat-product .price .screen-reader-text,
            .aieo-chat-product .price .woocommerce-ultimate-pricing-tooltip {
                display: none !important;
            }

            .aieo-chat-product .price del {
                color: rgba(255, 255, 255, 0.85) !important;
                font-size: 11px;
                order: 1;
            }

            .aieo-chat-product .price ins {
                text-decoration: none;
                background: none;
                color: white;
                font-weight: bold;
                order: 2;
            }

            .aieo-chat-product .price .woocommerce-Price-amount {
                display: inline;
                color: white;
            }

            .aieo-chat-product .price del .woocommerce-Price-amount {
                color: inherit;
            }

            /* Chat terms - reset theme line-height */
            .aieo-chat-terms {
                line-height: 1.4 !important;
                margin-top: 0 !important;
                margin-bottom: 12px !important;
            }

            /* Chat input wrapper - proper spacing */
            .aieo-chat-input-wrapper {
                gap: 12px !important;
                padding: 0 5px !important;
            }

            /* Chat input - reset all theme styles */
            .aieo-chat-input,
            #aieo-floating-chat-input {
                all: unset;
                box-sizing: border-box;
                flex: 1;
                padding: 12px 16px !important;
                border: 2px solid #E5E7EB !important;
                border-radius: 24px !important;
                font-size: var(--aieo-chat-text-fs, 1em) !important;
                font-family: inherit !important;
                line-height: 1.5 !important;
                color: #1F2937 !important;
                background: white !important;
                width: 100% !important;
                display: block !important;
                margin: 0 !important;
                box-shadow: none !important;
                transition: all 0.3s ease !important;
            }

            .aieo-chat-input:focus,
            #aieo-floating-chat-input:focus {
                border-color: var(--aieo-chat-button-color) !important;
                box-shadow: 0 0 0 3px var(--aieo-chat-button-shadow) !important;
                outline: none !important;
            }

            /* Send button - ensure proper shape and positioning */
            .aieo-chat-send-btn,
            #aieo-floating-chat-send {
                width: 48px !important;
                height: 48px !important;
                min-width: 48px !important;
                min-height: 48px !important;
                border: none !important;
                border-radius: 50% !important;
                color: white !important;
                cursor: pointer !important;
                display: flex !important;
                align-items: center !important;
                justify-content: center !important;
                transition: all 0.3s ease !important;
                padding: 0 !important;
                flex-shrink: 0 !important;
            }

            /* Theme: Rounded (default - modern with shadows).
             *
             * `!important` was stripped from these rules so a host
             * plugin/theme can override the popup's chrome via plain
             * CSS cascade (later origin / higher specificity). The
             * defaults still apply on standalone installs because
             * nothing else competes. On Rooster X / AIEO Side Cart the
             * launcher publishes its own #aieo-floating-chat-window
             * rules and wins by ID-vs-class specificity. */
            <?php if ($chat_theme === 'rounded') : ?>
            .aieo-floating-chat-window {
                border-radius: 16px;
                box-shadow: 0 10px 50px rgba(0, 0, 0, 0.2);
            }

            .aieo-chat-container {
                border-radius: 16px;
                box-shadow: 0 10px 40px var(--aieo-chat-button-shadow);
            }

            .aieo-chat-message-content {
                border-radius: 12px;
                box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
            }

            .aieo-chat-product {
                border-radius: 12px;
                box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
            }
            <?php else : ?>
            /* Theme: Square (clean and minimal) — same `!important`
             * stripping rationale as the rounded theme above. */
            .aieo-floating-chat-window {
                border-radius: 4px;
                box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
            }

            .aieo-chat-container {
                border-radius: 4px;
                box-shadow: none;
                border: 1px solid #E5E7EB;
            }

            .aieo-chat-message-content {
                border-radius: 4px;
                box-shadow: none;
                border: 1px solid #E5E7EB;
            }

            .aieo-chat-product {
                border-radius: 4px;
                box-shadow: none;
                border: 1px solid #E5E7EB;
            }

            .aieo-chat-input,
            #aieo-floating-chat-input {
                border-radius: 4px;
            }

            .aieo-chat-send-btn,
            #aieo-floating-chat-send {
                border-radius: 4px;
            }
            <?php endif; ?>

            .aieo-chat-message.user {
                background: var(--aieo-chat-primary-color-light) !important;
                color: var(--aieo-chat-primary-color) !important;
            }

            .aieo-chat-container a {
                color: var(--aieo-chat-primary-color) !important;
            }

            /* Feedback Slider Styles for Floating Chat */
            #aieo-floating-chat-messages .aieo-chat-feedback {
                margin-top: 10px;
                padding: 8px 12px;
                background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
                border-radius: 8px;
                border: 1px solid rgba(3, 22, 60, 0.08);
                box-sizing: border-box;
                width: 100%;
            }

            #aieo-floating-chat-messages .aieo-chat-feedback-label {
                font-size: 11px;
                color: #6B7280;
                margin-bottom: 6px;
                text-align: center;
            }

            #aieo-floating-chat-messages .aieo-chat-feedback-slider-container {
                display: flex;
                align-items: center;
                gap: 8px;
                width: 100%;
            }

            #aieo-floating-chat-messages .aieo-chat-feedback-emoji {
                font-size: 14px;
                line-height: 1;
                flex-shrink: 0;
            }

            #aieo-floating-chat-messages .aieo-chat-feedback-slider {
                flex: 1;
                -webkit-appearance: none;
                appearance: none;
                height: 6px;
                border-radius: 3px;
                background: linear-gradient(to right, #EF4444 0%, #F59E0B 50%, #22C55E 100%);
                outline: none;
                cursor: pointer;
                width: 100%;
                min-width: 0;
            }

            #aieo-floating-chat-messages .aieo-chat-feedback-slider::-webkit-slider-thumb {
                -webkit-appearance: none;
                appearance: none;
                width: 16px;
                height: 16px;
                border-radius: 50%;
                background: white;
                border: 2px solid var(--slider-color, #F59E0B);
                cursor: pointer;
                box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
            }

            #aieo-floating-chat-messages .aieo-chat-feedback-slider::-moz-range-thumb {
                width: 16px;
                height: 16px;
                border-radius: 50%;
                background: white;
                border: 2px solid var(--slider-color, #F59E0B);
                cursor: pointer;
                box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
            }

            #aieo-floating-chat-messages .aieo-chat-feedback-slider::-moz-range-track {
                height: 6px;
                border-radius: 3px;
                background: linear-gradient(to right, #EF4444 0%, #F59E0B 50%, #22C55E 100%);
            }

            #aieo-floating-chat-messages .aieo-chat-feedback-status {
                font-size: 10px;
                text-align: center;
                margin-top: 4px;
                min-height: 14px;
            }

            #aieo-floating-chat-messages .aieo-chat-feedback-saved {
                color: #22C55E;
                font-weight: 500;
            }

            #aieo-floating-chat-messages .aieo-chat-feedback-error {
                color: #EF4444;
                font-weight: 500;
            }
        </style>

        <!-- AI eShop Chat Floating Widget -->
        <div class="aieo-floating-chat-widget">
            <!-- Welcome Bubble (shows on first visit only) -->
            <div class="aieo-floating-welcome-bubble hidden <?php echo esc_attr($position); ?> mobile-<?php echo esc_attr($mobile_position); ?>" id="aieo-floating-welcome-bubble">
                <div class="aieo-floating-welcome-bubble-content">
                    <?php echo wp_kses_post($welcome_bubble); ?>
                </div>
                <div class="aieo-floating-welcome-bubble-arrow"></div>
            </div>

            <!-- Floating Button -->
            <div id="aieo-floating-chat-trigger" class="aieo-floating-trigger <?php echo esc_attr($position); ?> mobile-<?php echo esc_attr($mobile_position); ?>" style="display: none;">
                <?php if ($use_custom_icon) : ?>
                    <img src="<?php echo esc_url($custom_icon_url); ?>" alt="Chat" class="aieo-floating-custom-icon" style="width: 28px; height: 28px;" />
                <?php else : ?>
                    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                        <path d="M20 2H4C2.9 2 2 2.9 2 4V22L6 18H20C21.1 18 22 17.1 22 16V4C22 2.9 21.1 2 20 2ZM20 16H6L4 18V4H20V16Z" fill="white"/>
                        <path d="M7 9H17V11H7V9ZM7 12H14V14H7V12Z" fill="white"/>
                    </svg>
                <?php endif; ?>
            </div>

            <!-- Chat Popup -->
            <!--
                The saved popup_width / popup_height options describe the
                MOBILE size — desktop should use the CSS default (520×720,
                resizable) from chat-frontend.css. We therefore emit the
                saved dimensions inside a mobile-scoped @media rule rather
                than as an unconditional inline `style` attribute, otherwise
                desktop also gets the (smaller) mobile size and the `resize`
                handle has no headroom.
            -->
            <style>
                @media (max-width: 768px) {
                    #aieo-floating-chat-window {
                        width: <?php echo esc_attr($popup_width); ?>;
                        height: <?php echo esc_attr($popup_height); ?>;
                    }
                }
            </style>
            <div id="aieo-floating-chat-window" class="aieo-floating-chat-window <?php echo esc_attr($position); ?> mobile-<?php echo esc_attr($mobile_position); ?>" style="display: none;">
                <!-- Custom resize handles. CSS `resize: both` only emits one
                     handle at the bottom-right corner; these add the other
                     three corners + four edges. The JS resizer initialises
                     them on first chat open and is anchor-aware (knows
                     whether the popup is bottom-right / bottom-left / top-
                     right / top-left and grows the size by extending the
                     unanchored side). Hidden on mobile via the @media
                     block in chat-frontend.css. -->
                <div class="aieo-resize-handle aieo-resize-n"  data-aieo-resize="n"></div>
                <div class="aieo-resize-handle aieo-resize-s"  data-aieo-resize="s"></div>
                <div class="aieo-resize-handle aieo-resize-w"  data-aieo-resize="w"></div>
                <div class="aieo-resize-handle aieo-resize-e"  data-aieo-resize="e"></div>
                <div class="aieo-resize-handle aieo-resize-nw" data-aieo-resize="nw"></div>
                <div class="aieo-resize-handle aieo-resize-ne" data-aieo-resize="ne"></div>
                <div class="aieo-resize-handle aieo-resize-sw" data-aieo-resize="sw"></div>
                <div class="aieo-resize-handle aieo-resize-se" data-aieo-resize="se"></div>
                <div class="aieo-chat-wrapper aieo-floating-chat-wrapper">
                    <div class="aieo-chat-container">
                        <div class="aieo-chat-header">
                            <div class="aieo-chat-avatar">🤖</div>
                            <div class="aieo-chat-title">
                                <strong><?php echo esc_html($bot_name); ?></strong>
                                <span class="aieo-chat-status"><?php esc_html_e('● Online', 'ai-eshop-optimizer'); ?></span>
                            </div>
                            <button id="aieo-chat-close" class="aieo-chat-close" title="<?php esc_attr_e('Close chat', 'ai-eshop-optimizer'); ?>">&times;</button>
                        </div>
                        <div class="aieo-chat-messages" id="aieo-floating-chat-messages">
                            <!-- Welcome message will be added by JavaScript -->
                        </div>
                        <div class="aieo-chat-input-area">
                            <?php if (get_option('aieo_chat_show_terms', '0') === '1') : ?>
                                <div class="aieo-chat-terms">
                                    <?php esc_html_e('By using this chat, you agree to our terms of service.', 'ai-eshop-optimizer'); ?>
                                </div>
                            <?php endif; ?>
                            <div class="aieo-chat-input-wrapper">
                                <input type="text" id="aieo-floating-chat-input" class="aieo-chat-input" placeholder="<?php echo esc_attr(get_option('aieo_chat_input_placeholder', __('Ask about anything...', 'ai-eshop-optimizer'))); ?>" />
                                <button id="aieo-floating-chat-send" class="aieo-chat-send-btn">
                                    <svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor" transform="scale(-1, 1)">
                                        <path d="M2.553 9.106a1 1 0 000 1.788l14 7a1 1 0 001.409-1.169l-1.429-5A1 1 0 0115.571 11H11a1 1 0 110-2h4.571a1 1 0 00.962-.725l1.428-5a1 1 0 00-1.408-1.17l-14 7z"/>
                                    </svg>
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <script>
        /**
         * Floating Chat Widget - Optimized for Performance
         *
         * This script uses lazy initialization:
         * 1. Welcome bubble visibility is handled immediately (no DOM ready wait)
         * 2. Trigger button fades in after DOMContentLoaded
         * 3. Full chat initialization only happens when user clicks the trigger
         */
        (function() {
            // Check localStorage immediately to prevent flash
            var bubble = document.getElementById('aieo-floating-welcome-bubble');
            var dismissed = localStorage.getItem('aieo_floating_chat_bubble_dismissed');
            if (dismissed !== 'true' && bubble) {
                bubble.classList.remove('hidden');

                // Auto-hide after 10 seconds
                setTimeout(function() {
                    bubble.classList.add('hidden');
                    localStorage.setItem('aieo_floating_chat_bubble_dismissed', 'true');
                }, 10000);
            }

            // Show trigger button as soon as DOM is ready (lightweight operation)
            var showTrigger = function() {
                var trigger = document.getElementById('aieo-floating-chat-trigger');
                if (trigger) {
                    trigger.style.display = 'flex';
                    trigger.style.opacity = '0';
                    // Simple fade in without jQuery
                    requestAnimationFrame(function() {
                        trigger.style.transition = 'opacity 0.3s ease';
                        trigger.style.opacity = '1';
                    });
                }
            };

            if (document.readyState === 'loading') {
                document.addEventListener('DOMContentLoaded', showTrigger);
            } else {
                showTrigger();
            }
        })();

        // Floating chat initialization - only runs when user clicks the trigger
        function initFloatingChat() {
            var config = aieoChatConfig;
            var $messages = jQuery('#aieo-floating-chat-messages');
            var $input = jQuery('#aieo-floating-chat-input');
            var $sendBtn = jQuery('#aieo-floating-chat-send');
            var conversationId = null;
            var isProcessing = false;
            var selectedCategory = null;
            var hasShownWelcome = false;

            // Determine which category filter to use based on context
            var productCatEnabled = config.category_filter_enabled == '1' || config.category_filter_enabled == 1 || config.category_filter_enabled === true;
            var blogCatEnabled = config.blog_category_filter_enabled == '1' || config.blog_category_filter_enabled == 1 || config.blog_category_filter_enabled === true;
            var cptCatEnabled = config.cpt_category_filter_enabled == '1' || config.cpt_category_filter_enabled == 1 || config.cpt_category_filter_enabled === true;

            console.log('Category filter debug:', {
                productCatEnabled: productCatEnabled,
                blogCatEnabled: blogCatEnabled,
                cptCatEnabled: cptCatEnabled,
                currentCategory: config.currentCategory,
                currentBlogCategory: config.currentBlogCategory,
                currentCptCategory: config.currentCptCategory
            });

            // Load and show categories based on current context
            // Rule: If we're on a blog/CPT page AND that filter is enabled, show that type
            // Otherwise, show product categories if enabled (default fallback)
            var categoryTypeToShow = null;

            if (blogCatEnabled && config.currentBlogCategory && config.currentBlogCategory !== '') {
                // We're on a blog category page and blog filter is enabled - show blog categories
                categoryTypeToShow = 'blog';
            } else if (cptCatEnabled && config.currentCptCategory && config.currentCptCategory !== '') {
                // We're on a CPT category page and CPT filter is enabled - show CPT categories
                categoryTypeToShow = 'cpt';
            } else if (productCatEnabled) {
                // Default to product categories if enabled (works everywhere including blog pages when blog filter is disabled)
                categoryTypeToShow = 'product';
            } else if (blogCatEnabled) {
                // Fall back to blog categories if product categories not enabled
                categoryTypeToShow = 'blog';
            } else if (cptCatEnabled) {
                // Fall back to CPT categories
                categoryTypeToShow = 'cpt';
            }

            console.log('categoryTypeToShow:', categoryTypeToShow);

            if (categoryTypeToShow === 'product') {
                loadAndShowCategories(config.currentCategory || null, 'product');
            } else if (categoryTypeToShow === 'blog') {
                loadAndShowCategories(config.currentBlogCategory || null, 'blog');
            } else if (categoryTypeToShow === 'cpt') {
                loadAndShowCategories(config.currentCptCategory || null, 'cpt');
            } else {
                // Show welcome message only if categories are NOT enabled
                if (!hasShownWelcome) {
                    addMessage('assistant', config.welcomeMessage);
                    hasShownWelcome = true;
                }
            }

            // Send button click
            $sendBtn.on('click', sendMessage);

            // Block any host-page global key handlers from stealing the user's
            // typing while the chat input is focused. The brand-shopping
            // page (and probably others) bind document-level keydown to
            // jump to the matching letter section, which preventDefault's
            // the keystroke before it reaches the input — so the user can
            // see the page jump but no characters appear in the chat box.
            // Stopping propagation here keeps the input usable on every
            // host page without us having to know which pages do what.
            $input.on('keydown keypress keyup', function(e) {
                e.stopPropagation();
            });

            // Multi-edge resize for the floating window. CSS `resize: both`
            // only puts a grip at the bottom-right; these handles cover the
            // other 3 corners + 4 edges so the user can grab any side. The
            // logic is anchor-aware: when the window is bottom-right
            // anchored (default), we change width/height and the bottom-
            // right corner stays fixed in place. For top-anchored or left-
            // anchored placements we recompute top/left as well so the
            // anchor stays put visually. Disabled on mobile (no resize).
            (function initAieoResize() {
                if (window.matchMedia('(max-width: 768px)').matches) { return; }
                var winEl = document.getElementById('aieo-floating-chat-window');
                if (!winEl) { return; }

                function isAnchorRight()  { return winEl.classList.contains('bottom-right')  || winEl.classList.contains('top-right'); }
                function isAnchorBottom() { return winEl.classList.contains('bottom-right')  || winEl.classList.contains('bottom-left') || winEl.classList.contains('bottom-centre'); }

                winEl.querySelectorAll('.aieo-resize-handle').forEach(function (handle) {
                    handle.addEventListener('mousedown', function (downEvt) {
                        downEvt.preventDefault();
                        downEvt.stopPropagation();

                        var dir       = handle.getAttribute('data-aieo-resize'); // n,s,e,w,nw,ne,sw
                        var startX    = downEvt.clientX;
                        var startY    = downEvt.clientY;
                        var rect      = winEl.getBoundingClientRect();
                        var startW    = rect.width;
                        var startH    = rect.height;
                        var cs        = window.getComputedStyle(winEl);
                        var minW      = parseInt(cs.minWidth,  10) || 280;
                        var minH      = parseInt(cs.minHeight, 10) || 320;
                        var maxW      = window.innerWidth  - 20;
                        var maxH      = window.innerHeight - 20;
                        var anchoredR = isAnchorRight();
                        var anchoredB = isAnchorBottom();
                        var startTop  = rect.top;
                        var startLeft = rect.left;
                        document.body.style.userSelect = 'none';

                        function onMove(e) {
                            var dx = e.clientX - startX;
                            var dy = e.clientY - startY;
                            var newW = startW, newH = startH;

                            if (dir.indexOf('e') !== -1) { newW = startW + dx; }
                            if (dir.indexOf('w') !== -1) { newW = startW - dx; }
                            if (dir.indexOf('s') !== -1) { newH = startH + dy; }
                            if (dir.indexOf('n') !== -1) { newH = startH - dy; }

                            newW = Math.max(minW, Math.min(maxW, newW));
                            newH = Math.max(minH, Math.min(maxH, newH));
                            winEl.style.width  = newW + 'px';
                            winEl.style.height = newH + 'px';

                            // For sides that aren't anchored, we need to
                            // shift top/left so the OPPOSITE edge holds
                            // its position. CSS `right` / `bottom` cover
                            // the anchored cases automatically.
                            if (dir.indexOf('w') !== -1 && !anchoredR) {
                                winEl.style.left = (startLeft + (startW - newW)) + 'px';
                            }
                            if (dir.indexOf('n') !== -1 && !anchoredB) {
                                winEl.style.top  = (startTop  + (startH - newH)) + 'px';
                            }
                        }
                        function onUp() {
                            document.removeEventListener('mousemove', onMove);
                            document.removeEventListener('mouseup',   onUp);
                            document.body.style.userSelect = '';
                        }
                        document.addEventListener('mousemove', onMove);
                        document.addEventListener('mouseup',   onUp);
                    });
                });
            })();

            // Enter key press
            $input.on('keypress', function(e) {
                if (e.which === 13 && !isProcessing) {
                    sendMessage();
                }
            });

            function sendMessage() {
                var message = $input.val().trim();
                if (!message || isProcessing) {
                    return;
                }

                // Check for menu commands - since menu is persistent, just remind user
                var menuCommands = ['menu', 'μενού', 'μενου'];
                if (menuCommands.indexOf(message.toLowerCase()) !== -1) {
                    addMessage('user', message);
                    $input.val('');

                    // Show reminder message
                    var menuHint = config.i18n && config.i18n.menuReminder
                        ? config.i18n.menuReminder
                        : 'You can change categories anytime using the menu at the top of the chat.';
                    addMessage('assistant', menuHint);
                    return;
                }

                addMessage('user', message);
                $input.val('').focus();
                isProcessing = true;
                $sendBtn.prop('disabled', true);

                // Show typing indicator
                var $typing = jQuery('<div class="aieo-chat-message aieo-chat-message-assistant aieo-chat-typing"><div class="aieo-chat-avatar-small">🤖</div><div class="aieo-chat-message-content"><div class="aieo-chat-typing-dots"><span></span><span></span><span></span></div></div></div>');
                $messages.append($typing);
                scrollToBottom();

                // Prepare data
                var data = {
                    message: message,
                    conversation_id: conversationId
                };

                // Add category if selected
                if (selectedCategory) {
                    data.category = selectedCategory;
                }

                // Send to API
                jQuery.ajax({
                    url: config.restUrl + 'chat',
                    type: 'POST',
                    headers: {
                        'X-WP-Nonce': config.restNonce
                    },
                    data: JSON.stringify(data),
                    contentType: 'application/json',
                    success: function(response) {
                        console.log('Chat API Response:', response);
                        console.log('Products in response:', response.products);
                        console.log('Products count:', response.products ? response.products.length : 0);
                        console.log('Chat ID in response:', response.chat_id);
                        $typing.remove();
                        if (response.conversation_id) {
                            conversationId = response.conversation_id;
                        }
                        // Unified capture: link this chat turn to its origin page.
                        if (window.aieoChatTrack) { window.aieoChatTrack('chat_message', { conversation_id: conversationId }); }
                        addMessage('assistant', response.message, response.products, response.chat_id);
                    },
                    error: function() {
                        $typing.remove();
                        addMessage('assistant', 'Sorry, something went wrong. Please try again.');
                    },
                    complete: function() {
                        isProcessing = false;
                        $sendBtn.prop('disabled', false);
                        $input.focus();
                    }
                });
            }

            function addMessage(role, content, products, chatId) {
                console.log('addMessage called, $messages exists:', !!$messages, '$messages.length:', $messages ? $messages.length : 'N/A', 'chatId:', chatId);

                if (!$messages || $messages.length === 0) {
                    console.error('$messages is not available in addMessage!');
                    return;
                }

                var $msg = jQuery('<div class="aieo-chat-message aieo-chat-message-' + role + '"></div>');

                // For assistant messages, convert markdown to HTML. For user messages, escape HTML.
                var messageContent = role === 'assistant' ? convertMarkdownToHtml(content) : escapeHtml(content);
                var $messageContent = jQuery('<div class="aieo-message-content">' + messageContent + '</div>');
                $msg.append($messageContent);

                if (products && products.length > 0) {
                    var $products = jQuery('<div class="aieo-chat-products"></div>');
                    products.forEach(function(product) {
                        var $product = jQuery('<div class="aieo-chat-product"></div>');

                        // Image section
                        if (product.image && config.hideImages !== '1') {
                            var $imageDiv = jQuery('<div class="aieo-chat-product-image"></div>');
                            $imageDiv.append('<img src="' + escapeHtml(product.image) + '" alt="' + escapeHtml(product.title) + '">');
                            $product.append($imageDiv);
                        }

                        // Info section with button color background
                        var $infoDiv = jQuery('<div class="aieo-chat-product-info"></div>');
                        $infoDiv.append('<h4><a href="' + escapeHtml(product.url) + '">' + escapeHtml(product.title) + '</a></h4>');
                        if (product.price_html) {
                            $infoDiv.append('<div class="price">' + product.price_html + '</div>');
                        }
                        $product.append($infoDiv);

                        $products.append($product);
                    });
                    $msg.append($products); // Append as sibling to .aieo-message-content
                }

                // Add feedback slider for assistant messages with a chat_id
                if (role === 'assistant' && chatId) {
                    var feedbackText = config.i18n && config.i18n.feedbackPrompt ? config.i18n.feedbackPrompt : 'Help me improve! Rate this answer:';
                    var $feedback = jQuery('<div class="aieo-chat-feedback" data-chat-id="' + chatId + '"></div>');
                    $feedback.html(
                        '<div class="aieo-chat-feedback-label">' + escapeHtml(feedbackText) + '</div>' +
                        '<div class="aieo-chat-feedback-slider-container">' +
                            '<span class="aieo-chat-feedback-emoji">😞</span>' +
                            '<input type="range" class="aieo-chat-feedback-slider" min="0" max="100" value="50" />' +
                            '<span class="aieo-chat-feedback-emoji">😊</span>' +
                        '</div>' +
                        '<div class="aieo-chat-feedback-status"></div>'
                    );

                    var $slider = $feedback.find('.aieo-chat-feedback-slider');
                    var $status = $feedback.find('.aieo-chat-feedback-status');
                    var debounceTimer = null;

                    // Update slider track color based on value
                    function updateSliderColor(value) {
                        var color;
                        if (value < 50) {
                            // Red to yellow
                            var ratio = value / 50;
                            var r = 239;
                            var g = Math.round(68 + (158 * ratio));
                            var b = 68;
                            color = 'rgb(' + r + ', ' + g + ', ' + b + ')';
                        } else {
                            // Yellow to green
                            var ratio = (value - 50) / 50;
                            var r = Math.round(239 - (105 * ratio));
                            var g = Math.round(226 - (92 * ratio));
                            var b = Math.round(68 + (62 * ratio));
                            color = 'rgb(' + r + ', ' + g + ', ' + b + ')';
                        }
                        $slider.css('accent-color', color);
                    }

                    // Initial color
                    updateSliderColor(50);

                    $slider.on('input', function(e) {
                        var value = parseInt(e.target.value, 10);
                        updateSliderColor(value);

                        // Clear previous timer
                        if (debounceTimer) {
                            clearTimeout(debounceTimer);
                        }

                        // Debounce the save request
                        debounceTimer = setTimeout(function() {
                            saveRating(chatId, value, $status);
                        }, 500);
                    });

                    $msg.append($feedback);
                }

                $messages.append($msg);
                scrollToBottom();
            }

            function saveRating(chatId, rating, $status) {
                // Only save if rating is not the default (50)
                if (rating === 50) {
                    $status.text('').removeClass('aieo-chat-feedback-saved aieo-chat-feedback-error');
                    return;
                }

                var savedText = config.i18n && config.i18n.feedbackSaved ? config.i18n.feedbackSaved : 'Thanks for your feedback!';
                var errorText = config.i18n && config.i18n.feedbackError ? config.i18n.feedbackError : 'Could not save feedback';

                jQuery.ajax({
                    url: config.restUrl + 'rating',
                    type: 'POST',
                    headers: {
                        'X-WP-Nonce': config.restNonce
                    },
                    data: JSON.stringify({
                        chat_id: chatId,
                        rating: rating
                    }),
                    contentType: 'application/json'
                })
                .done(function() {
                    $status.text(savedText)
                        .removeClass('aieo-chat-feedback-error')
                        .addClass('aieo-chat-feedback-saved');
                })
                .fail(function() {
                    $status.text(errorText)
                        .removeClass('aieo-chat-feedback-saved')
                        .addClass('aieo-chat-feedback-error');
                });
            }

            function scrollToBottom() {
                if ($messages && $messages.length > 0 && $messages[0]) {
                    $messages.scrollTop($messages[0].scrollHeight);
                }
            }

            function escapeHtml(text) {
                var map = {
                    '&': '&amp;',
                    '<': '&lt;',
                    '>': '&gt;',
                    '"': '&quot;',
                    "'": '&#039;'
                };
                return String(text).replace(/[&<>"']/g, function(m) { return map[m]; });
            }

            function convertMarkdownToHtml(text) {
                // Convert markdown formatting to HTML for AI responses
                text = String(text);

                // First escape HTML entities to prevent XSS
                text = text.replace(/&/g, '&amp;')
                          .replace(/</g, '&lt;')
                          .replace(/>/g, '&gt;')
                          .replace(/"/g, '&quot;')
                          .replace(/'/g, '&#039;');

                // Convert markdown bold **text** to <strong>
                text = text.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>');

                // Convert markdown italic *text* to <em>
                text = text.replace(/\*([^*]+)\*/g, '<em>$1</em>');

                // Convert markdown links [text](url) to <a href="url">text</a>
                text = text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank">$1</a>');

                // Convert double newlines to paragraphs
                text = text.replace(/\n\n/g, '</p><p>');

                // Convert single newlines to <br>
                text = text.replace(/\n/g, '<br>');

                // Wrap in paragraph if not already wrapped
                if (!text.startsWith('<p>')) {
                    text = '<p>' + text + '</p>';
                }

                return text;
            }

            function loadAndShowCategories(currentCat, type) {
                type = type || 'product'; // Default to product categories
                var endpoint;
                if (type === 'blog') {
                    endpoint = 'blog-categories';
                } else if (type === 'cpt') {
                    endpoint = 'cpt-categories';
                } else {
                    endpoint = 'categories';
                }

                console.log('loadAndShowCategories called:', { currentCat: currentCat, type: type, endpoint: endpoint, url: config.restUrl + endpoint });

                jQuery.ajax({
                    url: config.restUrl + endpoint,
                    type: 'GET',
                    headers: {
                        'X-WP-Nonce': config.restNonce
                    },
                    success: function(response) {
                        console.log('AJAX success for ' + type + ' categories:', response);
                        if (response.categories && response.categories.length > 0) {
                            console.log('Calling showCategoryBubbles with', response.categories.length, 'categories');
                            showCategoryBubbles(response.categories, currentCat, type);
                        } else {
                            console.log('No categories in response or empty array');
                        }
                    },
                    error: function(xhr, status, error) {
                        console.error('Failed to load ' + type + ' categories:', { status: status, error: error, response: xhr.responseText });
                    }
                });
            }

            function showCategoryBubbles(categories, currentCat, type) {
                try {
                    type = type || 'product'; // Default to product categories

                    console.log('showCategoryBubbles called:', { categoriesCount: categories.length, currentCat: currentCat, type: type });

                    // Check if menu already exists in messages container - if yes, don't add again
                    if ($messages.find('.aieo-chat-category-menu').length > 0) {
                        console.log('Category menu already exists, returning early');
                        return;
                    }

                    console.log('No existing category menu, proceeding...');

                    // When the host page isn't tied to a known category,
                    // auto-select "All Categories" instead of leaving every
                    // bubble inactive + the input disabled. The first entry
                    // in the categories array is always the localised
                    // "All Categories" item (REST endpoint emits it with
                    // id=0, see class-rest-api.php::get_categories).
                    if (!currentCat && categories && categories.length > 0) {
                        var firstName = typeof categories[0] === 'string' ? categories[0] : categories[0].name;
                        if (firstName) {
                            currentCat = firstName;
                        }
                    }

                    // STEP 1: Show initial message FIRST
                    if (currentCat) {
                    // Category detected - tell user we'll help in that category
                    var helpingText;
                    // Check if it's "All Categories" (special case)
                    if (currentCat === 'All Categories' || currentCat === 'Όλες οι Κατηγορίες') {
                        helpingText = config.i18n && config.i18n.helpingWithAllCategories
                            ? config.i18n.helpingWithAllCategories
                            : 'I\'ll help you find any product from our entire catalog. What are you looking for?';
                    } else if (type === 'blog') {
                        helpingText = config.i18n && config.i18n.helpingWithBlogCategory
                            ? config.i18n.helpingWithBlogCategory
                            : 'I\'ll help you find blog posts in the {category} category. If you need something else, please select a different category.';
                        helpingText = helpingText.replace('{category}', escapeHtml(currentCat));
                    } else if (type === 'cpt') {
                        helpingText = config.i18n && config.i18n.helpingWithCptCategory
                            ? config.i18n.helpingWithCptCategory
                            : 'I\'ll help you find content in the {category} category. If you need something else, please select a different category.';
                        helpingText = helpingText.replace('{category}', escapeHtml(currentCat));
                    } else {
                        helpingText = config.i18n && config.i18n.helpingWithCategory
                            ? config.i18n.helpingWithCategory
                            : 'I\'ll help you find products in the {category} category. If you need something else, please select a different category.';
                        helpingText = helpingText.replace('{category}', escapeHtml(currentCat));
                    }
                    console.log('Adding helping text message:', helpingText);
                    addMessage('assistant', helpingText);
                    console.log('addMessage completed for helping text');
                } else {
                    // No category - ask them to select one
                    var promptText;
                    if (type === 'blog') {
                        promptText = config.i18n && config.i18n.blogCategoryPrompt
                            ? config.i18n.blogCategoryPrompt
                            : 'Please select a blog post category to get started:';
                    } else if (type === 'cpt') {
                        promptText = config.i18n && config.i18n.cptCategoryPrompt
                            ? config.i18n.cptCategoryPrompt
                            : 'Please select a category to get started:';
                    } else {
                        promptText = config.i18n && config.i18n.categoryPrompt
                            ? config.i18n.categoryPrompt
                            : 'Please select a product category to get started:';
                    }
                    console.log('Adding prompt text message:', promptText);
                    addMessage('assistant', promptText);
                }

                console.log('About to create category menu...');

                // STEP 2: Add category menu as a message (not prepended)
                var $categoryMenu = jQuery('<div class="aieo-chat-message aieo-chat-message-assistant"></div>');
                var $bubbles = jQuery('<div class="aieo-chat-category-bubbles"></div>');

                // Get theme-aware border radius
                var theme = config.theme || 'rounded';
                var borderRadius = theme === 'rounded' ? '12px' : '4px';

                categories.forEach(function(category) {
                    // Handle both old format (string) and new format (object with id and name)
                    var categoryName = typeof category === 'string' ? category : category.name;
                    var categoryId = typeof category === 'object' ? category.id : null;

                    var $bubble = jQuery('<button type="button" class="aieo-chat-category-bubble" data-category="' + escapeHtml(categoryName) + '">' + escapeHtml(categoryName) + '</button>');

                    // Apply theme-aware border radius
                    $bubble.css('border-radius', borderRadius);

                    if (categoryId) {
                        $bubble.attr('data-category-id', categoryId);
                    }

                    // Highlight current category
                    if (currentCat && categoryName === currentCat) {
                        $bubble.addClass('aieo-chat-category-bubble-highlight');
                    }

                    $bubble.on('click', function(e) {
                        e.preventDefault();
                        e.stopPropagation();
                        switchCategory(categoryName);
                    });

                    $bubbles.append($bubble);
                });

                $categoryMenu.append($bubbles);

                console.log('Appending category menu to $messages');

                // Append category menu as a message (in order)
                $messages.append($categoryMenu);

                console.log('Category menu appended, adding welcome message');

                // STEP 3: Show welcome message AFTER menu
                var welcomeMsg = config.welcomeMessage || 'Hello! How can I help you find the perfect product today?';
                addMessage('assistant', welcomeMsg);

                // Set initial category and enable/disable input
                if (currentCat) {
                    selectedCategory = currentCat;
                    $input.prop('disabled', false);
                    $sendBtn.prop('disabled', false);
                } else {
                    $input.prop('disabled', true);
                    $sendBtn.prop('disabled', true);
                }

                    console.log('showCategoryBubbles completed, scrolling to bottom');
                    scrollToBottom();
                } catch (error) {
                    console.error('Error in showCategoryBubbles:', error);
                }
            }

            function switchCategory(newCategory) {
                // Update the selected category
                var previousCategory = selectedCategory;
                selectedCategory = newCategory;

                // Update button highlighting
                jQuery('.aieo-chat-category-bubble').removeClass('aieo-chat-category-bubble-highlight');
                jQuery('.aieo-chat-category-bubble[data-category="' + newCategory + '"]').addClass('aieo-chat-category-bubble-highlight');

                // Show confirmation message - different wording for "All Categories"
                var switchText;
                if (newCategory === 'All Categories' || newCategory === 'Όλες οι Κατηγορίες') {
                    switchText = config.i18n && config.i18n.allCategoriesSwitched
                        ? config.i18n.allCategoriesSwitched
                        : 'Now searching across all categories. I\'ll help you find any product from our entire catalog.';
                } else {
                    switchText = config.i18n && config.i18n.categorySwitched
                        ? config.i18n.categorySwitched
                        : 'Switched to {category} category. I\'ll help you find products in this category.';
                    switchText = switchText.replace('{category}', escapeHtml(newCategory));
                }

                addMessage('assistant', switchText);

                // Enable input if it was disabled
                $input.prop('disabled', false);
                $sendBtn.prop('disabled', false);
                $input.focus();
            }
        }

        // Event handlers - attached after DOM is ready
        // Uses event delegation for efficiency
        jQuery(document).ready(function($) {
            // Unified chat telemetry: fire interactions through the EXISTING AIEO
            // Session Tracker so they (and the page they happen on) land in
            // wp_aieo_sessions — no second tracker, no per-page weight. No-op with
            // a short retry for the tracker's lazy init when it isn't ready yet.
            if (!window.aieoChatTrack) {
                window.aieoChatTrack = function (type, data, tries) {
                    tries = tries || 0;
                    try {
                        if (window.AIEO_SESSION_TRACKER && typeof window.AIEO_SESSION_TRACKER.track === 'function') {
                            window.AIEO_SESSION_TRACKER.track(type, data || {});
                            return;
                        }
                    } catch (e) { return; }
                    if (tries < 5) { setTimeout(function () { window.aieoChatTrack(type, data, tries + 1); }, 300); }
                };
            }

            // Note: Trigger fadeIn is handled in vanilla JS above for faster display

            // Dismiss welcome bubble when clicking anywhere on it
            $('#aieo-floating-welcome-bubble').on('click', function() {
                $(this).fadeOut(200);
                localStorage.setItem('aieo_floating_chat_bubble_dismissed', 'true');
            });

            // Toggle chat window - LAZY INITIALIZATION
            // The heavy initFloatingChat() only runs on first click
            $('#aieo-floating-chat-trigger').on('click', function() {
                $(this).hide();
                $('#aieo-floating-chat-window').fadeIn(300);
                // The shopper opened the chat — record where (page stamped by the tracker).
                if (window.aieoChatTrack) { window.aieoChatTrack('chat_open', {}); }
                // Hide welcome bubble if still visible
                $('#aieo-floating-welcome-bubble').fadeOut(200);
                localStorage.setItem('aieo_floating_chat_bubble_dismissed', 'true');

                // Initialize chat if not already done (LAZY LOADING)
                if (!window.aieoChatFloatingInitialized) {
                    initFloatingChat();
                    window.aieoChatFloatingInitialized = true;
                }
            });

            // Close chat window
            function closeFloatingChat() {
                $('#aieo-floating-chat-window').fadeOut(300, function() {
                    $('#aieo-floating-chat-trigger').fadeIn(300);
                });
            }

            // Close button click
            $('#aieo-chat-close').on('click', function() {
                closeFloatingChat();
            });

            // Click outside to close - uses event delegation
            $(document).on('click', function(e) {
                var $chatWindow = $('#aieo-floating-chat-window');
                var $chatTrigger = $('#aieo-floating-chat-trigger');
                var $target = $(e.target);

                // Only close if chat window is visible
                if ($chatWindow.is(':visible')) {
                    // Don't close if clicking on category bubbles or within chat window
                    if ($target.hasClass('aieo-chat-category-bubble') || $target.closest('.aieo-chat-category-bubbles').length > 0) {
                        return;
                    }

                    // Check if click is outside chat window and not on the trigger button
                    if (!$chatWindow.is(e.target) &&
                        $chatWindow.has(e.target).length === 0 &&
                        !$chatTrigger.is(e.target) &&
                        $chatTrigger.has(e.target).length === 0) {
                        closeFloatingChat();
                    }
                }
            });
        });
        </script>
        <?php
    }

    
    private function sanitize_dimension($value, $default, $min_px, $max_px) {
        if (empty($value)) {
            return $default;
        }

        
        if (is_string($value) && preg_match('/^(\d+(?:\.\d+)?)(px|vh|%|vw)$/i', $value, $matches)) {
            $number = floatval($matches[1]);
            $unit = strtolower($matches[2]);

            
            if ($unit === 'px') {
                $number = max($min_px, min($max_px, $number));
            }

            return $number . $unit;
        }

        
        $number = intval($value);
        if ($number > 0) {
            $number = max($min_px, min($max_px, $number));
            return $number . 'px';
        }

        return $default;
    }

    
    private function page_has_chat_shortcode() {
        global $post;

        
        if (!is_singular() || !$post) {
            return false;
        }

        
        if (has_shortcode($post->post_content, 'aieo_chat')) {
            return true;
        }

        
        if (has_block('core/shortcode', $post->post_content)) {
            
            if (strpos($post->post_content, '[aieo_chat') !== false) {
                return true;
            }
        }

        return false;
    }

    
    public function activate() {
        
        AI_eShop_Chat_Database_Manager::get_instance()->create_tables();
        AI_eShop_Chat_Business_Info_Manager::get_instance()->create_table();

        
        $this->set_default_options();

        
        flush_rewrite_rules();
    }

    
    public function deactivate() {
        
        flush_rewrite_rules();
    }

    
    private function set_default_options() {
        $defaults = array(
            'aieo_chat_enabled' => '0',
            'aieo_chat_bot_name' => 'AI Assistant by Oxford Metadata',
            'aieo_chat_welcome_message' => 'Hello! How can I help you find the perfect product today?',
            'aieo_chat_input_placeholder' => 'Ask about anything...',
            'aieo_chat_model' => 'claude-sonnet-4-5',
            'aieo_chat_max_tokens' => '500',
            'aieo_chat_temperature' => '0.5',
            'aieo_chat_max_results' => '10',
            'aieo_chat_rate_limit' => '1000',
            'aieo_chat_hide_images' => '0',
            'aieo_chat_require_login' => '0',
            'aieo_chat_history_enabled' => '1',
            'aieo_chat_show_terms' => '0',
            'aieo_chat_floating_enabled' => '0',
            'aieo_chat_floating_position' => 'bottom-right',
            'aieo_chat_floating_mobile_position' => 'bottom-right',
            'aieo_chat_floating_popup_width' => '390px',
            'aieo_chat_floating_popup_height' => '600px',
            'aieo_chat_enabled_post_types' => array('product')
        );

        foreach ($defaults as $key => $value) {
            if (get_option($key) === false) {
                add_option($key, $value, '', 'no');
            }
        }
    }

    
    public function ajax_save_content_selection() {
        check_ajax_referer('aieo_chat_admin', 'nonce');

        if (!current_user_can('manage_options')) {
            wp_send_json_error(array('message' => __('Insufficient permissions', 'ai-eshop-optimizer')), 403);
        }

        
        
        
        $post_types = isset($_POST['post_types']) ? array_map('sanitize_text_field', (array) wp_unslash($_POST['post_types'])) : array();
        $post_types = array_values(array_filter($post_types, 'strlen'));
        update_option('aieo_chat_enabled_post_types', $post_types);

        $taxonomies = isset($_POST['taxonomies']) ? array_map('sanitize_text_field', (array) wp_unslash($_POST['taxonomies'])) : array();
        $taxonomies = array_values(array_filter($taxonomies, 'strlen'));
        update_option('aieo_chat_enabled_taxonomies', $taxonomies);

        wp_send_json_success(array(
            'post_types_saved' => $post_types,
            'taxonomies_saved' => $taxonomies
        ));
    }

    
    public function ajax_save_settings() {
        check_ajax_referer('aieo_chat_admin', 'nonce');

        if (!current_user_can('manage_options')) {
            wp_send_json_error(array('message' => __('Insufficient permissions', 'ai-eshop-optimizer')), 403);
        }

        $saved_settings = array();

        
        if (isset($_POST['aieo_chat_deduplication_mode'])) {
            $dedup_mode = intval($_POST['aieo_chat_deduplication_mode']);
            update_option('aieo_chat_deduplication_mode', $dedup_mode);
            $saved_settings['deduplication_mode'] = $dedup_mode;
        }

        wp_send_json_success(array(
            'message' => __('Settings saved successfully', 'ai-eshop-optimizer'),
            'saved' => $saved_settings
        ));
    }

    
    public function add_cron_schedules($schedules) {
        if (!isset($schedules['weekly'])) {
            $schedules['weekly'] = array(
                'interval' => 7 * DAY_IN_SECONDS,
                'display'  => __('Once Weekly', 'ai-eshop-optimizer')
            );
        }
        if (!isset($schedules['monthly'])) {
            $schedules['monthly'] = array(
                'interval' => 30 * DAY_IN_SECONDS,
                'display'  => __('Once Monthly', 'ai-eshop-optimizer')
            );
        }
        return $schedules;
    }

    
    private function has_valid_pro_subscription() {
        
        if (get_option('aieo_user_membership') !== 'Pro') {
            return false;
        }

        
        $expiration_date = get_option('aieo_subscription_expiration', '');
        if (!empty($expiration_date)) {
            
            $expiration_timestamp = strtotime($expiration_date);
            $current_timestamp = current_time('timestamp', true);

            
            if ($expiration_timestamp < $current_timestamp) {
                if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { error_log('AIEO: Pro subscription expired on ' . $expiration_date . ' - disabling automation'); }

                
                update_option('aieo_auto_analytics_enabled', '0');
                update_option('aieo_auto_embeddings_enabled', '0');

                
                wp_clear_scheduled_hook('aieo_auto_analytics_event');
                wp_clear_scheduled_hook('aieo_auto_embeddings_event');

                return false;
            }
        }

        return true;
    }

    
    public function heal_auto_event_scheduling() {
        $this->maybe_rearm_auto_event(
            'aieo_auto_analytics_enabled',
            'aieo_auto_analytics_frequency',
            'aieo_auto_analytics_time',
            'aieo_auto_analytics_event'
        );
        $this->maybe_rearm_auto_event(
            'aieo_auto_embeddings_enabled',
            'aieo_auto_embeddings_frequency',
            'aieo_auto_embeddings_time',
            'aieo_auto_embeddings_event'
        );
    }

    
    private function maybe_rearm_auto_event($enabled_opt, $freq_opt, $time_opt, $hook) {
        if ('1' !== (string) get_option($enabled_opt, '0')) {
            return; 
        }
        if (wp_next_scheduled($hook)) {
            return; 
        }
        $frequency  = (string) get_option($freq_opt, 'weekly');
        $recurrence = in_array($frequency, array('daily', 'weekly', 'monthly'), true) ? $frequency : 'weekly';
        $time       = (string) get_option($time_opt, '03:00');
        $next_run   = $this->calc_next_run_time($recurrence, $time);
        if ($next_run) {
            wp_schedule_event($next_run, $recurrence, $hook);
            if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { error_log('AIEO: self-healed missing cron ' . $hook . ' for ' . gmdate('Y-m-d H:i:s', $next_run)); }
        }
    }

    
    private function calc_next_run_time($frequency, $time) {
        if (empty($time) || strpos($time, ':') === false) {
            return false;
        }
        list($hour, $minute) = array_pad(explode(':', $time), 2, '0');
        $hour   = (int) $hour;
        $minute = (int) $minute;
        $now    = current_time('timestamp', true);
        $today  = strtotime(gmdate('Y-m-d', $now) . ' ' . sprintf('%02d:%02d:00', $hour, $minute));
        if ($today <= $now) {
            if ('daily' === $frequency)  { return $today + DAY_IN_SECONDS; }
            if ('weekly' === $frequency) { return $today + (7 * DAY_IN_SECONDS); }
            return $today + (30 * DAY_IN_SECONDS);
        }
        return $today;
    }

    
    public function run_auto_analytics() {
        if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { error_log('AIEO: Running automated analytics update'); }

        
        if (!$this->has_valid_pro_subscription()) {
            if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { error_log('AIEO: Skipping analytics automation - Valid Pro subscription required'); }
            return;
        }

        
        
        do_action('aieo_run_export_and_analysis');

        if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { error_log('AIEO: Completed automated analytics update'); }
    }

    
    public function run_auto_embeddings() {
        if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { error_log('AIEO: Running automated embeddings generation'); }

        
        if (!$this->has_valid_pro_subscription()) {
            if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { error_log('AIEO: Skipping embeddings automation - Valid Pro subscription required'); }
            return;
        }

        
        $embedding_provider = get_option('aieo_embedding_provider', 'voyage');
        $dedup_mode = get_option('aieo_chat_deduplication_mode', 1);
        $enabled_post_types = get_option('aieo_chat_enabled_post_types', array('product'));

        if (empty($enabled_post_types)) {
            if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { error_log('AIEO: No post types selected for embedding generation'); }
            return;
        }

        
        if ($embedding_provider === 'voyage') {
            $embedding_engine = get_option('aieo_chat_embedding_model', 'voyage-3');
        } else {
            $embedding_engine = get_option('aieo_chat_openai_embedding_model', 'text-embedding-3-large');
        }

        if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { error_log('AIEO: Generating embeddings with engine: ' . $embedding_engine . ', dedup: ' . $dedup_mode); }

        
        global $wpdb;
        $content_ids = array();

        foreach ($enabled_post_types as $post_type) {
            $posts = get_posts(array(
                'post_type' => $post_type,
                'post_status' => 'publish',
                'numberposts' => -1,
                'fields' => 'ids'
            ));
            $content_ids = array_merge($content_ids, $posts);
        }

        if (empty($content_ids)) {
            if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { error_log('AIEO: No content found for embedding generation'); }
            return;
        }

        if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { error_log('AIEO: Processing ' . count($content_ids) . ' items for embedding generation'); }

        
        $batch_size = 10;
        $batches = array_chunk($content_ids, $batch_size);
        $processed = 0;

        foreach ($batches as $batch) {
            foreach ($batch as $content_id) {
                
                do_action('aieo_generate_single_embedding', $content_id, $embedding_engine, $dedup_mode);
                $processed++;
            }

            
            sleep(1);
        }

        if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { error_log('AIEO: Completed automated embeddings generation - processed ' . $processed . ' items'); }
    }

    
    private function get_top_category_for_term($term) {
        
        if ($term->parent == 0) {
            return $term->name;
        }

        
        $ancestors = get_ancestors($term->term_id, 'product_cat');
        if (empty($ancestors)) {
            return $term->name;
        }

        
        $top_term_id = end($ancestors);
        $top_term = get_term($top_term_id, 'product_cat');

        return (!is_wp_error($top_term) && $top_term) ? $top_term->name : $term->name;
    }

    
    
    private function canonical_term($object_type, $object_id, $taxonomy) {
        if (!class_exists('AIEO_SEO_Store')) {
            return null;
        }
        $tid = (int) AIEO_SEO_Store::get_primary_term($object_type, (int) $object_id, $taxonomy);
        if ($tid <= 0) {
            return null;
        }
        $term = get_term($tid, $taxonomy);
        return ($term && !is_wp_error($term)) ? $term : null;
    }

    private function get_top_category_for_product($product_id) {
        
        $terms = wp_get_post_terms($product_id, 'product_cat', array('fields' => 'all'));

        if (empty($terms) || is_wp_error($terms)) {
            return '';
        }

        
        
        $term = $this->canonical_term('product', $product_id, 'product_cat') ?: $terms[0];

        
        if ($term->parent == 0) {
            return $term->name;
        }

        
        $ancestors = get_ancestors($term->term_id, 'product_cat');
        if (empty($ancestors)) {
            return $term->name;
        }

        
        $top_term_id = end($ancestors);
        $top_term = get_term($top_term_id, 'product_cat');

        return (!is_wp_error($top_term) && $top_term) ? $top_term->name : $term->name;
    }

    
    private function get_top_blog_category_for_term($term) {
        
        if ($term->parent == 0) {
            return $term->name;
        }

        
        $ancestors = get_ancestors($term->term_id, 'category');
        if (empty($ancestors)) {
            return $term->name;
        }

        
        $top_term_id = end($ancestors);
        $top_term = get_term($top_term_id, 'category');

        return (!is_wp_error($top_term) && $top_term) ? $top_term->name : $term->name;
    }

    
    private function get_top_blog_category_for_post($post_id) {
        
        $terms = wp_get_post_terms($post_id, 'category', array('fields' => 'all'));

        if (empty($terms) || is_wp_error($terms)) {
            return '';
        }

        
        $term = $this->canonical_term('post', $post_id, 'category') ?: $terms[0];

        
        if ($term->parent == 0) {
            return $term->name;
        }

        
        $ancestors = get_ancestors($term->term_id, 'category');
        if (empty($ancestors)) {
            return $term->name;
        }

        
        $top_term_id = end($ancestors);
        $top_term = get_term($top_term_id, 'category');

        return (!is_wp_error($top_term) && $top_term) ? $top_term->name : $term->name;
    }

    
    private function get_top_cpt_category_for_term($term, $taxonomy) {
        
        if ($term->parent == 0) {
            return $term->name;
        }

        
        $ancestors = get_ancestors($term->term_id, $taxonomy);
        if (empty($ancestors)) {
            return $term->name;
        }

        
        $top_term_id = end($ancestors);
        $top_term = get_term($top_term_id, $taxonomy);

        return (!is_wp_error($top_term) && $top_term) ? $top_term->name : $term->name;
    }

    
    private function get_top_cpt_category_for_post($post_id, $taxonomy) {
        
        $terms = wp_get_post_terms($post_id, $taxonomy, array('fields' => 'all'));

        if (empty($terms) || is_wp_error($terms)) {
            return '';
        }

        
        $term = $this->canonical_term(get_post_type($post_id), $post_id, $taxonomy) ?: $terms[0];

        
        if ($term->parent == 0) {
            return $term->name;
        }

        
        $ancestors = get_ancestors($term->term_id, $taxonomy);
        if (empty($ancestors)) {
            return $term->name;
        }

        
        $top_term_id = end($ancestors);
        $top_term = get_term($top_term_id, $taxonomy);

        return (!is_wp_error($top_term) && $top_term) ? $top_term->name : $term->name;
    }

}

function aieo_chat_init() {
    AI_eShop_Chat::get_instance();
}
add_action('plugins_loaded', 'aieo_chat_init', 20);
