<?php
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Admin AI Models Handler
 *
 * Handles provider connection, provider configuration, and default model settings.
 *
 * @package    Kitsune_AI_Platform
 * @subpackage Kitsune_AI_Platform/admin
 */
class Kitsune_AI_Platform_Admin_Models extends Kitsune_AI_Platform_Admin_Ajax_Base {

    /**
     * Register AJAX hooks.
     */
    public function register_hooks() {
        add_action('wp_ajax_kitsune_ai_platform_test_api_connection', array($this, 'ajax_test_api_connection'));
        add_action('wp_ajax_kitsune_ai_platform_test_api', array($this, 'ajax_test_api_connection'));
        add_action('wp_ajax_kitsune_ai_platform_get_ai_providers', array($this, 'ajax_get_ai_providers'));
        add_action('wp_ajax_kitsune_ai_platform_get_provider', array($this, 'ajax_get_provider'));
        add_action('wp_ajax_kitsune_ai_platform_update_provider', array($this, 'ajax_update_provider'));
        add_action('wp_ajax_kitsune_ai_platform_get_default_settings', array($this, 'ajax_get_default_settings'));
        add_action('wp_ajax_kitsune_ai_platform_save_default_settings', array($this, 'ajax_save_default_settings'));
    }

    /**
     * AJAX: Test API connection
     */
    public function ajax_test_api_connection() {
        if (!$this->verify_admin_request('models')) {
            return;
        }

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

        if (empty($provider) || empty($api_key)) {
            wp_send_json_error(array('message' => __('Provider and API key are required', 'kitsune-ai-platform')));
            return;
        }

        require_once KITSUNE_AI_PLATFORM_PLUGIN_DIR . 'includes/class-kitsune-ai-platform-api.php';
        $api = new Kitsune_AI_Platform_API();
        $result = $api->test_connection($provider, $api_key);

        if (!empty($result['success'])) {
            wp_send_json_success(array(
                'message' => __('API connection successful', 'kitsune-ai-platform'),
                'data' => $result['data']
            ));
        } else {
            wp_send_json_error(array(
                'message' => $result['message'] ?? __('API connection failed', 'kitsune-ai-platform')
            ));
        }
    }

    /**
     * AJAX: Get AI providers
     */
    public function ajax_get_ai_providers() {
        if (!$this->verify_admin_request('models')) {
            return;
        }

        $providers = $this->get_available_providers();

        foreach ($providers as $key => &$provider) {
            $constant_name = 'KITSUNE_AI_PLATFORM_' . strtoupper(str_replace('-', '_', $key)) . '_API_KEY';
            if (defined($constant_name)) {
                $provider['connected'] = true;
                $provider['source'] = 'env';
                $provider['config'] = array('api_key_masked' => 'configured-in-env');
                continue;
            }

            $secure_key = $this->get_secure_key($key);
            if (!$secure_key) {
                $config = get_option('kitsune_ai_platform_provider_' . $key, array());
                if (!empty($config['api_key'])) {
                    $this->store_secure_key($key, $config['api_key']);
                    $config['api_key'] = '';
                    update_option('kitsune_ai_platform_provider_' . $key, $config);
                    $secure_key = $this->get_secure_key($key);
                }
            } else {
                $config = get_option('kitsune_ai_platform_provider_' . $key, array());
            }

            $provider['connected'] = !empty($secure_key);
            $provider['config'] = $config;

            if ($secure_key) {
                $provider['config']['api_key_masked'] = $this->mask_api_key($secure_key);
            }
        }

        wp_send_json_success($providers);
    }

