<?php
/**
 * Yandex AI Provider Class
 *
 * Integration with YandexGPT (text) and YandexART (images) APIs.
 *
 * @package SmartyPress_AI_Engine
 * @since 1.1.0
 */

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

/**
 * Yandex Provider class
 */
class SmartyPress_AI_Yandex_Provider extends SmartyPress_AI_AI_Provider {

	/**
	 * Yandex Cloud folder ID
	 *
	 * @var string
	 */
	private $folder_id;

	/**
	 * Yandex client instance
	 *
	 * @var SmartyPress_AI_Yandex_Client
	 */
	private $client;

	/**
	 * Constructor
	 *
	 * @param string $api_key   Yandex Cloud service account API key.
	 * @param string $folder_id Yandex Cloud folder ID.
	 * @param string $model     Default model name.
	 */
	public function __construct( $api_key, $folder_id, $model = 'yandexgpt-lite' ) {
		parent::__construct( $api_key, $model );
		$this->folder_id = $folder_id;
		$this->client    = new SmartyPress_AI_Yandex_Client( $api_key, $folder_id );
	}

	/**
	 * Generate content using YandexGPT
	 *
	 * @param string $prompt The prompt to send to AI.
	 * @param array  $params Additional parameters.
	 * @return array Response with content or error.
	 */
	public function generate_content( $prompt, $params = array() ) {
		$system_prompt = $params['system_prompt']
			?? __( 'You are a helpful assistant for content generation.', 'smartypress-ai-engine' );

		$messages = array(
			array(
				'role' => 'system',
				'text' => $system_prompt,
			),
			array(
				'role' => 'user',
				'text' => $prompt,
			),
		);

		$model = ! empty( $params['model'] ) ? $params['model'] : $this->model;

		try {
			$result = $this->client->generate_from_messages(
				$messages,
				$model,
				array(
					'temperature' => $params['temperature'] ?? 0.7,
					'max_tokens'  => $params['max_tokens'] ?? 2000,
				)
			);
		} catch ( Exception $e ) {
			$error_code = '';

			// Detect authentication errors.
			if ( stripos( $e->getMessage(), 'IAM token' ) !== false
				|| stripos( $e->getMessage(), 'OAuth' ) !== false
				|| stripos( $e->getMessage(), 'unauthorized' ) !== false
			) {
				$error_code = 'api_key_invalid';
			}

			// Log the error.
			if ( class_exists( 'SmartyPress_AI_Logger' ) ) {
				$log_request = array(
					'model'    => $model,
					'messages' => array(
						array( 'role' => 'system', 'content' => $system_prompt ),
						array( 'role' => 'user', 'content' => $prompt ),
					),
				);
				SmartyPress_AI_Logger::log_api_error(
					$this->get_provider_name(),
					SmartyPress_AI_Yandex_Client::COMPLETION_ENDPOINT,
					$log_request,
					array(
						'code' => 0,
						'body' => $e->getMessage(),
					),
					$e->getMessage(),
					$error_code
				);
			}

			return array(
				'success'    => false,
				'error'      => $e->getMessage(),
				'error_code' => $error_code,
			);
		}

		if ( ! $result['success'] ) {
			$error_code = '';

			// Detect auth errors from HTTP response.
			$code = $result['code'] ?? 0;
			if ( in_array( $code, array( 401, 403 ), true ) ) {
				$error_code = 'api_key_invalid';

				// Kept for compatibility with auth managers that cache credentials.
				$this->client->get_auth_manager()->clear_cache();
			}

			// Log the error.
			if ( class_exists( 'SmartyPress_AI_Logger' ) ) {
				$log_request = array(
					'model'       => $model,
					'temperature' => $params['temperature'] ?? 0.7,
					'max_tokens'  => $params['max_tokens'] ?? 2000,
					'messages'    => array(
						array( 'role' => 'system', 'content' => $system_prompt ),
						array( 'role' => 'user', 'content' => $prompt ),
					),
				);
				SmartyPress_AI_Logger::log_api_error(
					$this->get_provider_name(),
					SmartyPress_AI_Yandex_Client::COMPLETION_ENDPOINT,
					$log_request,
					array(
						'code' => $code,
						'body' => $result['error'] ?? '',
					),
					$result['error'] ?? __( 'Unknown error', 'smartypress-ai-engine' ),
					$error_code
				);
			}

			return array(
				'success'    => false,
				'error'      => $result['error'] ?? __( 'Unknown Yandex API error', 'smartypress-ai-engine' ),
				'error_code' => $error_code,
			);
		}

		// Extract content from YandexGPT response format.
		$content = $result['data']['result']['alternatives'][0]['message']['text'] ?? '';
		$usage   = $result['data']['result']['usage'] ?? array();

		// Clean markdown code blocks that Yandex sometimes adds.
		$content = $this->clean_markdown_artifacts( $content );

		// Log successful request.
		if ( class_exists( 'SmartyPress_AI_Logger' ) ) {
			$log_request = array(
				'model'       => $model,
				'temperature' => $params['temperature'] ?? 0.7,
				'max_tokens'  => $params['max_tokens'] ?? 2000,
				'messages'    => array(
					array( 'role' => 'system', 'content' => $system_prompt ),
					array( 'role' => 'user', 'content' => $prompt ),
				),
			);
			SmartyPress_AI_Logger::log_api_success(
				$this->get_provider_name(),
				SmartyPress_AI_Yandex_Client::COMPLETION_ENDPOINT,
				$log_request,
				array(
					'code'    => 200,
					'content' => $content,
					'usage'   => $usage,
				)
			);
		}

		// Record token usage for statistics.
		if ( class_exists( 'SmartyPress_AI_Token_Tracker' ) ) {
			SmartyPress_AI_Token_Tracker::record( array(
				'provider' => $this->get_provider_name(),
				'model'    => $model,
				'usage'    => $usage,
			) );
		}

		return array(
			'success' => true,
			'content' => $content,
			'usage'   => $usage,
		);
	}

