<?php
/**
 * AI Provider Manager Class
 *
 * Manages different AI providers (OpenAI, Claude, Gemini, etc.)
 *
 * @package AIProductContentImageGenerator
 * @since 1.0.0
 */

namespace AIProductContentImageGenerator\Services;

if (!defined('ABSPATH')) {
    exit; // Exit if accessed directly
}

/**
 * AIProviderManager class for managing AI providers
 */
class AIProviderManager {
    /**
     * Available AI providers
     *
     * @var array
     */
    private $providers = [];

    /**
     * Default provider
     *
     * @var string
     */
    private $default_provider = 'openai';

    /**
     * Constructor
     */
    public function __construct() {
        $this->init_providers();
    }

    /**
     * Initialize available providers
     */
    private function init_providers() {
        $this->providers = [
            'openai' => [
                'name' => 'OpenAI',
                'models' => [
                    'gpt-3.5-turbo' => 'GPT-3.5 Turbo',
                    'gpt-4' => 'GPT-4',
                    'gpt-4-turbo' => 'GPT-4 Turbo'
                ],
                'api_key_option' => 'apcig_openai_api_key',
                'endpoint' => 'https://api.openai.com/v1/chat/completions'
            ],
            'claude' => [
                'name' => 'Anthropic Claude',
                'models' => [
                    'claude-3-haiku' => 'Claude 3 Haiku',
                    'claude-3-sonnet' => 'Claude 3 Sonnet',
                    'claude-3-opus' => 'Claude 3 Opus'
                ],
                'api_key_option' => 'apcig_claude_api_key',
                'endpoint' => 'https://api.anthropic.com/v1/messages'
            ],
            'gemini' => [
                'name' => 'Google Gemini',
                'models' => [
                    'gemini-pro' => 'Gemini Pro',
                    'gemini-pro-vision' => 'Gemini Pro Vision'
                ],
                'api_key_option' => 'apcig_gemini_api_key',
                'endpoint' => 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent'
            ],
            'openrouter' => [
                'name' => 'OpenRouter',
                'models' => [
                    'meta-llama/llama-2-70b-chat' => 'Llama 2 70B',
                    'anthropic/claude-instant-v1' => 'Claude Instant',
                    'google/palm-2-chat-bison' => 'PaLM 2 Chat'
                ],
                'api_key_option' => 'apcig_openrouter_api_key',
                'endpoint' => 'https://openrouter.ai/api/v1/chat/completions'
            ]
        ];
    }

    /**
     * Get available providers
     *
     * @return array
     */
    public function get_providers() {
        return $this->providers;
    }

    /**
     * Get provider configuration
     *
     * @param string $provider_id
     * @return array|null
     */
    public function get_provider($provider_id) {
        return $this->providers[$provider_id] ?? null;
    }

    /**
     * Check if provider is configured
     *
     * @param string $provider_id
     * @return bool
     */
    public function is_provider_configured($provider_id) {
        $provider = $this->get_provider($provider_id);
        if (!$provider) {
            return false;
        }

        $api_key = get_option($provider['api_key_option']);
        return !empty($api_key);
    }

    /**
     * Get configured providers
     *
     * @return array
     */
    public function get_configured_providers() {
        $configured = [];
        foreach ($this->providers as $id => $provider) {
            if ($this->is_provider_configured($id)) {
                $configured[$id] = $provider;
            }
        }
        return $configured;
    }

    /**
     * Get default provider
     *
     * @return string
     */
    public function get_default_provider() {
        $saved_default = get_option('apcig_default_provider', $this->default_provider);
        
        if ($this->is_provider_configured($saved_default)) {
            return $saved_default;
        }

        $configured = $this->get_configured_providers();
        return !empty($configured) ? array_keys($configured)[0] : $this->default_provider;
    }

    /**
     * Set default provider
     *
     * @param string $provider_id
     * @return bool
     */
    public function set_default_provider($provider_id) {
        if (!$this->is_provider_configured($provider_id)) {
            return false;
        }

        return update_option('apcig_default_provider', $provider_id);
    }

    /**
     * Make API request to provider
     *
     * @param string $provider_id
     * @param array $data
     * @return array|WP_Error
     */
    public function make_request($provider_id, $data) {
        $provider = $this->get_provider($provider_id);
        if (!$provider) {
            return new \WP_Error('invalid_provider', 'Invalid AI provider');
        }

        if (!$this->is_provider_configured($provider_id)) {
            return new \WP_Error('provider_not_configured', 'AI provider not configured');
        }

        $api_key = get_option($provider['api_key_option']);
        $headers = $this->get_provider_headers($provider_id, $api_key);
        $body = $this->format_request_body($provider_id, $data);
        $endpoint = $this->get_provider_endpoint($provider_id, $api_key, $data);

        // Prepare request args
        $args = [
            'headers' => $headers,
            'body' => json_encode($body),
            'timeout' => 60
        ];
        
        // Disable SSL verification for local development
        // Check for local domains (.test, .local, localhost) or if WP_DEBUG is enabled
        $home_url = home_url();
        $is_local = (strpos($home_url, 'localhost') !== false || 
                     strpos($home_url, '.test') !== false || 
                     strpos($home_url, '.local') !== false ||
                     strpos($home_url, '127.0.0.1') !== false);
        
        if ($is_local || (defined('WP_DEBUG') && WP_DEBUG)) {
            $args['sslverify'] = false;
        }
        
        $response = wp_remote_post($endpoint, $args);

        if (is_wp_error($response)) {
            return $response;
        }

        $response_code = wp_remote_retrieve_response_code($response);
        $response_body = wp_remote_retrieve_body($response);

        if ($response_code !== 200) {
            return new \WP_Error('api_error', 'API request failed: ' . $response_body);
        }

        return json_decode($response_body, true);
    }