    /**
     * AJAX: Get specific provider
     */
    public function ajax_get_provider() {
        if (!$this->verify_admin_request('models')) {
            return;
        }

        $provider_id = isset($_GET['provider']) ? sanitize_text_field(wp_unslash($_GET['provider'])) : '';
        $providers = $this->get_available_providers();

        if (empty($provider_id) || !isset($providers[$provider_id])) {
            wp_send_json_error(array('message' => __('Provider not found', 'kitsune-ai-platform')));
            return;
        }

        $provider = $providers[$provider_id];
        $constant_name = 'KITSUNE_AI_PLATFORM_' . strtoupper(str_replace('-', '_', $provider_id)) . '_API_KEY';

        if (defined($constant_name)) {
            $provider['connected'] = true;
            $provider['source'] = 'env';
            $provider['config'] = array('api_key_masked' => 'configured-in-env');
            $provider['is_env_var'] = true;
            wp_send_json_success($provider);
            return;
        }

        $secure_key = $this->get_secure_key($provider_id);
        $config = get_option('kitsune_ai_platform_provider_' . $provider_id, array());

        $provider['connected'] = !empty($secure_key);
        $provider['config'] = $config;

        if ($secure_key) {
            $provider['config']['api_key_masked'] = $this->mask_api_key($secure_key);
        }

        wp_send_json_success($provider);
    }

    /**
     * AJAX: Update provider
     */
    public function ajax_update_provider() {
        if (!$this->verify_admin_request('models')) {
            return;
        }

        $provider_id = isset($_POST['provider']) ? sanitize_text_field(wp_unslash($_POST['provider'])) : '';
        $providers = $this->get_available_providers();

        if (empty($provider_id) || !isset($providers[$provider_id])) {
            wp_send_json_error(array('message' => __('Provider not found', 'kitsune-ai-platform')));
            return;
        }

        $constant_name = 'KITSUNE_AI_PLATFORM_' . strtoupper(str_replace('-', '_', $provider_id)) . '_API_KEY';
        if (defined($constant_name)) {
            wp_send_json_error(array('message' => __('API key is managed via environment variable and cannot be changed here.', 'kitsune-ai-platform')));
            return;
        }

        $data = $this->get_post_payload('data', array());
        if (!$data) {
            $data = map_deep(wp_unslash($_POST), 'sanitize_text_field');
        }

        $api_key = !empty($data['api_key']) ? sanitize_text_field($data['api_key']) : '';
        if (!empty($api_key) && strpos($api_key, '***') === false) {
            if (!$this->validate_api_key_format($api_key, $provider_id)) {
                wp_send_json_error(array('message' => __('Invalid API key format', 'kitsune-ai-platform')));
                return;
            }

            $this->store_secure_key($provider_id, $api_key);
            $this->log_audit($provider_id, 'update_key');
        }

        $settings = isset($data['settings']) ? $data['settings'] : array();
        if (is_string($settings)) {
            $decoded_settings = json_decode(wp_unslash($settings), true);
            $settings = is_array($decoded_settings) ? $decoded_settings : array();
        }
        $settings = is_array($settings) ? map_deep($settings, 'sanitize_text_field') : array();

        $selected_chat_models = isset($data['selected_chat_models']) ? $data['selected_chat_models'] : array();
        if (is_string($selected_chat_models)) {
            $decoded_chat_models = json_decode(wp_unslash($selected_chat_models), true);
            $selected_chat_models = is_array($decoded_chat_models) ? $decoded_chat_models : array();
        }

        $selected_embedding_models = isset($data['selected_embedding_models']) ? $data['selected_embedding_models'] : array();
        if (is_string($selected_embedding_models)) {
            $decoded_embedding_models = json_decode(wp_unslash($selected_embedding_models), true);
            $selected_embedding_models = is_array($decoded_embedding_models) ? $decoded_embedding_models : array();
        }

        $selected_image_models = isset($data['selected_image_models']) ? $data['selected_image_models'] : array();
        if (is_string($selected_image_models)) {
            $decoded_image_models = json_decode(wp_unslash($selected_image_models), true);
            $selected_image_models = is_array($decoded_image_models) ? $decoded_image_models : array();
        }

        $config = array(
            'selected_chat_models' => !empty($selected_chat_models) ? array_map('sanitize_text_field', (array) $selected_chat_models) : array(),
            'selected_embedding_models' => !empty($selected_embedding_models) ? array_map('sanitize_text_field', (array) $selected_embedding_models) : array(),
            'selected_image_models' => !empty($selected_image_models) ? array_map('sanitize_text_field', (array) $selected_image_models) : array(),
            'enabled' => !empty($data['enabled']) && $data['enabled'] !== 'false',
            'settings' => !empty($settings) ? $settings : array(),
            'api_key' => '',
        );

        update_option('kitsune_ai_platform_provider_' . $provider_id, $config);

        wp_send_json_success(array(
            'message' => __('Provider configuration updated', 'kitsune-ai-platform'),
        ));
    }

