<?php

namespace AIPT\Api\OpenRouter;

use AIPT\Api\AIClientInterface;
use AIPT\Utils\PromptFormatter;
use AIPT\Core\ErrorHandler;

class OpenRouterClient implements AIClientInterface {
    private $api_key;
    private $api_url = 'https://openrouter.ai/api/v1/chat/completions';
    private $models = [

        'openrouter/free' => [
            'name' => 'openrouter/free',
            'max_tokens' => 8192,
            'temperature' => 0.7,
            'supports_system_message' => true
        ],
        'meta-llama/llama-3.3-70b-instruct:free' => [
            'name' => 'meta-llama/llama-3.3-70b-instruct:free',
            'max_tokens' => 8192,
            'temperature' => 0.7,
            'supports_system_message' => true
        ],
        'google/gemma-3-27b-it:free' => [
            'name' => 'google/gemma-3-27b-it:free',
            'max_tokens' => 8192,
            'temperature' => 0.7,
            'supports_system_message' => true
        ],
        'deepseek/deepseek-r1:free' => [
            'name' => 'deepseek/deepseek-r1:free',
            'max_tokens' => 8192,
            'temperature' => 0.7,
            'supports_system_message' => true
        ],
        'meta-llama/llama-3.1-8b-instruct:free' => [
            'name' => 'meta-llama/llama-3.1-8b-instruct:free',
            'max_tokens' => 8192,
            'temperature' => 0.7,
            'supports_system_message' => true
        ],
        

        'anthropic/claude-sonnet-4.6' => [
            'name' => 'anthropic/claude-sonnet-4.6',
            'max_tokens' => 8192,
            'temperature' => 0.8,
            'supports_system_message' => true
        ],
        'google/gemini-2.5-flash' => [
            'name' => 'google/gemini-2.5-flash',
            'max_tokens' => 8192,
            'temperature' => 0.8,
            'supports_system_message' => true
        ],
        'deepseek/deepseek-v3.2' => [
            'name' => 'deepseek/deepseek-v3.2',
            'max_tokens' => 8192,
            'temperature' => 0.8,
            'supports_system_message' => true
        ],
        'x-ai/grok-4.1-fast' => [
            'name' => 'x-ai/grok-4.1-fast',
            'max_tokens' => 16384,
            'temperature' => 0.8,
            'supports_system_message' => true
        ],
        'meta-llama/llama-3.1-70b-instruct' => [
            'name' => 'meta-llama/llama-3.1-70b-instruct',
            'max_tokens' => 8192,
            'temperature' => 0.8,
            'supports_system_message' => true
        ],
    ];

    public function __construct($api_key) {
        $this->api_key = $api_key;
    }

    public function generate_description(string $system_prompt, string $user_prompt, string $model = 'openrouter/free', ?int $maximum_length = null): string {

        if (!isset($this->models[$model])) {

            $this->models[$model] = [
                'name' => $model,
                'max_tokens' => 8192,
                'temperature' => 0.7,
                'supports_system_message' => true
            ];
        }

        $model_config = $this->models[$model];
        $messages = [];

        $system_prompt = $this->sanitize_prompt_content($system_prompt);
        $user_prompt = $this->sanitize_prompt_content($user_prompt);

        if ($model_config['supports_system_message']) {
            $messages[] = [
                'role' => 'system',
                'content' => $system_prompt
            ];
            $messages[] = [
                'role' => 'user',
                'content' => $user_prompt
            ];
        } else {
            $messages[] = [
                'role' => 'user',
                'content' => $system_prompt . "\n\n" . $user_prompt
            ];
        }

        $request_body = [
            'model' => $model_config['name'],
            'messages' => $messages,
            'temperature' => $model_config['temperature']
        ];

        if ($maximum_length) {
            $request_body['max_tokens'] = $maximum_length;
        } else if (isset($model_config['max_tokens'])) {
            $request_body['max_tokens'] = $model_config['max_tokens'];
        }

        if (isset($model_config['top_p'])) {
            $request_body['top_p'] = $model_config['top_p'];
        }

        $json_body = wp_json_encode($request_body, JSON_UNESCAPED_UNICODE);

        if ( false === $json_body ) {
            throw new \Exception(
                esc_html__( 'Failed to encode request body as JSON. The product data may contain invalid characters.', 'ai-product-tools' )
            );
        }

        $response = wp_remote_post($this->api_url, [
            'headers' => [
                'Authorization' => 'Bearer ' . $this->api_key,
                'Content-Type' => 'application/json',
                'HTTP-Referer' => self::get_site_url_value(),
                'X-Title' => 'AI Product Tools WordPress Plugin'
            ],
            'body' => $json_body,
            'timeout' => 30,
        ]);

        if ($response instanceof \WP_Error) {
            $error_message = $response->get_error_message();
            throw new \Exception('WP Error: ' . esc_html($error_message));
        }

        $response_code = wp_remote_retrieve_response_code($response);
        $content_type = (string) wp_remote_retrieve_header($response, 'content-type');
        $body_str = (string) wp_remote_retrieve_body($response);

        if (strpos($content_type, 'application/json') === false && !empty($body_str) && $body_str[0] === '<') {
            throw new \Exception(esc_html__('The API response was not valid JSON. This is often caused by a server firewall or security plugin blocking outbound requests. Please contact your hosting provider or check your security plugin settings.', 'ai-product-tools'));
        }

        $body = json_decode($body_str, true);
        if (json_last_error() !== JSON_ERROR_NONE) {

            throw new \Exception(
                sprintf(
                    /* translators: %s: JSON error message */
                    __('Invalid JSON response from the API: %s', 'ai-product-tools'),
                    json_last_error_msg()
                )
            );

        }

        if (isset($body['error'])) {
            $error_data = $body['error'];

            $detailed_error = ErrorHandler::format_api_response_error($error_data, 'OpenRouter', $response_code);

            throw new \Exception($detailed_error);
        }

        if (!isset($body['choices'][0]['message']['content'])) {
            throw new \Exception('Invalid response from OpenRouter API: Response structure is not as expected');
        }

        return trim($body['choices'][0]['message']['content']);
    }

