<?php

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

class AI_eShop_Chat_Embedding_Manager {

    
    private static $instance = null;

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

    
    private function __construct() {
        
        add_action('save_post_product', array($this, 'maybe_update_embedding'), 10, 2);
        add_action('delete_post', array($this, 'delete_embedding_on_delete'));

        
        add_action('wp_ajax_aieo_chat_generate_embeddings', array($this, 'ajax_generate_embeddings'));
        add_action('wp_ajax_aieo_chat_generate_taxonomy_embeddings', array($this, 'ajax_generate_taxonomy_embeddings'));
        add_action('wp_ajax_aieo_chat_regenerate_embedding', array($this, 'ajax_regenerate_embedding'));
        add_action('wp_ajax_aieo_chat_delete_embeddings', array($this, 'ajax_delete_embeddings'));
        add_action('wp_ajax_aieo_chat_get_engine_stats', array($this, 'ajax_get_engine_stats'));
        add_action('wp_ajax_aieo_chat_update_embedding_model', array($this, 'ajax_update_embedding_model'));
        add_action('wp_ajax_aieo_chat_get_delete_counts', array($this, 'ajax_get_delete_counts'));
        add_action('wp_ajax_aieo_chat_get_available_engines', array($this, 'ajax_get_available_engines'));
        add_action('wp_ajax_aieo_chat_get_delete_stats', array($this, 'ajax_get_delete_stats'));
        add_action('wp_ajax_aieo_chat_save_last_trained_engine', array($this, 'ajax_save_last_trained_engine'));
    }

    
    public function generate_embedding($post_id, $post_type = 'product', $force = false) {
        
        $content = AI_eShop_Chat_Content_Extractor::extract_content($post_id, $post_type);

        if (empty($content)) {
            return new WP_Error('no_content', __('No content to generate embedding', 'ai-eshop-optimizer'));
        }

        
        $content_hash = md5($content);

        
        if (!$force) {
            $db = AI_eShop_Chat_Database_Manager::get_instance();
            $existing = $db->get_embedding($post_id);

            if ($existing && $existing['content_hash'] === $content_hash) {
                
                return true;
            }
        }

        
        
        wp_cache_delete('aieo_embedding_provider', 'options');
        wp_cache_delete('aieo_chat_openai_embedding_model', 'options');
        wp_cache_delete('aieo_chat_embedding_model', 'options');
        
        $embedding_provider = get_option('aieo_embedding_provider', 'voyage');

        
        if ($embedding_provider === 'openai') {
            
            $model = get_option('aieo_chat_openai_embedding_model', 'text-embedding-3-large');
            $api = AI_eShop_Chat_OpenAI_API::get_instance();
            $embedding = $api->generate_embedding($content, $model);
        } else {
            
            $model = get_option('aieo_chat_embedding_model', 'voyage-2');
            $api = AI_eShop_Chat_Anthropic_API::get_instance();
            $embedding = $api->generate_embedding($content, $model);
        }

        if (is_wp_error($embedding)) {
            return $embedding;
        }

        
        $db = AI_eShop_Chat_Database_Manager::get_instance();
        $result = $db->store_embedding($post_id, $embedding, $content_hash, $post_type, $model);

        if (!$result) {
            return new WP_Error('storage_failed', __('Failed to store embedding', 'ai-eshop-optimizer'));
        }

        return true;
    }

    
    public function generate_embeddings_batch($post_ids, $post_type = 'product', $deduplicated = 0, $engine_type = null) {
        $results = array();

        
        $post_ids = array_values(array_unique(array_map('intval', $post_ids)));

        
        if (get_option('aieo_chat_prioritize_by_sales', '0') === '1' && $post_type === 'product') {
            $post_ids = $this->sort_by_sales($post_ids);
        } elseif (get_option('aieo_chat_prioritize_top_sellers', '0') === '1' && $post_type === 'product') {
            
            $post_ids = $this->sort_by_sales($post_ids);
        }

        
        if ($engine_type !== null) {
            
            if (strpos($engine_type, 'text-embedding') === 0) {
                $embedding_provider = 'openai';
                $model = $engine_type;
            } else {
                $embedding_provider = 'voyage';
                $model = $engine_type;
            }
        } else {
            
            
            wp_cache_delete('aieo_embedding_provider', 'options');
            wp_cache_delete('aieo_chat_openai_embedding_model', 'options');
            wp_cache_delete('aieo_chat_embedding_model', 'options');

            $embedding_provider = get_option('aieo_embedding_provider', 'voyage');

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

        
        
        

        
        $chunk_size = 20;
        $chunks = array_chunk($post_ids, $chunk_size);

        foreach ($chunks as $chunk) {
            
            $texts = array();
            $post_data = array();

            foreach ($chunk as $post_id) {
                $content = AI_eShop_Chat_Content_Extractor::extract_content($post_id, $post_type, (bool)$deduplicated);

                if (empty($content)) {
                    $results[$post_id] = array(
                        'success' => false,
                        'error' => __('No content to generate embedding', 'ai-eshop-optimizer')
                    );
                    continue;
                }

                
                if ($embedding_provider === 'openai') {
                    $content = $this->truncate_for_openai($content, 6000); 
                }

                $texts[] = $content;
                $post_data[] = array(
                    'post_id' => $post_id,
                    'content_hash' => md5($content)
                );
            }

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

            
            
            
            

            
            
            $texts_by_id = array_combine(array_column($post_data, 'post_id'), $texts);

            
            
            
            
            
            
            
            $api = ($embedding_provider === 'openai')
                ? AI_eShop_Chat_OpenAI_API::get_instance()
                : AI_eShop_Chat_Anthropic_API::get_instance();

            $embeddings = null;
            $last_error = null;
            $delays = array(0, 1, 3, 9); 
            foreach ($delays as $attempt_index => $delay_seconds) {
                if ($delay_seconds > 0) {
                    sleep($delay_seconds);
                }
                $embeddings = $api->generate_embeddings_batch($texts_by_id, $model);
                if (!is_wp_error($embeddings)) {
                    break;
                }
                $last_error = $embeddings;
                $attempt_num = $attempt_index + 1;
                error_log(sprintf(
                    'AIEO embeddings batch retry %d/%d (model=%s, chunk_size=%d): %s',
                    $attempt_num,
                    count($delays),
                    $model,
                    count($texts_by_id),
                    $embeddings->get_error_message()
                ));
            }

            if (is_wp_error($embeddings)) {
                
                $err_msg = $last_error ? $last_error->get_error_message() : 'unknown error';
                foreach ($chunk as $post_id) {
                    if (!isset($results[$post_id])) {
                        $results[$post_id] = array(
                            'success' => false,
                            'error' => $err_msg
                        );
                    }
                }
                continue;
            }

            
            $db = AI_eShop_Chat_Database_Manager::get_instance();
            foreach ($post_data as $index => $data) {
                
                $post_id = $data['post_id'];

                if (isset($embeddings[$post_id])) {
                    
                    
                    

                    $stored = $db->store_embedding(
                        $data['post_id'],
                        $embeddings[$post_id],
                        $data['content_hash'],
                        $post_type,
                        $model,
                        $deduplicated
                    );

                    $results[$data['post_id']] = array(
                        'success' => $stored,
                        'error' => $stored ? null : __('Failed to store embedding', 'ai-eshop-optimizer')
                    );
                } else {
                    $results[$data['post_id']] = array(
                        'success' => false,
                        'error' => __('Missing embedding in response', 'ai-eshop-optimizer')
                    );
                }
            }
        }

        return $results;
    }

    
    public function generate_all_embeddings($post_type = 'product', $batch_size = 50, $offset = 0, $deduplicated = 0, $engine_type = null) {
        $db = AI_eShop_Chat_Database_Manager::get_instance();

        
        
        if ($engine_type === null) {
            $provider = get_option('aieo_embedding_provider', 'voyage');
            if ($provider === 'openai') {
                $engine_type = get_option('aieo_chat_openai_embedding_model', 'text-embedding-3-large');
            } else {
                $engine_type = get_option('aieo_chat_embedding_model', 'voyage-2');
            }
        }

        
        
        
        
        
        
        
        
        
        
        
        if ($post_type === 'product') {
            $needs_check_key = 'aieo_chat_needs_guard_checked';
            if (get_transient($needs_check_key) === false) {
                global $wpdb;
                $needs_populated = (int) $wpdb->get_var(
                    "SELECT COUNT(*) FROM {$wpdb->prefix}aieo_core_product_vitals
                     WHERE primary_need_id IS NOT NULL AND product_id = parent_id
                     LIMIT 1"
                );
                if ($needs_populated === 0) {
                    
                    if (!class_exists('AI_eShop_Product_Needs')) {
                        require_once plugin_dir_path(dirname(__FILE__)) . 'class-product-needs.php';
                    }
                    if (class_exists('AI_eShop_Product_Needs')) {
                        AI_eShop_Product_Needs::get_instance()->populate_product_needs();
                        if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { error_log('AIEO embedding trainer: vitals.primary_need was empty, re-ran PopulateProductNeeds.'); }
                    }
                }
                set_transient($needs_check_key, 1, MINUTE_IN_SECONDS);
            }
        }

        
        
        

        
        
        
        
        
        global $wpdb;
        if ($post_type === 'product') {
            $vitals_helper = AI_eShop_Chat_Product_Vitals_Helper::get_instance();
            if ($vitals_helper->is_vitals_table_available()) {
                $total_items = (int) $vitals_helper->count_sellable_units(array('in_stock_only' => true));
            } else {
                $total_items = (int) $wpdb->get_var($wpdb->prepare(
                    "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type = %s AND post_status = 'publish'",
                    $post_type
                ));
            }
        } else {
            $total_items = (int) $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type = %s AND post_status = 'publish'",
                $post_type
            ));
        }

        
        $post_ids = $db->get_posts_without_embeddings($post_type, $batch_size, $engine_type, $deduplicated);

        
        
        

