<?php
/**
 * Optional text rewrite pass for generated alt text.
 *
 * @package AIAltTextGenerator
 * @since 2.4.1
 */

namespace AIAltTextGenerator;

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

/**
 * Applies a post-generation rewrite prompt containing {{AltText}}.
 *
 * Failures never abort generation — the original alt text is returned.
 *
 * @since 2.4.1
 */
class AltRewriter {

	/**
	 * @return string Always returns usable alt text (original on rewrite failure).
	 */
	public static function apply( string $alt_text, ?array $settings = null ): string {
		$settings = $settings ?? Settings::get();
		$prompt   = trim( (string) ( $settings['rewrite_prompt'] ?? '' ) );

		if ( $alt_text === '' || $prompt === '' || strpos( $prompt, '{{AltText}}' ) === false ) {
			return $alt_text;
		}

		$provider = Settings::sanitizeProvider( (string) ( $settings['provider'] ?? 'openai' ) );
		$api_key  = Settings::getApiKey( $settings, $provider );
		if ( $api_key === '' ) {
			return $alt_text;
		}

		$user_prompt = str_replace( '{{AltText}}', $alt_text, $prompt );
		$timeout     = Text::safeHttpTimeout( (int) ( $settings['request_timeout'] ?? 90 ) );
		$model       = Settings::resolveModelForProvider( $settings );

		$result = match ( $provider ) {
			'gemini' => self::requestGemini( $api_key, $model, $user_prompt, $timeout ),
			'claude' => self::requestClaude( $api_key, $model, $user_prompt, $timeout ),
			default  => self::requestOpenAi( $api_key, $model, $user_prompt, $timeout ),
		};

		if ( is_wp_error( $result ) ) {
			Diagnostics::debug(
				'rewrite_skipped',
				[
					'provider' => $provider,
					'model'    => $model,
					'message'  => $result->get_error_message(),
					'code'     => $result->get_error_code(),
				]
			);

			return $alt_text;
		}

		$rewritten = trim( (string) $result );

		return $rewritten !== '' ? $rewritten : $alt_text;
	}

	private static function requestOpenAi( string $api_key, string $model, string $user_prompt, int $timeout ): string|\WP_Error {
		$body = Models::withTokenLimit(
			[
				'model'    => $model,
				'messages' => [
					[
						'role'    => 'system',
						'content' => 'You rewrite image alt text. Return only the rewritten alt text with no quotes or commentary.',
					],
					[
						'role'    => 'user',
						'content' => $user_prompt,
					],
				],
			],
			200
		);

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

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

		$code = (int) wp_remote_retrieve_response_code( $response );
		$data = json_decode( (string) wp_remote_retrieve_body( $response ), true );
		if ( $code < 200 || $code >= 300 || ! is_array( $data ) ) {
			$message = is_array( $data ) ? (string) ( $data['error']['message'] ?? '' ) : '';

			return new \WP_Error( 'rewrite_failed', $message !== '' ? $message : __( 'Alt text rewrite request failed.', 'wp-powersuite' ), [ 'status' => $code ] );
		}

		return trim( (string) ( $data['choices'][0]['message']['content'] ?? '' ) );
	}

	private static function requestGemini( string $api_key, string $model, string $user_prompt, int $timeout ): string|\WP_Error {
		$url = sprintf(
			'https://generativelanguage.googleapis.com/v1beta/models/%s:generateContent',
			rawurlencode( $model )
		);

		$response = wp_remote_post(
			$url,
			[
				'timeout' => $timeout,
				'headers' => [
					'Content-Type'   => 'application/json',
					'x-goog-api-key' => $api_key,
				],
				'body'    => wp_json_encode(
					[
						'contents' => [
							[
								'parts' => [
									[
										'text' => 'Rewrite image alt text. Return only the rewritten alt text with no quotes or commentary.' . "\n\n" . $user_prompt,
									],
								],
							],
						],
					]
				),
			]
		);

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

		$code = (int) wp_remote_retrieve_response_code( $response );
		$data = json_decode( (string) wp_remote_retrieve_body( $response ), true );
		if ( $code < 200 || $code >= 300 || ! is_array( $data ) ) {
			$message = is_array( $data ) ? (string) ( $data['error']['message'] ?? '' ) : '';

			return new \WP_Error( 'rewrite_failed', $message !== '' ? $message : __( 'Alt text rewrite request failed.', 'wp-powersuite' ), [ 'status' => $code ] );
		}

		return trim( (string) ( $data['candidates'][0]['content']['parts'][0]['text'] ?? '' ) );
	}

	private static function requestClaude( string $api_key, string $model, string $user_prompt, int $timeout ): string|\WP_Error {
		$response = wp_remote_post(
			'https://api.anthropic.com/v1/messages',
			[
				'timeout' => $timeout,
				'headers' => [
					'x-api-key'         => $api_key,
					'anthropic-version' => '2023-06-01',
					'content-type'      => 'application/json',
				],
				'body'    => wp_json_encode(
					[
						'model'      => $model,
						'max_tokens' => 200,
						'messages'   => [
							[
								'role'    => 'user',
								'content' => 'Rewrite image alt text. Return only the rewritten alt text with no quotes or commentary.' . "\n\n" . $user_prompt,
							],
						],
					]
				),
			]
		);

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

		$code = (int) wp_remote_retrieve_response_code( $response );
		$data = json_decode( (string) wp_remote_retrieve_body( $response ), true );
		if ( $code < 200 || $code >= 300 || ! is_array( $data ) ) {
			$message = is_array( $data ) ? (string) ( $data['error']['message'] ?? '' ) : '';

			return new \WP_Error( 'rewrite_failed', $message !== '' ? $message : __( 'Alt text rewrite request failed.', 'wp-powersuite' ), [ 'status' => $code ] );
		}

		$content = '';
		foreach ( (array) ( $data['content'] ?? [] ) as $part ) {
			if ( is_array( $part ) && ( $part['type'] ?? '' ) === 'text' ) {
				$content .= (string) ( $part['text'] ?? '' );
			}
		}

		return trim( $content );
	}
}
