<?php
/**
 * AI Provider Manager
 * Quản lý tập trung tất cả AI providers
 */

if ( ! defined( 'ABSPATH' ) ) exit; // Thoát nếu truy cập trực tiếp

class AIAutotool_AI_Provider_Manager {
    
    /**
     * Instance
     */
    private static $instance = null;
    
    /**
     * Registered providers
     */
    private $providers = array();
    
    /**
     * Active provider ID
     */
    private $active_provider_id = '';
    
    /**
     * Active model
     */
    private $active_model = '';

    /**
     * Provider routing mode: single or rotate
     */
    private $routing_mode = 'single';
    
    /**
     * Option names
     */
    private $option_active_provider = 'aiautotool_active_ai_provider';
    private $option_active_model = 'aiautotool_active_ai_model';
    private $option_routing_mode = 'aiautotool_ai_provider_routing_mode';
    private $option_rotation_index = 'aiautotool_ai_provider_rotation_index';
    
    /**
     * Get instance
     */
    public static function get_instance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    /**
     * Constructor
     */
    private function __construct() {
        $this->load_providers();
        $this->register_providers();
        $this->load_active_settings();
    }
    
    /**
     * Load provider classes
     */
    private function load_providers() {
        $provider_dir = dirname(__FILE__) . '/providers/';
        
        require_once dirname(__FILE__) . '/aiautotool_ai_provider_base.php';
        
        if (file_exists($provider_dir . 'aiautotool_ai_provider_openai.php')) {
            require_once $provider_dir . 'aiautotool_ai_provider_openai.php';
        }

        if (file_exists($provider_dir . 'aiautotool_ai_provider_openai_compatible.php')) {
            require_once $provider_dir . 'aiautotool_ai_provider_openai_compatible.php';
        }

        if (file_exists($provider_dir . 'aiautotool_ai_provider_anthropic.php')) {
            require_once $provider_dir . 'aiautotool_ai_provider_anthropic.php';
        }

        if (file_exists($provider_dir . 'aiautotool_ai_provider_azure_openai.php')) {
            require_once $provider_dir . 'aiautotool_ai_provider_azure_openai.php';
        }
        
        if (file_exists($provider_dir . 'aiautotool_ai_provider_gemini.php')) {
            require_once $provider_dir . 'aiautotool_ai_provider_gemini.php';
        }
        
        if (file_exists($provider_dir . 'aiautotool_ai_provider_pollinations.php')) {
            require_once $provider_dir . 'aiautotool_ai_provider_pollinations.php';
        }
        
        if (file_exists($provider_dir . 'aiautotool_ai_provider_llm7.php')) {
            require_once $provider_dir . 'aiautotool_ai_provider_llm7.php';
        }
        
        if (file_exists($provider_dir . 'aiautotool_ai_provider_huggingface.php')) {
            require_once $provider_dir . 'aiautotool_ai_provider_huggingface.php';
        }
        
        if (file_exists($provider_dir . 'aiautotool_ai_provider_cloudflare.php')) {
            require_once $provider_dir . 'aiautotool_ai_provider_cloudflare.php';
        }

        $voice_manager_file = dirname(__FILE__) . '/aiautotool_ai_voice_manager.php';
        if (file_exists($voice_manager_file)) {
            require_once $voice_manager_file;
        }
    }
    
