<?php
namespace EasyChat\Library\Queue\Jobs;

use EasyChat\Library\Queue\JobInterface;
use EasyChat\Library\AiProvider\Gemini;
use EasyChat\Library\AiProvider\EasyTokensProvider;
use EasyChat\Library\AiProvider\OpenAI;
use EasyChat\Library\Ai\EmbeddingConfigResolver;
use EasyChat\Library\Ai\VectorStorageGuard;
use EasyChat\Library\Http\ProxyPolicy;
use EasyChat\Model\Setting;
use D1medrol\MysqlVector\VectorTable;

class EmbeddingJob implements JobInterface {

    private $registry;

    public function __construct($registry) {
        $this->registry = $registry;
    }

    











    public function handle(array $payload): void {
        $text         = isset($payload['text'])         ? (string) $payload['text']         : '';
        $item_id      = isset($payload['item_id'])      ? (int)    $payload['item_id']      : 0;
        $section_id   = isset($payload['section_id'])   ? (int)    $payload['section_id']   : 0;
        $extra_meta   = isset($payload['meta']) && is_array($payload['meta']) ? $payload['meta'] : [];
        $knowledge_id = isset($payload['knowledge_id']) ? (int)    $payload['knowledge_id'] : 0;
        $origin       = isset($payload['origin'])       ? (string) $payload['origin']       : '';
        $final_status = (isset($payload['final_status']) && $payload['final_status'] === 'disabled')
            ? 'disabled'
            : 'active';

        if ($text === '') {
            throw new \Exception('EmbeddingJob: payload.text is required');
        }

        $db = $this->registry->get('db');

         
         
        if ($origin === 'cms_index') {
            $semantic_enabled = (new Setting($this->registry))->get('chat_cms_semantic_enabled', '0');
            if ((string)$semantic_enabled !== '1') {
                if ($knowledge_id > 0) {
                    $db->query(
                        "UPDATE `" . easychat_db_prefix() . "knowledge`
                         SET status = 'failed', vector_id = NULL,
                             error = 'cms_semantic_paused', date_modified = NOW()
                         WHERE id = $knowledge_id"
                    );
                }
                return;
            }
        }

         
        if ($knowledge_id > 0) {
            $db->query(
                "UPDATE `" . easychat_db_prefix() . "knowledge`
                 SET status = 'indexing', date_modified = NOW()
                 WHERE id = $knowledge_id"
            );
        }

        try {
             
            $model_setting = new Setting($this->registry);
            $provider_name = $model_setting->get('chat_ai_provider', 'gemini');
            $api_key       = $model_setting->get('chat_ai_key',      '');
            $model         = $model_setting->get('chat_ai_model',    'gemini-3.5-flash');
            $api_host      = $model_setting->get('chat_ai_host',     '');

            if (empty($api_key)) {
                throw new \Exception('EmbeddingJob: AI API key is not configured');
            }

            $config = ['model' => $model];
            if ($provider_name === 'easytokens') {
                $config['host'] = 'https://api.easytokens.ru';
            } elseif ($api_host !== '') {
                $config['host'] = rtrim($api_host, '/');
            }

            $proxy = (new ProxyPolicy($model_setting))->proxyForProfile($this->proxyProfileForAiProvider($provider_name));
            if ($proxy !== null) {
                $config['proxy'] = $proxy;
            }

            if ($provider_name === 'gemini') {
                $provider = new Gemini($api_key, $config);
            } elseif ($provider_name === 'easytokens') {
                $provider = new EasyTokensProvider($api_key, $config);
            } else {
                $provider = new OpenAI($api_key, $config);
            }

            $embedding_config = EmbeddingConfigResolver::resolve($provider_name);
            $embedding_model  = $embedding_config['model'];
            $dimension        = (int)$embedding_config['dimension'];

             
            $vector = $provider->getEmbedding(
                $text,
                $embedding_model,
                EmbeddingConfigResolver::requestDimension($embedding_config)
            );

            if (empty($vector) || !is_array($vector)) {
                throw new \Exception('EmbeddingJob: provider returned an empty or invalid embedding');
            }

             
            $mysqli = $db->getRawConnection();
             
             
             
             
            VectorStorageGuard::ensureCompatible($this->registry, VECTOR_STORAGE, $dimension, $knowledge_id);
            $vectorTable = new VectorTable($mysqli, VECTOR_STORAGE, $dimension);

            $vector_id = $vectorTable->upsert($vector);

            $meta = array_merge($extra_meta, [
                'item_id'    => $item_id,
                'section_id' => $section_id ?: null,
            ]);

            $vectorTable->upsertMeta($meta, $vector_id);

             
            if ($knowledge_id > 0) {
                $db->query(
                    "UPDATE `" . easychat_db_prefix() . "knowledge`
                     SET status = '" . $final_status . "', vector_id = $vector_id, error = NULL, date_modified = NOW()
                     WHERE id = $knowledge_id"
                );
            }

        } catch (\Exception $e) {
             
            if ($knowledge_id > 0) {
                $err = $db->escape($e->getMessage());
                $db->query(
                    "UPDATE `" . easychat_db_prefix() . "knowledge`
                     SET status = 'failed', error = '$err', date_modified = NOW()
                     WHERE id = $knowledge_id"
                );
            }
            throw $e;
        }
    }

    private function proxyProfileForAiProvider($provider_name) {
        $provider_name = strtolower(trim((string)$provider_name));
        if ($provider_name === 'gemini') {
            return 'ai_gemini';
        }
        if ($provider_name === 'easytokens') {
            return 'ai_easytokens';
        }
        return 'ai_openai';
    }
}