    public function generate_faq_content(string $system_prompt, string $user_prompt, ?string $model = null): string {
        $resolved_model = $model ?: 'openrouter/free';

        return $this->generate_description($system_prompt, $user_prompt, $resolved_model);
    }

    /**
     * Prompt içeriğini temizler ve API için hazırlar
     * 
     * @param string $content Temizlenecek prompt içeriği 
     * @return string Temizlenmiş içerik
     */
    private function sanitize_prompt_content(string $content): string {
        return PromptFormatter::cleanContent($content);
    }

    private static function get_site_url_value(): string {
        return (string) \get_site_url();
    }

	public static function validate_api_key(string $api_key): bool {
		$api_key = trim($api_key);
		if ($api_key === '' || strlen($api_key) < 20) {
			throw new \Exception('Invalid API key');
		}

		$key_validation_response = wp_remote_get('https://openrouter.ai/api/v1/key', [
			'headers' => [
                'Authorization' => 'Bearer ' . $api_key,
                'HTTP-Referer' => self::get_site_url_value(),
                'X-Title' => 'AI Product Tools'
            ],
            'timeout' => 20
        ]);

        if (is_wp_error($key_validation_response)) {

            throw new \Exception('Network error contacting OpenRouter: ' . $key_validation_response->get_error_message());
        }

        $key_response_code = wp_remote_retrieve_response_code($key_validation_response);
        $key_body_str = (string) wp_remote_retrieve_body($key_validation_response);

        if ($key_response_code === 200) {
            $key_body = json_decode($key_body_str, true);

            if (json_last_error() !== JSON_ERROR_NONE) {

                throw new \Exception('OpenRouter API returned invalid JSON: ' . json_last_error_msg());
            }

            if (!isset($key_body['data'])) {
                throw new \Exception('OpenRouter API response missing expected data structure');
            }

            return true;
        }

        if ($key_response_code === 401) {
            throw new \Exception('Invalid API key');
        }

        throw new \Exception('OpenRouter API returned unexpected status: ' . $key_response_code);
    }

    public function get_available_models(): array {
        return $this->models;
    }
    
    /**
     * API istekleri için parametre ayarlarını yapar
     * 
     * @param array $parameters Ayarlanacak parametreler
     * @return void
     */
    public function setParameters(array $parameters): void {
        if (empty($parameters)) {
            return;
        }
        
        try {

            foreach ($this->models as &$model_config) {

                if (isset($parameters['temperature']) && is_numeric($parameters['temperature'])) {
                    $temperature = floatval($parameters['temperature']);

                    if ($temperature >= 0.0 && $temperature <= 2.0) {
                        $model_config['temperature'] = $temperature;
                    }
                }
                

                if (isset($parameters['top_p']) && is_numeric($parameters['top_p'])) {
                    $topP = floatval($parameters['top_p']);

                    if ($topP >= 0.0 && $topP <= 1.0) {
                        $model_config['top_p'] = $topP;
                    }
                }
                

                if (isset($parameters['frequency_penalty']) && is_numeric($parameters['frequency_penalty'])) {
                    $freqPenalty = floatval($parameters['frequency_penalty']);

                    if ($freqPenalty >= -2.0 && $freqPenalty <= 2.0) {
                        $model_config['frequency_penalty'] = $freqPenalty;
                    }
                }
                

                if (isset($parameters['presence_penalty']) && is_numeric($parameters['presence_penalty'])) {
                    $presPenalty = floatval($parameters['presence_penalty']);

                    if ($presPenalty >= -2.0 && $presPenalty <= 2.0) {
                        $model_config['presence_penalty'] = $presPenalty;
                    }
                }
            }
		} catch (\Exception $e) {

		}
	}
}