    /**
     * Register all providers
     */
    private function register_providers() {
        // OpenAI
        if (class_exists('AIAutotool_AI_Provider_OpenAI')) {
            $this->register_provider(new AIAutotool_AI_Provider_OpenAI());
        }
        
        // Gemini
        if (class_exists('AIAutotool_AI_Provider_Gemini')) {
            $this->register_provider(new AIAutotool_AI_Provider_Gemini());
        }
        
        // Pollinations.ai
        if (class_exists('AIAutotool_AI_Provider_Pollinations')) {
            $this->register_provider(new AIAutotool_AI_Provider_Pollinations());
        }
        
        // LLM7 (separate provider)
        if (class_exists('AIAutotool_AI_Provider_LLM7')) {
            $this->register_provider(new AIAutotool_AI_Provider_LLM7());
        }
        
        // HuggingFace
        if (class_exists('AIAutotool_AI_Provider_HuggingFace')) {
            $this->register_provider(new AIAutotool_AI_Provider_HuggingFace());
        }
        
        // Cloudflare
        if (class_exists('AIAutotool_AI_Provider_Cloudflare')) {
            $this->register_provider(new AIAutotool_AI_Provider_Cloudflare());
        }

        if (class_exists('AIAutotool_AI_Provider_Anthropic')) {
            $this->register_provider(new AIAutotool_AI_Provider_Anthropic());
        }

        if (class_exists('AIAutotool_AI_Provider_Azure_OpenAI')) {
            $this->register_provider(new AIAutotool_AI_Provider_Azure_OpenAI());
        }

        $openai_compatible_providers = array(
            'AIAutotool_AI_Provider_OpenRouter',
            'AIAutotool_AI_Provider_9Router',
            'AIAutotool_AI_Provider_Groq',
            'AIAutotool_AI_Provider_DeepSeek',
            'AIAutotool_AI_Provider_Mistral',
            'AIAutotool_AI_Provider_Together',
            'AIAutotool_AI_Provider_Fireworks',
            'AIAutotool_AI_Provider_Perplexity',
            'AIAutotool_AI_Provider_XAI',
            'AIAutotool_AI_Provider_Ollama',
            'AIAutotool_AI_Provider_GLM_Coding',
            'AIAutotool_AI_Provider_GLM_China',
            'AIAutotool_AI_Provider_Kimi',
            'AIAutotool_AI_Provider_Minimax_Coding',
            'AIAutotool_AI_Provider_Minimax_China',
            'AIAutotool_AI_Provider_Alibaba',
            'AIAutotool_AI_Provider_Alibaba_Intl',
            'AIAutotool_AI_Provider_Volcengine_Ark',
            'AIAutotool_AI_Provider_BytePlus_ModelArk',
            'AIAutotool_AI_Provider_Cerebras',
            'AIAutotool_AI_Provider_Cohere',
            'AIAutotool_AI_Provider_Nebius',
            'AIAutotool_AI_Provider_SiliconFlow',
            'AIAutotool_AI_Provider_Hyperbolic',
            'AIAutotool_AI_Provider_Chutes',
            'AIAutotool_AI_Provider_NVIDIA_NIM',
        );

        foreach ($openai_compatible_providers as $provider_class) {
            if (class_exists($provider_class)) {
                $this->register_provider(new $provider_class());
            }
        }
        
        // Hook for external providers
        do_action('aiautotool_register_ai_providers', $this);
    }
    
    /**
     * Register a provider
     */
    public function register_provider($provider) {
        if ($provider instanceof AIAutotool_AI_Provider_Base) {
            $this->providers[$provider->get_id()] = $provider;
        }
    }
    
    /**
     * Load active settings
     */
    private function load_active_settings() {
        $this->active_provider_id = get_option($this->option_active_provider, '');
        $this->active_model = get_option($this->option_active_model, '');
        $this->routing_mode = get_option($this->option_routing_mode, 'single');
        if (!in_array($this->routing_mode, array('single', 'rotate'), true)) {
            $this->routing_mode = 'single';
        }
        
        // Auto-detect if not set
        if (empty($this->active_provider_id)) {
            $this->auto_detect_provider();
        }
    }
    