    /**
     * AJAX: Get default model settings
     */
    public function ajax_get_default_settings() {
        if (!$this->verify_admin_request('models')) {
            return;
        }

        $defaults = get_option('kitsune_ai_platform_default_models', array(
            'chatbots' => '',
            'content' => '',
            'imageGen' => '',
            'embeddings' => '',
            'fallback' => '',
        ));

        $response = array();
        foreach ($defaults as $key => $value) {
            $response[$key] = $this->format_model_value($value);
        }

        wp_send_json_success($response);
    }

    /**
     * AJAX: Save default model settings
     */
    public function ajax_save_default_settings() {
        if (!$this->verify_admin_request('models')) {
            return;
        }

        $data = $this->get_post_payload('data', array());
        if (!$data) {
            $data = map_deep(wp_unslash($_POST), 'sanitize_text_field');
        }

        $defaults = array(
            'chatbots' => $this->normalize_model_payload($data['chatbots'] ?? ''),
            'content' => $this->normalize_model_payload($data['content'] ?? ''),
            'imageGen' => $this->normalize_model_payload($data['imageGen'] ?? ''),
            'embeddings' => $this->normalize_model_payload($data['embeddings'] ?? ''),
            'fallback' => $this->normalize_model_payload($data['fallback'] ?? ''),
        );

        // Guard: block embedding model change if any KB source was synced after the last reset.
        $current_defaults     = get_option('kitsune_ai_platform_default_models', array());
        $current_embeddings   = $this->normalize_model_payload($current_defaults['embeddings'] ?? '');
        $requested_embeddings = $defaults['embeddings'];

        if ($requested_embeddings !== '' && $requested_embeddings !== $current_embeddings) {
            $last_reset = get_option('kitsune_ai_platform_kb_last_reset', '');
            $meta_query = array(
                array(
                    'key'   => '_ai_platform_kb_status',
                    'value' => 'synced',
                ),
            );
            if ($last_reset !== '') {
                $meta_query[] = array(
                    'key'     => '_ai_platform_kb_last_updated',
                    'value'   => $last_reset,
                    'compare' => '>=',
                    'type'    => 'DATETIME',
                );
            }
            $synced = get_posts(array(
                'post_type'      => 'kitsune_ai_kb_source',
                'post_status'    => array('private', 'publish', 'draft'),
                'posts_per_page' => 1,
                'fields'         => 'ids',
                'no_found_rows'  => false,
                'meta_query'     => $meta_query,
            ));
            if (!empty($synced)) {
                wp_send_json_error(array(
                    'message' => __('Cannot change the embedding model while knowledge base sources are synced. Reset the knowledge base first.', 'kitsune-ai-platform'),
                    'blocked' => true,
                ));
                return;
            }
        }

        update_option('kitsune_ai_platform_default_models', $defaults);

        wp_send_json_success(array(
            'message' => __('Default models updated', 'kitsune-ai-platform'),
        ));
    }

