<?php

namespace App\Services;

use App\Contracts\AiProvider;
use App\Models\SystemSetting;
use App\Models\User;
use App\Services\AiProviders\AnthropicProvider;
use App\Services\AiProviders\OpenAiProvider;

class AiProviderFactory
{
    /**
     * Get the appropriate AI provider for a user.
     */
    public static function forUser(User $user): AiProvider
    {
        $settings = $user->aiSettings;

        // Check if user can use their own key and has one configured
        if ($user->canUseOwnAiApiKey() && $settings) {
            $provider = $settings->preferred_provider;

            if ($provider !== 'system' && $settings->hasApiKeyFor($provider)) {
                return self::createProvider($provider, $settings->getApiKeyFor($provider));
            }
        }

        // Fall back to system provider
        return self::getSystemProvider();
    }

    /**
     * Get the system-configured AI provider.
     */
    public static function getSystemProvider(): AiProvider
    {
        $provider = SystemSetting::get('ai_provider', 'openai');
        $apiKey = SystemSetting::get('ai_provider_api_key');

        if (empty($apiKey)) {
            throw new \RuntimeException(__('user.ai_api_key_not_configured'));
        }

        return self::createProvider($provider, $apiKey);
    }

    /**
     * Create a provider instance.
     */
    public static function createProvider(string $provider, string $apiKey): AiProvider
    {
        return match ($provider) {
            'openai' => new OpenAiProvider($apiKey),
            'anthropic' => new AnthropicProvider($apiKey),
            default => throw new \InvalidArgumentException("Unknown AI provider: {$provider}"),
        };
    }

    /**
     * Get all available providers.
     */
    public static function getAvailableProviders(): array
    {
        return [
            'openai' => [
                'id' => 'openai',
                'name' => 'OpenAI',
                'key_prefix' => 'sk-',
                'key_placeholder' => 'sk-...',
            ],
            'anthropic' => [
                'id' => 'anthropic',
                'name' => 'Anthropic (Claude)',
                'key_prefix' => 'sk-ant-',
                'key_placeholder' => 'sk-ant-...',
            ],
        ];
    }

    /**
     * Get available models for a provider.
     */
    public static function getModelsForProvider(string $provider): array
    {
        return match ($provider) {
            'openai' => [
                // GPT-5.2 series (flagship)
                'gpt-5.2' => 'GPT-5.2',
                'gpt-5.2-pro' => 'GPT-5.2 Pro',
                // GPT-5 series
                'gpt-5' => 'GPT-5',
                'gpt-5-mini' => 'GPT-5 Mini',
                'gpt-5-nano' => 'GPT-5 Nano',
                // Reasoning models (o-series)
                'o3' => 'o3 (Reasoning)',
                'o3-mini' => 'o3 Mini (Fast Reasoning)',
                'o4-mini' => 'o4 Mini (Reasoning)',
                // GPT-4.1 series (1M context)
                'gpt-4.1' => 'GPT-4.1',
                'gpt-4.1-mini' => 'GPT-4.1 Mini',
                'gpt-4.1-nano' => 'GPT-4.1 Nano',
                // GPT-4o series
                'gpt-4o' => 'GPT-4o',
                'gpt-4o-mini' => 'GPT-4o Mini',
            ],
            'anthropic' => [
                // Claude 4.5 series (latest)
                'claude-opus-4-5-20251101' => 'Claude Opus 4.5',
                'claude-sonnet-4-5-20250929' => 'Claude Sonnet 4.5',
                'claude-haiku-4-5-20251001' => 'Claude Haiku 4.5',
                // Claude 4.1 series
                'claude-opus-4-1-20250805' => 'Claude Opus 4.1',
                // Claude 4 series
                'claude-opus-4-20250514' => 'Claude Opus 4',
                'claude-sonnet-4-20250514' => 'Claude Sonnet 4',
            ],
            default => [],
        };
    }
}