    /**
     * Auto detect best available provider
     * Public method to allow triggering auto-detection when API keys are added
     */
    public function auto_detect_provider() {
        // Refresh providers to check their current configuration status
        $this->refresh_providers();
        
        foreach ($this->get_provider_priority() as $provider_id) {
            $provider = $this->get_provider($provider_id);
            if ($provider && $provider->is_configured()) {
                $this->set_active_provider($provider_id);
                
                // Set default model
                if (empty($this->active_model)) {
                    $this->set_active_model($provider->get_default_model());
                }
                
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * Refresh provider instances to check their current configuration
     * This is needed when API keys are added/removed
     */
    public function refresh_providers() {
        // Clear existing providers
        $this->providers = array();
        
        // Re-register providers to refresh their API key status
        $this->register_providers();
    }
    
    /**
     * Get provider by ID
     */
    public function get_provider($provider_id) {
        return isset($this->providers[$provider_id]) ? $this->providers[$provider_id] : null;
    }
    
    /**
     * Get all providers
     */
    public function get_all_providers() {
        return $this->providers;
    }
    
    /**
     * Get active provider
     */
    public function get_active_provider() {
        if (empty($this->active_provider_id)) {
            $this->auto_detect_provider();
        }
        
        return $this->get_provider($this->active_provider_id);
    }
    
    /**
     * Set active provider
     */
    public function set_active_provider($provider_id) {
        if (isset($this->providers[$provider_id])) {
            $this->active_provider_id = $provider_id;
            update_option($this->option_active_provider, $provider_id);
            
            // Also update model to provider's default
            $provider = $this->get_provider($provider_id);
            if ($provider) {
                $this->set_active_model($provider->get_default_model());
            }
            
            return true;
        }
        return false;
    }
    
    /**
     * Get active model
     */
    public function get_active_model() {
        if (empty($this->active_model)) {
            $provider = $this->get_active_provider();
            if ($provider) {
                $this->active_model = $provider->get_default_model();
            }
        }
        return $this->active_model;
    }
    
    /**
     * Set active model
     */
    public function set_active_model($model) {
        $this->active_model = $model;
        update_option($this->option_active_model, $model);
    }

    /**
     * Get provider routing mode.
     */
    public function get_provider_routing_mode() {
        if (!in_array($this->routing_mode, array('single', 'rotate'), true)) {
            $this->routing_mode = get_option($this->option_routing_mode, 'single');
        }

        return in_array($this->routing_mode, array('single', 'rotate'), true) ? $this->routing_mode : 'single';
    }

    /**
     * Set provider routing mode.
     */
    public function set_provider_routing_mode($mode) {
        $mode = in_array($mode, array('single', 'rotate'), true) ? $mode : 'single';
        $this->routing_mode = $mode;
        update_option($this->option_routing_mode, $mode);

        return true;
    }

    /**
     * Provider order used for auto-detect, fallback, and rotate mode.
     */
    public function get_provider_priority() {
        return array(
            'pollinations',
            'llm7',
            'ollama',
            '9router',
            'gemini',
            'groq',
            'openrouter',
            'huggingface',
            'deepseek',
            'mistral',
            'together',
            'fireworks',
            'perplexity',
            'xai',
            'glm_coding',
            'glm_china',
            'kimi',
            'alibaba',
            'alibaba_intl',
            'volcengine_ark',
            'byteplus_modelark',
            'siliconflow',
            'cerebras',
            'cohere',
            'nebius',
            'hyperbolic',
            'chutes',
            'nvidia_nim',
            'minimax_coding',
            'minimax_china',
            'anthropic',
            'openai',
            'azure_openai',
            'cloudflare',
        );
    }

    /**
     * Build configured provider configs in deterministic order.
     */
    public function get_configured_provider_configs() {
        $this->refresh_providers();
        $configs = array();
        $seen = array();

        foreach ($this->get_provider_priority() as $provider_id) {
            $provider = $this->get_provider($provider_id);
            if ($provider && $provider->is_configured()) {
                $configs[] = array(
                    'provider' => $provider,
                    'provider_id' => $provider_id,
                    'model' => ($provider_id === $this->active_provider_id && !empty($this->active_model)) ? $this->active_model : $provider->get_default_model(),
                );
                $seen[$provider_id] = true;
            }
        }

        foreach ($this->providers as $provider_id => $provider) {
            if (isset($seen[$provider_id]) || !$provider->is_configured()) {
                continue;
            }

            $configs[] = array(
                'provider' => $provider,
                'provider_id' => $provider_id,
                'model' => ($provider_id === $this->active_provider_id && !empty($this->active_model)) ? $this->active_model : $provider->get_default_model(),
            );
        }

        return $configs;
    }

    /**
     * Get provider and model for one AI request based on routing mode.
     */
    public function get_provider_for_request() {
        if ($this->get_provider_routing_mode() !== 'rotate') {
            $provider = $this->get_active_provider();
            if (!$provider || !$provider->is_configured()) {
                $this->auto_detect_provider();
                $provider = $this->get_active_provider();
            }

            if (!$provider || !$provider->is_configured()) {
                return false;
            }

            return array(
                'provider' => $provider,
                'provider_id' => $provider->get_id(),
                'model' => $this->get_active_model() ?: $provider->get_default_model(),
                'routing_mode' => 'single',
            );
        }

        $configs = $this->get_configured_provider_configs();
        if (empty($configs)) {
            return false;
        }

        $count = count($configs);
        $index = (int) get_option($this->option_rotation_index, 0);
        if ($index < 0 || $index >= $count) {
            $index = 0;
        }

        $selected = $configs[$index];
        update_option($this->option_rotation_index, ($index + 1) % $count, false);

        return array(
            'provider' => $selected['provider'],
            'provider_id' => $selected['provider_id'],
            'model' => $selected['model'],
            'routing_mode' => 'rotate',
        );
    }

    /**
     * Get configured providers that support image generation.
     */
    public function get_image_provider_configs() {
        $this->refresh_providers();
        $configs = array();
        $seen = array();

        foreach ($this->get_provider_priority() as $provider_id) {
            $provider = $this->get_provider($provider_id);
            if (!$provider || !$provider->supports_capability('image_generation') || !$provider->is_configured()) {
                continue;
            }

            $image_models = $provider->get_image_models();
            if (empty($image_models)) {
                continue;
            }

            $configs[] = array(
                'provider' => $provider,
                'provider_id' => $provider_id,
                'model' => key($image_models),
                'models' => $image_models,
            );
            $seen[$provider_id] = true;
        }

        foreach ($this->providers as $provider_id => $provider) {
            if (isset($seen[$provider_id]) || !$provider->supports_capability('image_generation') || !$provider->is_configured()) {
                continue;
            }

            $image_models = $provider->get_image_models();
            if (empty($image_models)) {
                continue;
            }

            $configs[] = array(
                'provider' => $provider,
                'provider_id' => $provider_id,
                'model' => key($image_models),
                'models' => $image_models,
            );
        }

        return $configs;
    }

    /**
     * Get image provider/model for one request.
     */
    public function get_image_provider_for_request($provider_id = '', $model = '') {
        $provider_id = sanitize_text_field((string) $provider_id);
        $model = sanitize_text_field((string) $model);

        if ($provider_id !== '') {
            $provider = $this->get_provider($provider_id);
            if (!$provider || !$provider->supports_capability('image_generation') || !$provider->is_configured()) {
                return false;
            }

            $models = $provider->get_image_models();
            if (empty($models)) {
                return false;
            }

            if ($model === '' || !isset($models[$model])) {
                $model = key($models);
            }

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

        $configs = $this->get_image_provider_configs();
        if (empty($configs)) {
            return false;
        }

        return array(
            'provider' => $configs[0]['provider'],
            'provider_id' => $configs[0]['provider_id'],
            'model' => $configs[0]['model'],
            'routing_mode' => 'auto',
        );
    }
    
    /**
     * Get configured providers
     */
    public function get_configured_providers() {
        $configured = array();
        foreach ($this->providers as $id => $provider) {
            if ($provider->is_configured()) {
                $configured[$id] = $provider;
            }
        }
        return $configured;
    }
    
    /**
     * Check if any provider is configured
     */
    public function has_configured_provider() {
        foreach ($this->providers as $provider) {
            if ($provider->is_configured()) {
                return true;
            }
        }
        return false;
    }
    
    /**
     * Get provider info for settings UI
     */
    public function get_providers_info() {
        // Refresh providers to ensure we have latest configuration status
        // This is important when API keys are added/removed, especially for Cloudflare
        // which needs to parse credentials dynamically
        $this->refresh_providers();
        
        $info = array();
        foreach ($this->providers as $id => $provider) {
            // Call is_configured() which will dynamically check for keys
            // This ensures we get the latest status even if provider was instantiated earlier
            $is_configured = $provider->is_configured();
            
            $info[$id] = array(
                'id' => $id,
                'name' => $provider->get_name(),
                'configured' => $is_configured,
                'models' => $provider->get_available_models(),
                'default_model' => $provider->get_default_model(),
                'capabilities' => $provider->get_capabilities()
            );
        }
        return $info;
    }

    /**
     * Get image generation provider info for frontend selects.
     */
    public function get_image_providers_info() {
        $info = array();
        foreach ($this->get_image_provider_configs() as $config) {
            $provider = $config['provider'];
            $provider_id = $config['provider_id'];
            $info[$provider_id] = array(
                'id' => $provider_id,
                'name' => $provider->get_name(),
                'configured' => true,
                'models' => $config['models'],
                'default_model' => $config['model'],
                'capabilities' => $provider->get_capabilities(),
            );
        }
        return $info;
    }
}

// Initialize
AIAutotool_AI_Provider_Manager::get_instance();

// Auto-detect provider on admin_init if no provider is active
add_action('admin_init', function() {
    $manager = AIAutotool_AI_Provider_Manager::get_instance();
    $active_provider = $manager->get_active_provider();
    if (!$active_provider) {
        // Try to auto-detect if no provider is active
        $manager->auto_detect_provider();
    }
}, 20); // Priority 20 to run after other admin_init hooks