    /**
     * Get available AI providers.
     *
     * @return array
     */
    private function get_available_providers() {
        return array(
            'openai' => array(
                'id' => 'openai',
                'name' => 'OpenAI',
                'logo' => plugins_url('admin/assets/images/openai-logo.svg', dirname(__FILE__)),
                'icon' => 'fas fa-robot',
                'chat_models' => array(
                    'gpt-4o' => array('name' => 'GPT-4o'),
                    'gpt-4o-mini' => array('name' => 'GPT-4o Mini'),
                    'gpt-4.1' => array('name' => 'GPT-4.1'),
                    'gpt-4.1-mini' => array('name' => 'GPT-4.1 Mini'),
                    'gpt-4.1-nano' => array('name' => 'GPT-4.1 Nano'),
                    'gpt-5.2' => array('name' => 'GPT-5.2'),
                    'gpt-5.1' => array('name' => 'GPT-5.1'),
                    'gpt-5' => array('name' => 'GPT-5'),
                    'gpt-5-mini' => array('name' => 'GPT-5 Mini'),
                    'gpt-5-nano' => array('name' => 'GPT-5 Nano'),
                    'o3' => array('name' => 'o3'),
                    'o3-mini' => array('name' => 'o3 Mini'),
                    'o4-mini' => array('name' => 'o4 Mini'),
                ),
                'embedding_models' => array(
                    'text-embedding-3-small' => array('name' => 'Text Embedding 3 Small'),
                    'text-embedding-3-large' => array('name' => 'Text Embedding 3 Large'),
                    'text-embedding-ada-002' => array('name' => 'Ada 002'),
                ),
                'image_models' => array(
                    'dall-e-3' => array('name' => 'DALL-E 3'),
                    'dall-e-2' => array('name' => 'DALL-E 2'),
                ),
                'requires_api_key' => true,
            ),
            'anthropic' => array(
                'id' => 'anthropic',
                'name' => 'Anthropic',
                'logo' => plugins_url('admin/assets/images/anthropic-logo.svg', dirname(__FILE__)),
                'icon' => 'fas fa-bolt',
                'chat_models' => array(
                    'claude-opus-4-6-20260205' => array('name' => 'Claude Opus 4.6'),
                    'claude-opus-4-5-20251101' => array('name' => 'Claude Opus 4.5'),
                    'claude-sonnet-4-5-20250929' => array('name' => 'Claude Sonnet 4.5'),
                    'claude-sonnet-4-20250514' => array('name' => 'Claude Sonnet 4'),
                    'claude-haiku-4-5-20251001' => array('name' => 'Claude Haiku 4.5'),
                ),
                'embedding_models' => array(),
                'image_models' => array(),
                'requires_api_key' => true,
            ),
            'google' => array(
                'id' => 'google',
                'name' => 'Google',
                'logo' => plugins_url('admin/assets/images/google-logo.svg', dirname(__FILE__)),
                'icon' => 'fab fa-google',
                'chat_models' => array(
                    'gemini-3-pro-preview' => array('name' => 'Gemini 3 Pro Preview'),
                    'gemini-3-flash-preview' => array('name' => 'Gemini 3 Flash Preview'),
                    'gemini-2.5-pro' => array('name' => 'Gemini 2.5 Pro'),
                    'gemini-2.5-flash' => array('name' => 'Gemini 2.5 Flash'),
                    'gemini-2.5-flash-lite' => array('name' => 'Gemini 2.5 Flash Lite'),
                ),
                'embedding_models' => array(
                    'gemini-embedding-001' => array('name' => 'Gemini Embedding 001'),
                ),
                'image_models' => array(
                    'imagen-3.0-generate-001' => array('name' => 'Imagen 3'),
                ),
                'requires_api_key' => true,
            ),
        );
    }

    /**
     * Normalize model value to a provider+model object.
     *
     * @param mixed $value
     * @return array|string
     */
    private function normalize_model_payload($value) {
        if (is_array($value)) {
            $provider = sanitize_text_field($value['provider'] ?? '');
            $model = sanitize_text_field($value['model'] ?? '');
            if ($model === '') {
                return '';
            }
            if ($provider === '') {
                $provider = $this->resolve_provider_for_model($model);
            }
            return array(
                'provider' => $provider,
                'model' => $model,
            );
        }

        $value = is_string($value) ? trim($value) : '';
        if ($value === '') {
            return '';
        }

        $parts = explode(':', $value, 2);
        $provider = '';
        $model = $value;
        if (count($parts) === 2) {
            $provider = sanitize_text_field($parts[0]);
            $model = sanitize_text_field($parts[1]);
        } else {
            $model = sanitize_text_field($value);
            $provider = $this->resolve_provider_for_model($model);
        }

        if ($model === '') {
            return '';
        }

        return array(
            'provider' => $provider,
            'model' => $model,
        );
    }

