<?php
/**
 * AI Provider Factory.
 *
 * Creates AI provider instances based on configuration.
 *
 * @package Inqyra
 */

// If this file is called directly, abort.
if (!defined('WPINC')) {
    die;
}

/**
 * AI Provider Factory class.
 */
class Inqyra_AI_Provider_Factory {

    /**
     * Supported providers.
     */
    const PROVIDERS = ['claude', 'openai', 'gemini', 'mistral', 'deepseek'];

    /**
     * Create a provider instance.
     *
     * @param string $provider Provider name (claude, openai, gemini, mistral, deepseek).
     * @param string $api_key  API key for the provider.
     * @return Inqyra_AI_Provider_Interface Provider instance.
     * @throws Exception If provider is unknown.
     */
    public static function create(string $provider, string $api_key = ''): Inqyra_AI_Provider_Interface {
        // Get API key from settings if not provided
        if (empty($api_key)) {
            $api_key = self::get_api_key($provider);
        }

        switch ($provider) {
            case 'claude':
                return new Inqyra_Claude_Provider($api_key);

            case 'openai':
                return new Inqyra_OpenAI_Provider($api_key);

            case 'gemini':
                return new Inqyra_Gemini_Provider($api_key);

            case 'mistral':
                return new Inqyra_Mistral_Provider($api_key);

            case 'deepseek':
                return new Inqyra_DeepSeek_Provider($api_key);

            default:
                throw new Exception(
                    /* translators: %s: name of the unknown AI provider */
                    esc_html(sprintf(__('Unknown AI provider: %s', 'inqyra'), $provider))
                );
        }
    }

    /**
     * Create a provider for an agent.
     *
     * @param object $agent Agent configuration object.
     * @return Inqyra_AI_Provider_Interface Provider instance.
     * @throws Exception If provider is not configured.
     */
    public static function create_for_agent($agent): Inqyra_AI_Provider_Interface {
        $provider = $agent->provider ?? 'claude';
        $instance = self::create($provider);

        if (!$instance->is_configured()) {
            throw new Exception(
                esc_html(sprintf(
                    /* translators: %s: name of the AI provider (e.g. Claude, OpenAI) */
                    __('API key for %s is not configured. Please add it in Settings.', 'inqyra'),
                    $instance->get_name()
                ))
            );
        }

        return $instance;
    }

    /**
     * Get API key for a provider from settings.
     *
     * @param string $provider Provider name.
     * @return string API key or empty string.
     */
    public static function get_api_key(string $provider): string {
        $settings = get_option('inqyra_settings', []);
        $api_keys = $settings['api_keys'] ?? [];

        $encrypted_key = $api_keys[$provider] ?? '';

        if (empty($encrypted_key)) {
            return '';
        }

        // Decrypt the API key
        if (class_exists('Inqyra_Encryption')) {
            $decrypted = Inqyra_Encryption::decrypt($encrypted_key);
            // If decryption fails, the key might be stored in plain text (legacy)
            if ($decrypted !== false) {
                return $decrypted;
            }
        }

        // Fallback to returning as-is (for legacy unencrypted keys)
        return $encrypted_key;
    }

    /**
     * Get all configured providers.
     *
     * @return array Array of provider names that have API keys configured.
     */
    public static function get_configured_providers(): array {
        $configured = [];

        foreach (self::PROVIDERS as $provider) {
            if (!empty(self::get_api_key($provider))) {
                $configured[] = $provider;
            }
        }

        return $configured;
    }

    /**
     * Get all providers with their configuration status.
     *
     * @return array Array of provider info.
     */
    public static function get_all_providers(): array {
        $providers = [];

        foreach (self::PROVIDERS as $provider_id) {
            try {
                $instance = self::create($provider_id);
                $providers[$provider_id] = [
                    'id' => $provider_id,
                    'name' => $instance->get_name(),
                    'models' => $instance->get_models(),
                    'default_model' => $instance->get_default_model(),
                    'configured' => $instance->is_configured(),
                ];
            } catch (Exception $e) {
                // Skip if provider class doesn't exist
                continue;
            }
        }

        return $providers;
    }

    /**
     * Check if any provider is configured.
     *
     * @return bool Whether at least one provider has an API key.
     */
    public static function has_any_configured(): bool {
        return !empty(self::get_configured_providers());
    }
}
