<?php
namespace TeknoTok\AiTranslator\Providers;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use TeknoTok\AiTranslator\Utils\Crypto;
use TeknoTok\AiTranslator\Utils\Logger;

/**
 * OpenAI Direct Translation Provider.
 * Connects directly to api.openai.com using the decrypted API Key.
 */
class OpenAIProvider implements ProviderInterface {

	/**
	 * Translate text strings or arrays.
	 *
	 * @param string|array $text        String or array to translate.
	 * @param string       $source_lang Source locale.
	 * @param string       $target_lang Target locale.
	 * @return string|array Translated output.
	 * @throws \Exception
	 */
	public function translate( $text, $source_lang, $target_lang ) {
		$settings = get_option( 'teknotok_ait_settings', array() );
		$model    = $settings['openai_model'] ?? 'gpt-4o-mini';
		$enc_key  = $settings['openai_key'] ?? '';

		if ( empty( $enc_key ) ) {
			throw new \Exception( __( 'OpenAI API Key is not configured.', 'teknotok-ai-translator' ) );
		}

		$api_key = Crypto::decrypt( $enc_key );
		if ( empty( $api_key ) ) {
			throw new \Exception( __( 'Failed to decrypt OpenAI API Key.', 'teknotok-ai-translator' ) );
		}

		$is_array = is_array( $text );

		if ( $is_array ) {
			$system_prompt = sprintf(
				"You are a professional web translator. Translate the input JSON values from %s to %s. Preserve HTML markup tags, class names, variables, shortcodes, and placeholders exactly as they are. Output only valid JSON matching the exact keys of the input.",
				$source_lang,
				$target_lang
			);
			$user_content = wp_json_encode( $text );
			$response_format = array( 'type' => 'json_object' );
		} else {
			$system_prompt = sprintf(
				"You are a professional web translator. Translate the user input from %s to %s. Preserve HTML markup tags, class names, variables, shortcodes, and placeholders exactly as they are. Output ONLY the translated text, do not add any comments or markdown formatting.",
				$source_lang,
				$target_lang
			);
			$user_content = $text;
			$response_format = null;
		}

		$messages = array(
			array(
				'role'    => 'system',
				'content' => $system_prompt,
			),
			array(
				'role'    => 'user',
				'content' => $user_content,
			),
		);

		$payload = array(
			'model'       => $model,
			'messages'    => $messages,
			'temperature' => 0.3,
		);

		if ( $response_format ) {
			$payload['response_format'] = $response_format;
		}

		$item_count = $is_array ? count( $text ) : 1;
		$char_count = $is_array ? strlen( wp_json_encode( $text ) ) : strlen( $text );
		Logger::log( sprintf( '[OpenAI API] Dispatching request (model="%s", items=%d, chars=%d, source="%s", target="%s")', $model, $item_count, $char_count, $source_lang, $target_lang ), 'info' );
		
		$start_time = microtime( true );

		$response = wp_remote_post(
			'https://api.openai.com/v1/chat/completions',
			array(
				'headers' => array(
					'Authorization' => 'Bearer ' . $api_key,
					'Content-Type'  => 'application/json',
				),
				'body'    => wp_json_encode( $payload ),
				'timeout' => 120,
			)
		);

		$elapsed = round( microtime( true ) - $start_time, 2 );

		if ( is_wp_error( $response ) ) {
			Logger::log( sprintf( '[OpenAI API Error] Request failed after %s seconds: %s', $elapsed, $response->get_error_message() ), 'error' );
			throw new \Exception( $response->get_error_message() );
		}

		$code = wp_remote_retrieve_response_code( $response );
		$body = wp_remote_retrieve_body( $response );

		if ( 200 !== $code ) {
			$error_data = json_decode( $body, true );
			$msg = $error_data['error']['message'] ?? sprintf( __( 'OpenAI API request failed with code %d', 'teknotok-ai-translator' ), $code );
			Logger::log( sprintf( '[OpenAI API Error] Response code %d received after %s seconds. Details: %s', $code, $elapsed, $body ), 'error' );
			throw new \Exception( $msg, $code );
		}

		$data = json_decode( $body, true );
		$translated = $data['choices'][0]['message']['content'] ?? '';

		if ( empty( $translated ) ) {
			Logger::log( sprintf( '[OpenAI API Error] Received empty translation content choices from OpenAI after %s seconds.', $elapsed ), 'error' );
			throw new \Exception( __( 'Received empty response from OpenAI.', 'teknotok-ai-translator' ) );
		}

		Logger::log( sprintf( '[OpenAI API Success] Received successful response in %s seconds. (HTTP %d, chars=%d)', $elapsed, $code, strlen( $translated ) ), 'info' );

		if ( $is_array ) {
			$decoded = json_decode( $translated, true );
			if ( ! is_array( $decoded ) ) {
				Logger::log( '[OpenAI API Error] Failed to decode translation JSON from OpenAI: ' . $translated, 'error' );
				throw new \Exception( __( 'OpenAI did not return a valid translation mapping.', 'teknotok-ai-translator' ) );
			}
			return $decoded;
		}

		return trim( $translated );
	}

	/**
	 * Test provider configurations and credentials.
	 *
	 * @return bool True if configurations validate, false otherwise.
	 */
	public function validate_key() {
		try {
			$this->translate( 'Test', 'en', 'es' );
			return true;
		} catch ( \Exception $e ) {
			return false;
		}
	}

	/**
	 * Check if provider is configured.
	 *
	 * @return bool True if configured, false otherwise.
	 */
	public function is_configured() {
		$settings = get_option( 'teknotok_ait_settings', array() );
		return ! empty( $settings['openai_key'] );
	}
}