        if (empty($post_ids)) {
            return array(
                'success' => true,
                'message' => __('All posts have embeddings', 'ai-eshop-optimizer'),
                'processed' => 0,
                'remaining' => 0,
                'total_items' => $total_items,
                'total' => $total_items  
            );
        }

        
        $results = $this->generate_embeddings_batch($post_ids, $post_type, $deduplicated, $engine_type);

        
        $successes = count(array_filter($results, function($r) {
            return $r['success'];
        }));

        
        $remaining_count = $db->count_posts_without_embeddings($post_type, $engine_type, $deduplicated);

        
        if ($remaining_count < 0) {
            $remaining_count = 0;
        }
        if ($remaining_count > $total_items) {
            $remaining_count = $total_items;
        }

        
        $failure_stats = $db->get_failure_statistics($post_type, $engine_type, $deduplicated);

        return array(
            'success' => true,
            'processed' => $successes,
            'failed' => count($results) - $successes,
            'remaining' => $remaining_count,
            'total_items' => $total_items,
            'total' => $total_items,  
            'failure_stats' => $failure_stats,  
            'details' => $results
        );
    }

    
    public function generate_all_taxonomy_embeddings($taxonomy = 'product_cat', $batch_size = 50, $offset = 0, $deduplicated = 0) {
        $db = AI_eShop_Chat_Database_Manager::get_instance();

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

        
        $total_count = wp_count_terms(array(
            'taxonomy' => $taxonomy,
            'hide_empty' => false
        ));

        
        $term_ids = $db->get_terms_without_embeddings($taxonomy, $batch_size, $engine_type, $deduplicated);

        if (empty($term_ids)) {
            return array(
                'success' => true,
                'message' => __('All terms have embeddings', 'ai-eshop-optimizer'),
                'processed' => 0,
                'remaining' => 0,
                'total' => $total_count
            );
        }

        
        $results = $this->generate_taxonomy_embeddings_batch($term_ids, $taxonomy, $deduplicated);

        
        $successes = count(array_filter($results, function($r) {
            return $r['success'];
        }));

        
        $all_terms_without = $db->get_terms_without_embeddings($taxonomy, 999999, $engine_type, $deduplicated);
        $remaining_count = count($all_terms_without);

        
        if ($remaining_count < 0) {
            $remaining_count = 0;
        }
        if ($remaining_count > $total_count) {
            $remaining_count = $total_count;
        }

        return array(
            'success' => true,
            'processed' => $successes,
            'failed' => count($results) - $successes,
            'remaining' => $remaining_count,
            'total' => $total_count,
            'details' => $results
        );
    }

    
    private function generate_taxonomy_embeddings_batch($term_ids, $taxonomy, $deduplicated = 0) {
        $db = AI_eShop_Chat_Database_Manager::get_instance();
        $results = array();

        
        
        wp_cache_delete('aieo_embedding_provider', 'options');
        wp_cache_delete('aieo_chat_openai_embedding_model', 'options');
        wp_cache_delete('aieo_chat_embedding_model', 'options');
        
        $embedding_provider = get_option('aieo_embedding_provider', 'voyage');

        if ($embedding_provider === 'openai') {
            $api = AI_eShop_Chat_OpenAI_API::get_instance();
            $model = get_option('aieo_chat_openai_embedding_model', 'text-embedding-3-large');
        } else {
            $api = AI_eShop_Chat_Anthropic_API::get_instance();
            $model = get_option('aieo_chat_embedding_model', 'voyage-3-large');
        }

        
        $contents_to_embed = array();
        foreach ($term_ids as $term_id) {
            $content = AI_eShop_Chat_Content_Extractor::extract_content($term_id, 'taxonomy:' . $taxonomy, (bool)$deduplicated);
            $contents_to_embed[$term_id] = $content;
        }

        
        $embeddings = $api->generate_embeddings_batch($contents_to_embed, $model);

        if (is_wp_error($embeddings)) {
            
            foreach ($term_ids as $term_id) {
                $results[] = array(
                    'term_id' => $term_id,
                    'success' => false,
                    'error' => $embeddings->get_error_message()
                );
            }
            return $results;
        }

        
        foreach ($embeddings as $term_id => $embedding) {
            if (is_wp_error($embedding)) {
                $results[] = array(
                    'term_id' => $term_id,
                    'success' => false,
                    'error' => $embedding->get_error_message()
                );
                continue;
            }

            
            $content = $contents_to_embed[$term_id];
            $content_hash = md5($content);

            
            $engine_type = ($embedding_provider === 'openai') ?
                get_option('aieo_chat_openai_embedding_model', 'text-embedding-3-large') :
                get_option('aieo_chat_embedding_model', 'voyage-2');

            
            $stored = $db->store_embedding($term_id, $embedding, $content_hash, 'taxonomy:' . $taxonomy, $engine_type, $deduplicated);

            $results[] = array(
                'term_id' => $term_id,
                'success' => $stored,
                'error' => !$stored ? 'Failed to store embedding' : null
            );
        }

        return $results;
    }

    
    public function maybe_update_embedding($post_id, $post) {
        
        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
            return;
        }

        if (wp_is_post_revision($post_id)) {
            return;
        }

        
        if ($post->post_status !== 'publish') {
            return;
        }

        
        $enabled_types = get_option('aieo_chat_enabled_post_types', array('product'));
        if (!in_array($post->post_type, $enabled_types, true)) {
            return;
        }

        
        wp_schedule_single_event(time() + 10, 'aieo_chat_generate_single_embedding', array(
            'post_id' => $post_id,
            'post_type' => $post->post_type
        ));
    }

    
    public function delete_embedding_on_delete($post_id) {
        $db = AI_eShop_Chat_Database_Manager::get_instance();
        $db->delete_embedding($post_id);
    }

    
    public function cosine_similarity($vec1, $vec2) {
        $dot_product = 0;
        $magnitude1 = 0;
        $magnitude2 = 0;

        $len = min(count($vec1), count($vec2));

        for ($i = 0; $i < $len; $i++) {
            $dot_product += $vec1[$i] * $vec2[$i];
            $magnitude1 += $vec1[$i] * $vec1[$i];
            $magnitude2 += $vec2[$i] * $vec2[$i];
        }

        $magnitude1 = sqrt($magnitude1);
        $magnitude2 = sqrt($magnitude2);

        if ($magnitude1 == 0 || $magnitude2 == 0) {
            return 0;
        }

        return $dot_product / ($magnitude1 * $magnitude2);
    }

    
    public function search_similar($query, $args = array()) {
        
        $defaults = array(
            'post_types' => array('product'),
            'limit' => 10,
            'min_similarity' => 0.5
        );

        $args = wp_parse_args($args, $defaults);

        
        $embedding_provider = get_option('aieo_embedding_provider', 'voyage');

        if ($embedding_provider === 'openai') {
            $model = get_option('aieo_chat_openai_embedding_model', 'text-embedding-3-large');
            $api = AI_eShop_Chat_OpenAI_API::get_instance();
            $query_embedding = $api->generate_embedding($query, $model);
        } else {
            $model = get_option('aieo_chat_embedding_model', 'voyage-2');
            $api = AI_eShop_Chat_Anthropic_API::get_instance();
            $query_embedding = $api->generate_embedding($query, $model);
        }

        if (is_wp_error($query_embedding)) {
            return $query_embedding;
        }

        
        $db = AI_eShop_Chat_Database_Manager::get_instance();
        $embeddings = $db->get_embeddings_for_search($args['post_types'], null, $model);

        if (empty($embeddings)) {
            return array();
        }

        
        $similarities = array();
        foreach ($embeddings as $post_id => $embedding) {
            $similarity = $this->cosine_similarity($query_embedding, $embedding);

            if ($similarity >= $args['min_similarity']) {
                $similarities[$post_id] = $similarity;
            }
        }

        
        arsort($similarities);

        
        
        
        
        $similarities = $this->filter_by_category($similarities, isset($args['category']) ? $args['category'] : '');

        
        $similarities = array_slice($similarities, 0, $args['limit'], true);

        
        $results = array();
        foreach ($similarities as $post_id => $score) {
            $results[] = array(
                'post_id' => $post_id,
                'score' => $score,
                'post' => get_post($post_id)
            );
        }

        return $results;
    }

    
    private function get_excluded_term_keys() {
        
        
        
        
        if (get_option('aieo_chat_honor_navigator_hidden_terms', '1') !== '1') {
            return array();
        }
        if (!class_exists('AIEO_DMM_Settings')) {
            return array();
        }
        $raw = (string) AIEO_DMM_Settings::get('navigator_excluded_terms', '');
        if ($raw === '') {
            return array();
        }
        
        
        $aliases = array(
            'product_brand' => array('product_brand', 'pwb-brand', 'pa_brand', 'pa-brand'),
            'pwb-brand'     => array('product_brand', 'pwb-brand', 'pa_brand', 'pa-brand'),
            'pa_brand'      => array('product_brand', 'pwb-brand', 'pa_brand', 'pa-brand'),
            'pa-brand'      => array('product_brand', 'pwb-brand', 'pa_brand', 'pa-brand'),
            'pa-need'       => array('pa-need', 'pa_need'),
            'pa_need'       => array('pa-need', 'pa_need'),
        );
        $out = array();
        foreach (preg_split('/[,\s]+/', $raw) as $tok) {
            $tok = trim($tok);
            if ($tok === '') continue;
            if (strpos($tok, ':') === false) {
                $out[] = 'product_cat:' . (int) $tok;
                continue;
            }
            list($tax, $id) = explode(':', $tok, 2);
            $tax = sanitize_key($tax);
            $id  = (int) $id;
            $taxes = isset($aliases[$tax]) ? $aliases[$tax] : array($tax);
            foreach ($taxes as $alias) {
                $out[] = $alias . ':' . $id;
            }
        }
        return array_flip(array_unique($out));
    }

    
    private function get_excluded_product_ids() {
        static $cache = null;
        if ($cache !== null) {
            return $cache;
        }
        $cache = array();
        $excluded_keys = $this->get_excluded_term_keys();
        if (empty($excluded_keys)) {
            return $cache;
        }
        $by_tax = array();
        foreach (array_keys($excluded_keys) as $key) {
            $parts = explode(':', $key, 2);
            if (count($parts) !== 2) continue;
            $by_tax[$parts[0]][] = (int) $parts[1];
        }
        global $wpdb;
        foreach ($by_tax as $tax => $ids) {
            $ids = array_unique(array_filter($ids));
            if (empty($ids)) continue;
            $placeholders = implode(',', array_fill(0, count($ids), '%d'));
            
            
            $tt_ids = $wpdb->get_col($wpdb->prepare(
                "SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy}
                 WHERE taxonomy = %s AND term_id IN ($placeholders)",
                array_merge(array($tax), $ids)
            ));
            if (empty($tt_ids)) continue;
            $tt_placeholders = implode(',', array_fill(0, count($tt_ids), '%d'));
            $rows = $wpdb->get_col($wpdb->prepare(
                "SELECT DISTINCT object_id FROM {$wpdb->term_relationships}
                 WHERE term_taxonomy_id IN ($tt_placeholders)",
                $tt_ids
            ));
            foreach ($rows as $pid) {
                $cache[(int) $pid] = true;
            }
        }
        return $cache;
    }

    
    private function filter_by_category($similarities, $category) {
        global $wpdb;

        
        
        
        
        $excluded_pids = $this->get_excluded_product_ids();
        if (!empty($excluded_pids)) {
            $kept = array();
            foreach ($similarities as $pid => $score) {
                if (isset($excluded_pids[(int) $pid])) continue;
                
                if (get_post_type($pid) === 'product_variation') {
                    $parent = (int) wp_get_post_parent_id($pid);
                    if ($parent && isset($excluded_pids[$parent])) continue;
                }
                $kept[$pid] = $score;
            }
            $similarities = $kept;
        }

        if (empty($similarities) || empty($category)) {
            return $similarities;
        }

        $post_ids = array_keys($similarities);

        
        
        
        
        
        
        
        $non_product_similarities = array();
        $hierarchy_lookup = array();   
        $hierarchy_ids = array();      

        foreach ($post_ids as $post_id) {
            $post_type = get_post_type($post_id);
            if ($post_type === 'product' || $post_type === 'product_variation') {
                if ($post_type === 'product_variation') {
                    $parent_id = (int) wp_get_post_parent_id($post_id);
                    $lookup_id = $parent_id > 0 ? $parent_id : $post_id;
                } else {
                    $lookup_id = (int) $post_id;
                }
                $hierarchy_lookup[$lookup_id][] = $post_id;
                $hierarchy_ids[$lookup_id] = true;
            } else {
                
                $non_product_similarities[$post_id] = $similarities[$post_id];
            }
        }

        
        if (empty($hierarchy_ids)) {
            return $similarities;
        }

        $hierarchy_id_list = array_keys($hierarchy_ids);
        $placeholders = implode(',', array_fill(0, count($hierarchy_id_list), '%d'));

        
        $query = $wpdb->prepare(
            "SELECT DISTINCT product_id
             FROM {$wpdb->prefix}aieo_core_product_category_hierarchy
             WHERE product_id IN ($placeholders)
             AND top_category = %s",
            array_merge($hierarchy_id_list, array($category))
        );

        
        $matching_hierarchy_ids_raw = $wpdb->get_col($query);

        
        
        $keep_post_ids = array();
        foreach ($matching_hierarchy_ids_raw as $hierarchy_id) {
            $hierarchy_id = (int) $hierarchy_id;
            if (!empty($hierarchy_lookup[$hierarchy_id])) {
                foreach ($hierarchy_lookup[$hierarchy_id] as $original_post_id) {
                    $keep_post_ids[$original_post_id] = true;
                }
            }
        }

        
        
        
        
        
        $filtered_similarities = array();
        foreach ($similarities as $post_id => $score) {
            if (isset($non_product_similarities[$post_id]) || isset($keep_post_ids[$post_id])) {
                $filtered_similarities[$post_id] = $score;
            }
        }

        return $filtered_similarities;
    }

    
    private function sort_by_sales($post_ids) {
        global $wpdb;

        if (empty($post_ids)) {
            return $post_ids;
        }

        
        $priority_metric = get_option('aieo_chat_product_priority_metric', 'total_sales');

        
        $metric_column_map = array(
            'total_sales'      => 'TotalItemSales',
            'distinct_orders'  => 'DistinctOrderSales',
            'total_turnover'   => 'TotalTurnover',
            'unique_sales'     => 'UniqueItemSales',
            'first_in_cart'    => 'FirstItemSales',
            'last_in_cart'     => 'LastItemSales',
            'avg_jlw'          => 'AvgJLW',
            'avg_vlw'          => 'AvgVLW'
        );

        $column = isset($metric_column_map[$priority_metric]) ? $metric_column_map[$priority_metric] : 'TotalItemSales';

        
        $vitals_table = $wpdb->prefix . 'aieo_core_product_vitals';
        $table_exists = $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $vitals_table)) === $vitals_table;

        if (!$table_exists) {
            
            $products_with_sales = array();
            foreach ($post_ids as $post_id) {
                $total_sales = (int) get_post_meta($post_id, 'total_sales', true);
                $products_with_sales[] = array(
                    'id' => $post_id,
                    'sales' => $total_sales
                );
            }

            
            usort($products_with_sales, function($a, $b) {
                return $b['sales'] - $a['sales'];
            });

            return array_column($products_with_sales, 'id');
        }

        
        $placeholders = implode(',', array_fill(0, count($post_ids), '%d'));

        
        
        
        
        $temp_orders_table = $wpdb->prefix . 'aieo_temp_orders';
        $query = "
            SELECT ProductId, MAX({$column}) as metric_value
            FROM {$temp_orders_table}
            WHERE ProductId IN ({$placeholders})
            GROUP BY ProductId
            ORDER BY metric_value DESC
        ";

        
        
        $prepared_query = $wpdb->prepare($query, $post_ids);

        
        
        $results = $wpdb->get_results($prepared_query, ARRAY_A);

        if (empty($results)) {
            
            return $post_ids;
        }

        
        $sorted_ids = array_column($results, 'ProductId');

        
        $missing_ids = array_diff($post_ids, $sorted_ids);
        if (!empty($missing_ids)) {
            $sorted_ids = array_merge($sorted_ids, $missing_ids);
        }

        
        $sorted_ids = array_values(array_unique(array_map('intval', $sorted_ids)));

        return $sorted_ids;
    }

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

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

        $post_type = isset($_POST['post_type']) ? sanitize_text_field(wp_unslash( $_POST['post_type'] )) : 'product';
        $batch_size = isset($_POST['batch_size']) ? (int) $_POST['batch_size'] : 50;
        $offset = isset($_POST['offset']) ? (int) $_POST['offset'] : 0;
        $engine_type = isset($_POST['engine_type']) ? sanitize_text_field(wp_unslash( $_POST['engine_type'] )) : null;
        $deduplicated = isset($_POST['deduplicated']) ? (int) $_POST['deduplicated'] : 0;

        
        
        

        
        $original_provider = null;
        $original_model = null;
        if ($engine_type) {
            
            if (strpos($engine_type, 'text-embedding') === 0) {
                
                $original_provider = get_option('aieo_embedding_provider');
                $original_model = get_option('aieo_chat_openai_embedding_model');
                update_option('aieo_embedding_provider', 'openai');
                update_option('aieo_chat_openai_embedding_model', $engine_type);
                
                wp_cache_delete('aieo_embedding_provider', 'options');
                wp_cache_delete('aieo_chat_openai_embedding_model', 'options');
            } else {
                
                $original_provider = get_option('aieo_embedding_provider');
                $original_model = get_option('aieo_chat_embedding_model');
                update_option('aieo_embedding_provider', 'voyage');
                update_option('aieo_chat_embedding_model', $engine_type);
                
                wp_cache_delete('aieo_embedding_provider', 'options');
                wp_cache_delete('aieo_chat_embedding_model', 'options');
            }
        }

        
        $result = $this->generate_all_embeddings($post_type, $batch_size, $offset, $deduplicated, $engine_type);

        
        if ($engine_type && $original_provider !== null) {
            update_option('aieo_embedding_provider', $original_provider);
            if (strpos($engine_type, 'text-embedding') === 0) {
                update_option('aieo_chat_openai_embedding_model', $original_model);
            } else {
                update_option('aieo_chat_embedding_model', $original_model);
            }
            
            wp_cache_delete('aieo_embedding_provider', 'options');
            wp_cache_delete('aieo_chat_openai_embedding_model', 'options');
            wp_cache_delete('aieo_chat_embedding_model', 'options');
        }

        wp_send_json_success($result);
    }

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

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

        $taxonomy = isset($_POST['taxonomy']) ? sanitize_text_field(wp_unslash( $_POST['taxonomy'] )) : 'product_cat';
        $batch_size = isset($_POST['batch_size']) ? (int) $_POST['batch_size'] : 50;
        $offset = isset($_POST['offset']) ? (int) $_POST['offset'] : 0;
        $engine_type = isset($_POST['engine_type']) ? sanitize_text_field(wp_unslash( $_POST['engine_type'] )) : null;
        $deduplicated = isset($_POST['deduplicated']) ? (int) $_POST['deduplicated'] : 0;

        
        $original_provider = null;
        $original_model = null;
        if ($engine_type) {
            
            if (strpos($engine_type, 'text-embedding') === 0) {
                
                $original_provider = get_option('aieo_embedding_provider');
                $original_model = get_option('aieo_chat_openai_embedding_model');
                update_option('aieo_embedding_provider', 'openai');
                update_option('aieo_chat_openai_embedding_model', $engine_type);
                
                wp_cache_delete('aieo_embedding_provider', 'options');
                wp_cache_delete('aieo_chat_openai_embedding_model', 'options');
            } else {
                
                $original_provider = get_option('aieo_embedding_provider');
                $original_model = get_option('aieo_chat_embedding_model');
                update_option('aieo_embedding_provider', 'voyage');
                update_option('aieo_chat_embedding_model', $engine_type);
                
                wp_cache_delete('aieo_embedding_provider', 'options');
                wp_cache_delete('aieo_chat_embedding_model', 'options');
            }
        }

        $result = $this->generate_all_taxonomy_embeddings($taxonomy, $batch_size, $offset, $deduplicated);

        
        if ($engine_type && $original_provider !== null) {
            update_option('aieo_embedding_provider', $original_provider);
            if (strpos($engine_type, 'text-embedding') === 0) {
                update_option('aieo_chat_openai_embedding_model', $original_model);
            } else {
                update_option('aieo_chat_embedding_model', $original_model);
            }
            
            wp_cache_delete('aieo_embedding_provider', 'options');
            wp_cache_delete('aieo_chat_openai_embedding_model', 'options');
            wp_cache_delete('aieo_chat_embedding_model', 'options');
        }

        wp_send_json_success($result);
    }

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

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

        $post_id = isset($_POST['post_id']) ? (int) $_POST['post_id'] : 0;

        if (!$post_id) {
            wp_send_json_error(array('message' => __('Invalid post ID', 'ai-eshop-optimizer')));
        }

        $post = get_post($post_id);
        if (!$post) {
            wp_send_json_error(array('message' => __('Post not found', 'ai-eshop-optimizer')));
        }

        $result = $this->generate_embedding($post_id, $post->post_type, true);

        if (is_wp_error($result)) {
            wp_send_json_error(array('message' => $result->get_error_message()));
        }

        wp_send_json_success(array('message' => __('Embedding regenerated successfully', 'ai-eshop-optimizer')));
    }

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

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

        global $wpdb;
        $table_name = $wpdb->prefix . 'aieo_chat_embeddings';

        
        $delete_all = isset($_POST['delete_all']) && sanitize_text_field( wp_unslash( $_POST['delete_all'] ) );
        $types = isset($_POST['types']) && is_array( wp_unslash( $_POST['types'] ) ) ? array_map('sanitize_text_field', wp_unslash( $_POST['types'] )) : array();
        $engine_type = isset($_POST['engine_type']) ? sanitize_text_field(wp_unslash( $_POST['engine_type'] )) : '';
        $deduplicated = isset($_POST['deduplicated']) ? intval($_POST['deduplicated']) : null;

        if ($delete_all) {
            
            if ($engine_type) {
                
                $where = "engine_type = %s";
                $prepare_args = array($engine_type);

                if ($deduplicated !== null) {
                    $where .= " AND deduplicated = %d";
                    $prepare_args[] = $deduplicated;
                }

                
                $count = $wpdb->get_var($wpdb->prepare(
                    "SELECT COUNT(*) FROM {$table_name} WHERE {$where}",
                    $prepare_args
                ));
                $result = $wpdb->query($wpdb->prepare(
                    "DELETE FROM {$table_name} WHERE {$where}",
                    $prepare_args
                ));

                if ($result === false) {
                    wp_send_json_error(array('message' => __('Failed to delete embeddings', 'ai-eshop-optimizer')));
                }

                $dedup_msg = $deduplicated !== null ? ($deduplicated === 1 ? ' (deduplicated)' : ' (full content)') : '';
                wp_send_json_success(array(
                    
                    'message' => sprintf(__('Successfully deleted all %1$d embeddings for engine: %2$s%3$s', 'ai-eshop-optimizer'), $count, $engine_type, $dedup_msg)
                ));
            } else {
                
                $count = $wpdb->get_var("SELECT COUNT(*) FROM {$table_name}");
                $result = $wpdb->query("TRUNCATE TABLE {$table_name}");

                if ($result === false) {
                    wp_send_json_error(array('message' => __('Failed to delete embeddings', 'ai-eshop-optimizer')));
                }

                wp_send_json_success(array(
                    
                    'message' => sprintf(__('Successfully deleted all %d embeddings', 'ai-eshop-optimizer'), $count)
                ));
            }
        } elseif (!empty($types)) {
            
            $placeholders = implode(',', array_fill(0, count($types), '%s'));

            if ($engine_type) {
                
                $where = "post_type IN ($placeholders) AND engine_type = %s";
                $prepare_args = array_merge($types, array($engine_type));

                if ($deduplicated !== null) {
                    $where .= " AND deduplicated = %d";
                    $prepare_args[] = $deduplicated;
                }

                
                $count = $wpdb->get_var($wpdb->prepare(
                    "SELECT COUNT(*) FROM {$table_name} WHERE {$where}",
                    $prepare_args
                ));

                $result = $wpdb->query($wpdb->prepare(
                    "DELETE FROM {$table_name} WHERE {$where}",
                    $prepare_args
                ));
            } else {
                
                $count = $wpdb->get_var($wpdb->prepare(
                    "SELECT COUNT(*) FROM {$table_name} WHERE post_type IN ($placeholders)",
                    $types
                ));

                $result = $wpdb->query($wpdb->prepare(
                    "DELETE FROM {$table_name} WHERE post_type IN ($placeholders)",
                    $types
                ));
            }

            if ($result === false) {
                wp_send_json_error(array('message' => __('Failed to delete embeddings', 'ai-eshop-optimizer')));
            }

            
            $type_labels = array(
                'product' => __('Products', 'ai-eshop-optimizer'),
                'product_variation' => __('Product Variations', 'ai-eshop-optimizer'),
                'post' => __('Blog Posts', 'ai-eshop-optimizer'),
                'page' => __('Pages', 'ai-eshop-optimizer')
            );

            $deleted_types = array();
            foreach ($types as $type) {
                $deleted_types[] = isset($type_labels[$type]) ? $type_labels[$type] : ucfirst($type);
            }

            $type_names = implode(', ', $deleted_types);
            $engine_msg = $engine_type ? ' (' . $engine_type : '';
            if ($deduplicated !== null) {
                $engine_msg .= $deduplicated === 1 ? ' - deduplicated' : ' - full content';
            }
            $engine_msg .= $engine_type ? ')' : '';

            wp_send_json_success(array(
                'message' => sprintf(
                    
                    __('Successfully deleted %1$d embeddings for: %2$s%3$s', 'ai-eshop-optimizer'),
                    $count,
                    $type_names,
                    $engine_msg
                )
            ));
        } else {
            wp_send_json_error(array('message' => __('No content types selected', 'ai-eshop-optimizer')));
        }
    }

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

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

        $engine_type = isset($_POST['engine_type']) ? sanitize_text_field(wp_unslash( $_POST['engine_type'] )) : '';
        $deduplicated = isset($_POST['deduplicated']) ? intval($_POST['deduplicated']) : 1;

        
        
        

        if (empty($engine_type)) {
            wp_send_json_error(array('message' => __('No engine type specified', 'ai-eshop-optimizer')));
        }

        global $wpdb;
        $db = AI_eShop_Chat_Database_Manager::get_instance();
        $stats = array();

        
        $all_post_types = get_post_types(array('public' => true), 'objects');
        $vitals_helper = AI_eShop_Chat_Product_Vitals_Helper::get_instance();
        $vitals_available = $vitals_helper->is_vitals_table_available();
        $vitals_table = $wpdb->prefix . 'aieo_core_product_vitals';

        foreach ($all_post_types as $post_type_obj) {
            $post_type = $post_type_obj->name;

            
            if (in_array($post_type, array('attachment', 'revision', 'nav_menu_item'))) {
                continue;
            }

            
            
            
            
            
            
            if ($post_type === 'product' && $vitals_available) {
                
                $total_count = (int) $wpdb->get_var(
                    "SELECT COUNT(DISTINCT v.product_id)
                     FROM {$vitals_table} v
                     INNER JOIN {$wpdb->posts} p ON v.product_id = p.ID
                     LEFT JOIN (
                         SELECT DISTINCT parent_id
                         FROM {$vitals_table}
                         WHERE product_id <> parent_id
                     ) vp ON vp.parent_id = v.product_id
                     WHERE p.post_type IN ('product', 'product_variation')
                       AND p.post_status = 'publish'
                       AND v.stock > 0
                       AND (v.product_id <> v.parent_id OR vp.parent_id IS NULL)"
                );
            } else {
                
                $counts = wp_count_posts($post_type);
                $total_count = isset($counts->publish) ? (int) $counts->publish : 0;
            }

            
            if ($total_count === 0) {
                continue;
            }

            
            if ($post_type === 'product' && $vitals_available) {
                
                $has_count = (int) $wpdb->get_var($wpdb->prepare(
                    "SELECT COUNT(DISTINCT e.post_id)
                     FROM {$wpdb->prefix}aieo_chat_embeddings e
                     INNER JOIN {$wpdb->posts} p ON e.post_id = p.ID
                     INNER JOIN {$vitals_table} v ON e.post_id = v.product_id
                     LEFT JOIN (
                         SELECT DISTINCT parent_id
                         FROM {$vitals_table}
                         WHERE product_id <> parent_id
                     ) vp ON vp.parent_id = v.product_id
                     WHERE e.engine_type = %s
                       AND e.deduplicated = %d
                       AND p.post_type IN ('product', 'product_variation')
                       AND p.post_status = 'publish'
                       AND v.stock > 0
                       AND (v.product_id <> v.parent_id OR vp.parent_id IS NULL)",
                    $engine_type,
                    $deduplicated
                ));
            } else {
                
                $has_count = (int) $wpdb->get_var($wpdb->prepare(
                    "SELECT COUNT(DISTINCT e.post_id)
                     FROM {$wpdb->prefix}aieo_chat_embeddings e
                     INNER JOIN {$wpdb->posts} p ON e.post_id = p.ID
                     WHERE e.post_type = %s
                     AND e.engine_type = %s
                     AND e.deduplicated = %d
                     AND p.post_type = %s
                     AND p.post_status = 'publish'",
                    $post_type,
                    $engine_type,
                    $deduplicated,
                    $post_type
                ));
            }

            
            $stats[$post_type] = array(
                'label' => $post_type_obj->label,
                'total' => $total_count,
                'has' => $has_count,
                'missing' => $total_count - $has_count
            );
        }

        wp_send_json_success($stats);
    }

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

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

        $engine_type = isset($_POST['engine_type']) ? sanitize_text_field(wp_unslash( $_POST['engine_type'] )) : '';

        if (empty($engine_type)) {
            wp_send_json_error(array('message' => __('No engine type specified', 'ai-eshop-optimizer')));
        }

        
        $valid_engines = array(
            'voyage-2',
            'voyage-large-2',
            'voyage-3',
            'voyage-3-lite',
            'voyage-3-large',
            'voyage-3.5',
            'voyage-3.5-lite',
            'voyage-multilingual-2',
            'text-embedding-3-large',
            'text-embedding-3-small',
            'text-embedding-ada-002'
        );

        if (!in_array($engine_type, $valid_engines)) {
            wp_send_json_error(array('message' => __('Invalid engine type', 'ai-eshop-optimizer')));
        }

        
        $openai_models = array('text-embedding-3-large', 'text-embedding-3-small', 'text-embedding-ada-002');
        $is_openai = in_array($engine_type, $openai_models);

        
        update_option('aieo_embedding_provider', $is_openai ? 'openai' : 'voyage');

        
        if ($is_openai) {
            update_option('aieo_chat_openai_embedding_model', $engine_type);
        } else {
            update_option('aieo_chat_embedding_model', $engine_type);
        }

        wp_send_json_success(array(
            
            'message' => sprintf(__('Embedding model updated to: %s', 'ai-eshop-optimizer'), $engine_type)
        ));
    }

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

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

        global $wpdb;
        $table = $wpdb->prefix . 'aieo_chat_embeddings';

        
        $results = $wpdb->get_results(
            "SELECT DISTINCT engine_type, deduplicated
             FROM {$table}
             ORDER BY engine_type, deduplicated",
            ARRAY_A
        );

        if ($results === false) {
            wp_send_json_error(array('message' => __('Database error', 'ai-eshop-optimizer')));
        }

        
        $voyage_engines = array();
        $openai_engines = array();
        $openai_models = array('text-embedding-3-large', 'text-embedding-3-small', 'text-embedding-ada-002');

        foreach ($results as $row) {
            $engine = $row['engine_type'];
            $dedup = intval($row['deduplicated']);
            $label = $engine . ($dedup === 1 ? ' (deduplicated)' : ' (full content)');
            $value = $engine . ':' . $dedup;

            $engine_data = array(
                'label' => $label,
                'value' => $value,
                'engine' => $engine,
                'deduplicated' => $dedup
            );

            if (in_array($engine, $openai_models)) {
                $openai_engines[] = $engine_data;
            } else {
                $voyage_engines[] = $engine_data;
            }
        }

        wp_send_json_success(array(
            'voyage' => $voyage_engines,
            'openai' => $openai_engines
        ));
    }

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

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

        global $wpdb;
        $table = $wpdb->prefix . 'aieo_chat_embeddings';

        
        $filter = isset($_POST['filter']) ? sanitize_text_field(wp_unslash( $_POST['filter'] )) : '';

        $engine_type = null;
        $deduplicated = null;

        if (!empty($filter)) {
            $parts = explode(':', $filter);
            if (count($parts) === 2) {
                $engine_type = $parts[0];
                $deduplicated = intval($parts[1]);
            }
        }

        
        $where = '1=1';
        $prepare_args = array();

        if ($engine_type) {
            $where .= ' AND engine_type = %s';
            $prepare_args[] = $engine_type;
        }

        if ($deduplicated !== null) {
            $where .= ' AND deduplicated = %d';
            $prepare_args[] = $deduplicated;
        }

        
        if (!empty($prepare_args)) {
            $results = $wpdb->get_results($wpdb->prepare(
                "SELECT post_type, COUNT(*) as count
                 FROM {$table}
                 WHERE {$where}
                 GROUP BY post_type
                 ORDER BY post_type",
                $prepare_args
            ), ARRAY_A);
        } else {
            $results = $wpdb->get_results(
                "SELECT post_type, COUNT(*) as count
                 FROM {$table}
                 WHERE {$where}
                 GROUP BY post_type
                 ORDER BY post_type",
                ARRAY_A
            );
        }

        
        if (!empty($prepare_args)) {
            $total = $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(*) FROM {$table} WHERE {$where}",
                $prepare_args
            ));
        } else {
            $total = $wpdb->get_var("SELECT COUNT(*) FROM {$table} WHERE {$where}");
        }

        
        $by_type = array();
        foreach ($results as $row) {
            $by_type[$row['post_type']] = intval($row['count']);
        }

        wp_send_json_success(array(
            'total' => intval($total),
            'by_type' => $by_type
        ));
    }

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

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

        global $wpdb;
        $table_name = $wpdb->prefix . 'aieo_chat_embeddings';
        $engine_type = isset($_POST['engine_type']) ? sanitize_text_field(wp_unslash( $_POST['engine_type'] )) : '';

        $counts = array();

        if ($engine_type) {
            
            $results = $wpdb->get_results($wpdb->prepare(
                "SELECT post_type, COUNT(*) as count
                 FROM {$table_name}
                 WHERE engine_type = %s
                 GROUP BY post_type",
                $engine_type
            ), ARRAY_A);
        } else {
            
            $results = $wpdb->get_results(
                "SELECT post_type, COUNT(*) as count
                 FROM {$table_name}
                 GROUP BY post_type",
                ARRAY_A
            );
        }

        
        foreach ($results as $row) {
            $counts[$row['post_type']] = (int) $row['count'];
        }

        
        $common_types = array('product', 'product_variation', 'post', 'page');
        foreach ($common_types as $type) {
            if (!isset($counts[$type])) {
                $counts[$type] = 0;
            }
        }

        wp_send_json_success($counts);
    }

    
    private function truncate_for_openai($content, $max_tokens = 6000) {
        
        
        $max_chars = $max_tokens * 2;

        if (strlen($content) <= $max_chars) {
            return $content;
        }

        
        $truncated = substr($content, 0, $max_chars);
        $last_space = strrpos($truncated, ' ');

        if ($last_space !== false && $last_space > ($max_chars * 0.9)) {
            $truncated = substr($truncated, 0, $last_space);
        }

        return $truncated;
    }

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

        if (!current_user_can('manage_options')) {
            wp_send_json_error(__('Unauthorized', 'ai-eshop-optimizer'));
            return;
        }

        $engine_type = isset($_POST['engine_type']) ? sanitize_text_field(wp_unslash( $_POST['engine_type'] )) : '';
        $deduplicated = isset($_POST['deduplicated']) ? intval($_POST['deduplicated']) : null;

        if (empty($engine_type)) {
            wp_send_json_error(__('Engine type is required', 'ai-eshop-optimizer'));
            return;
        }

        
        update_option('aieo_chat_last_trained_engine', $engine_type);

        
        if ($deduplicated !== null) {
            update_option('aieo_chat_last_trained_deduplication', $deduplicated);
        }

        wp_send_json_success(array(
            'message' => __('Last trained settings saved', 'ai-eshop-optimizer'),
            'engine_type' => $engine_type,
            'deduplicated' => $deduplicated
        ));
    }
}

add_action('aieo_chat_generate_single_embedding', function($args) {
    $manager = AI_eShop_Chat_Embedding_Manager::get_instance();
    $manager->generate_embedding($args['post_id'], $args['post_type']);
}, 10, 1);