    /**
     * Get endpoint URL for provider
     *
     * @param string $provider_id
     * @param string $api_key
     * @param array $data Request data to determine endpoint type
     * @return string
     */
    private function get_provider_endpoint($provider_id, $api_key, $data = []) {
        $provider = $this->get_provider($provider_id);
        $endpoint = $provider['endpoint'];
        
        if ($provider_id === 'openai' && isset($data['model']) && strpos($data['model'], 'dall-e') === 0) {
            $endpoint = 'https://api.openai.com/v1/images/generations';
        }
        
        if ($provider_id === 'gemini') {
            $endpoint .= '?key=' . $api_key;
        }
        
        return $endpoint;
    }

    /**
     * Get headers for provider
     *
     * @param string $provider_id
     * @param string $api_key
     * @return array
     */
    private function get_provider_headers($provider_id, $api_key) {
        $headers = [
            'Content-Type' => 'application/json'
        ];

        switch ($provider_id) {
            case 'openai':
            case 'openrouter':
                $headers['Authorization'] = 'Bearer ' . $api_key;
                break;
            case 'claude':
                $headers['x-api-key'] = $api_key;
                $headers['anthropic-version'] = '2023-06-01';
                break;
            case 'gemini':
                break;
        }

        return $headers;
    }

    /**
     * Format request body for provider
     *
     * @param string $provider_id
     * @param array $data
     * @return array
     */
    private function format_request_body($provider_id, $data) {
        switch ($provider_id) {
            case 'openai':
            case 'openrouter':
                // Check if this is an image generation request
                if (isset($data['model']) && strpos($data['model'], 'dall-e') === 0) {
                    // Image generation request
                    return [
                        'model' => $data['model'],
                        'prompt' => $data['prompt'],
                        'n' => $data['n'] ?? 1,
                        'size' => $data['size'] ?? '512x512',
                        'response_format' => $data['response_format'] ?? 'url'
                    ];
                } else {
                    // Text generation request
                    return [
                        'model' => $data['model'] ?? 'gpt-3.5-turbo',
                        'messages' => $data['messages'],
                        'max_tokens' => $data['max_tokens'] ?? 1000,
                        'temperature' => $data['temperature'] ?? 0.7
                    ];
                }
            
            case 'claude':
                return [
                    'model' => $data['model'] ?? 'claude-3-haiku',
                    'max_tokens' => $data['max_tokens'] ?? 1000,
                    'messages' => $data['messages']
                ];
            
            case 'gemini':
                $contents = [];
                foreach ($data['messages'] as $message) {
                    $contents[] = [
                        'parts' => [
                            ['text' => $message['content']]
                        ]
                    ];
                }
                
                return [
                    'contents' => $contents,
                    'generationConfig' => [
                        'maxOutputTokens' => $data['max_tokens'] ?? 1000,
                        'temperature' => $data['temperature'] ?? 0.7
                    ]
                ];
        }

        return $data;
    }

    /**
     * Extract content from provider response
     *
     * @param string $provider_id
     * @param array $response
     * @return string
     */
    public function extract_content($provider_id, $response) {
        switch ($provider_id) {
            case 'openai':
            case 'openrouter':
                return $response['choices'][0]['message']['content'] ?? '';
            
            case 'claude':
                return $response['content'][0]['text'] ?? '';
            
            case 'gemini':
                return $response['candidates'][0]['content']['parts'][0]['text'] ?? '';
        }

        return '';
    }

    /**
     * Test API connection for a provider
     *
     * @param string $provider_id
     * @param string $api_key
     * @return bool|\WP_Error
     */
    public function test_connection($provider_id, $api_key) {
        if (!isset($this->providers[$provider_id])) {
            return new \WP_Error('invalid_provider', 'Invalid provider');
        }

        $test_data = [
            'messages' => [
                ['role' => 'user', 'content' => 'Hello']
            ],
            'max_tokens' => 10,
            'temperature' => 0.1
        ];

        try {
            $response = $this->make_request($provider_id, $api_key, $test_data);
            
            if (is_wp_error($response)) {
                return $response;
            }

            $content = $this->extract_content($provider_id, $response);
            
            if (empty($content)) {
                return new \WP_Error('invalid_response', 'Invalid API response');
            }

            return true;
            
        } catch (\Exception $e) {
            return new \WP_Error('connection_failed', $e->getMessage());
        }
    }
}