	/**
	 * Generate image using YandexART
	 *
	 * @param string $prompt Image generation prompt.
	 * @param array  $params Additional parameters (model, resolution).
	 * @return array Response with image data or error.
	 */
	public function generate_image( $prompt, $params = array() ) {
		try {
			$result = $this->client->generate_image( $prompt, $params );
		} catch ( Exception $e ) {
			return array(
				'success' => false,
				'error'   => $e->getMessage(),
			);
		}

		if ( ! $result['success'] ) {
			return $result;
		}

		return array(
			'success'  => true,
			'b64_json' => $result['b64_json'],
			'model'    => 'yandex-art',
			'usage'    => array(),
		);
	}

	/**
	 * Validate API key and folder ID.
	 *
	 * @return bool True if valid, false otherwise.
	 */
	public function validate_api_key() {
		try {
			$messages = array(
				array(
					'role' => 'user',
					'text' => __( 'Say "Hello"', 'smartypress-ai-engine' ),
				),
			);

			$result = $this->client->generate_from_messages(
				$messages,
				$this->model,
				array( 'max_tokens' => 10 )
			);

			return $result['success'] ?? false;
		} catch ( Exception $e ) {
			return false;
		}
	}

	/**
	 * Get available text models
	 *
	 * @return array List of available models with metadata.
	 */
	public function get_available_models() {
		return SmartyPress_AI_Yandex_Models::get_model_descriptions();
	}

	/**
	 * Get available image generation models
	 *
	 * @return array List of image models with resolutions.
	 */
	public function get_available_image_models() {
		return SmartyPress_AI_Yandex_Models::get_image_models();
	}

	/**
	 * Clean markdown artifacts from Yandex response
	 *
	 * YandexGPT sometimes wraps HTML content in markdown code blocks.
	 *
	 * @param string $content Raw content from API.
	 * @return string Cleaned content.
	 */
	private function clean_markdown_artifacts( $content ) {
		// Remove markdown code blocks (``` or ```html etc.) at start.
		$content = preg_replace( '/^```[a-z]*\s*/i', '', $content );
		// Remove markdown code blocks at end.
		$content = preg_replace( '/\s*```$/i', '', $content );

		// Also handle HTML-escaped versions (<br> before/after ```).
		$content = preg_replace( '/<br\s*\/?>\s*```\s*$/i', '', $content );
		$content = preg_replace( '/^```\s*<br\s*\/?>/i', '', $content );

		// Clean up any remaining standalone ``` at start/end.
		$content = preg_replace( '/^```\s*/i', '', $content );
		$content = preg_replace( '/\s*```$/i', '', $content );

		return trim( $content );
	}
}
