<?php
/**
 * OpenAI provider.
 *
 * @package Ugcify\AI
 */

namespace Ugcify\AI;

use WP_Error;

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

class OpenAIProvider extends AbstractAIProvider {
	private const API_URL = 'https://api.openai.com/v1/responses';

	/**
	 * Provider slug.
	 *
	 * @var string
	 */
	protected $provider = 'openai';

	/**
	 * Analyze hotspot suggestions.
	 *
	 * @param array<string,mixed>             $image_source Image source block info.
	 * @param array<int,array<string,mixed>>  $candidates Candidate products.
	 * @param array<string,mixed>             $context Review context.
	 * @return array<string,mixed>|WP_Error
	 */
	public function analyze_hotspots( array $image_source, array $candidates, array $context = array() ) {
		$api_key = $this->get_api_key();
		if ( '' === $api_key ) {
			return new WP_Error( 'missing_api_key', __( 'OpenAI API key is missing.', 'ugcify' ) );
		}

		$image_payload = $this->get_image_payload( $image_source );
		if ( is_wp_error( $image_payload ) ) {
			return $image_payload;
		}

		$image_url = ! empty( $image_payload['data'] )
			? 'data:' . (string) $image_payload['media_type'] . ';base64,' . (string) $image_payload['data']
			: (string) $image_payload['url'];

		$response = wp_remote_post(
			self::API_URL,
			array(
				'timeout' => 60,
				'headers' => array(
					'content-type'  => 'application/json',
					'authorization' => 'Bearer ' . $api_key,
				),
				'body'    => wp_json_encode(
					array(
						'model' => $this->get_model(),
						'input' => array(
							array(
								'role'    => 'user',
								'content' => array(
									array(
										'type' => 'input_text',
										'text' => $this->build_instruction_text( $candidates, $context, (int) $this->settings['max_suggestions'] ),
									),
									array(
										'type'      => 'input_image',
										'image_url' => $image_url,
									),
								),
							),
						),
					)
				),
			)
		);

		if ( is_wp_error( $response ) ) {
			return new WP_Error( 'provider_request_failed', $response->get_error_message() );
		}

		$status = (int) wp_remote_retrieve_response_code( $response );
		if ( $status < 200 || $status >= 300 ) {
			return new WP_Error( 'provider_http_error', __( 'OpenAI request failed.', 'ugcify' ) );
		}

		$decoded = json_decode( (string) wp_remote_retrieve_body( $response ), true );
		if ( ! is_array( $decoded ) ) {
			return new WP_Error( 'invalid_provider_response', __( 'Invalid OpenAI response.', 'ugcify' ) );
		}

		$text = isset( $decoded['output_text'] ) ? (string) $decoded['output_text'] : $this->collect_text( $decoded );
		$json = $this->extract_json_object( $text );
		if ( ! is_array( $json ) ) {
			return new WP_Error( 'invalid_provider_json', __( 'OpenAI did not return valid JSON.', 'ugcify' ) );
		}

		return $json;
	}

	/**
	 * Collect response text recursively.
	 *
	 * @param mixed $value Response value.
	 * @return string
	 */
	private function collect_text( $value ): string {
		if ( is_array( $value ) ) {
			$text = '';
			foreach ( $value as $key => $item ) {
				if ( ( 'text' === $key || 'output_text' === $key ) && is_string( $item ) ) {
					$text .= $item;
					continue;
				}
				$text .= $this->collect_text( $item );
			}
			return $text;
		}

		return '';
	}
}