    /**
     * Format stored model value as provider:model string.
     *
     * @param mixed $value
     * @return string
     */
    private function format_model_value($value) {
        if (is_array($value)) {
            $provider = sanitize_text_field($value['provider'] ?? '');
            $model = sanitize_text_field($value['model'] ?? '');
            if ($model === '') {
                return '';
            }
            if ($provider === '') {
                $provider = $this->resolve_provider_for_model($model);
            }
            return $provider !== '' ? $provider . ':' . $model : $model;
        }

        $value = is_string($value) ? trim($value) : '';
        if ($value === '') {
            return '';
        }

        if (strpos($value, ':') !== false) {
            return $value;
        }

        $provider = $this->resolve_provider_for_model($value);
        return $provider !== '' ? $provider . ':' . $value : $value;
    }

    /**
     * Resolve provider ID for a model across all providers.
     *
     * @param string $model
     * @return string
     */
    private function resolve_provider_for_model($model) {
        $providers = $this->get_available_providers();
        foreach ($providers as $provider_id => $provider) {
            $collections = array(
                $provider['chat_models'] ?? array(),
                $provider['embedding_models'] ?? array(),
                $provider['image_models'] ?? array(),
            );

            foreach ($collections as $models) {
                if (is_array($models) && array_key_exists($model, $models)) {
                    return $provider_id;
                }
            }
        }

        return '';
    }

    /**
     * Mask API key for display.
     *
     * @param string $api_key API key.
     * @return string
     */
    private function mask_api_key($api_key) {
        if (empty($api_key)) {
            return '';
        }

        if (strlen($api_key) <= 8) {
            return str_repeat('*', strlen($api_key));
        }

        return substr($api_key, 0, 4) . str_repeat('*', strlen($api_key) - 8) . substr($api_key, -4);
    }

    /**
     * Validate provider API key format.
     *
     * @param string $key API key.
     * @param string $provider_id Provider identifier.
     * @return bool
     */
    private function validate_api_key_format($key, $provider_id) {
        if (!is_string($key) || $key === '') {
            return false;
        }

        $patterns = array(
            'openai' => '/^sk-[a-zA-Z0-9]{32,}$/',
            'anthropic' => '/^sk-ant-[a-zA-Z0-9-]{32,}$/',
            'google' => '/^AIza[a-zA-Z0-9-_]{35}$/',
        );

        if (isset($patterns[$provider_id])) {
            return preg_match($patterns[$provider_id], $key) === 1;
        }

        return strlen($key) > 8;
    }

    /**
     * Get key from secure storage.
     *
     * @param string $env_type Provider key.
     * @return string|false
     */
    private function get_secure_key($env_type) {
        $keys = get_option('kitsune_ai_platform_api_keys', array());

        if (empty($keys[$env_type])) {
            return false;
        }

        require_once KITSUNE_AI_PLATFORM_PLUGIN_DIR . 'includes/class-kitsune-ai-platform-encryption.php';
        return Kitsune_AI_Platform_Encryption::decrypt($keys[$env_type]);
    }

    /**
     * Store key in secure storage.
     *
     * @param string $env_type Provider key.
     * @param string $key API key.
     */
    private function store_secure_key($env_type, $key) {
        $keys = get_option('kitsune_ai_platform_api_keys', array());

        require_once KITSUNE_AI_PLATFORM_PLUGIN_DIR . 'includes/class-kitsune-ai-platform-encryption.php';
        $encrypted = Kitsune_AI_Platform_Encryption::encrypt($key);

        $keys[$env_type] = $encrypted;
        update_option('kitsune_ai_platform_api_keys', $keys);
    }

    /**
     * Log provider key update action.
     *
     * @param string $env_type Provider key.
     * @param string $action Action name.
     */
    private function log_audit($env_type, $action) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'kitsune_ai_platform_audit_log';
        $remote_addr = sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'] ?? ''));

        $wpdb->insert(
            $table_name,
            array(
                'env_type' => $env_type,
                'action' => $action,
                'user_id' => get_current_user_id(),
                'ip_address' => $remote_addr,
                'timestamp' => current_time('mysql')
            ),
            array('%s', '%s', '%d', '%s', '%s')
        );
    }

}
