<?php
/**
 * SummPress OpenAI AI Service
 *
 * Handles article summarization using OpenAI API.
 *
 * @package SummPress
 * @since 1.1.0
 */

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

/**
 * OpenAI AI Service Class
 *
 * Implements the SummPress_AI_Service interface for OpenAI API.
 *
 * @since 1.1.0
 */
class SummPress_OpenAI_AI implements SummPress_AI_Service {

	protected $summpress;

	/**
	 * Constructor.
	 *
	 * @since 1.0.0
	 */
	public function __construct( SummPress $summpress ) {
		$this->summpress = $summpress;
	}

	/**
	 * Generate a summary using OpenAI API.
	 *
	 * @since 1.1.0
	 * @param string $title Article title.
	 * @param string $content Article content.
	 * @return array|WP_Error Summary data or error.
	 */
	public function generate_summary( $title, $content ){
		$api_key =  $this->summpress->get_option( 'openai_api_key', '' );
		$model =  $this->summpress->get_option( 'openai_model', 'gpt-4' );

		if ( empty( $api_key ) ) {
			return new WP_Error(
				'missing_api_key',
				__( 'OpenAI API key is not configured in settings', 'summpressai' )
			);
		}

		$endpoint = 'https://api.openai.com/v1/chat/completions';
		$prompt = $this->get_summary_prompt( $title, $content );

		$request_body = wp_json_encode(
			[
				'model'    => $model,
				'messages' => [
					[
						'role'    => 'user',
						'content' => $prompt,
					],
				],
				'max_tokens' => 1000,
				'temperature' => 0.7,
			]
		);

		$response = wp_remote_post(
			$endpoint,
			[
				'headers' => [
					'Content-Type'  => 'application/json',
					'Authorization' => 'Bearer ' . $api_key,
				],
				'body'    => $request_body,
				'timeout' => 60,
			]
		);

		if ( is_wp_error( $response ) ) {
			return new WP_Error(
				'api_request_failed',
				sprintf(
				/* translators: %s: Error message */
					__( 'OpenAI API request failed: %s', 'summpressai' ),
					$response->get_error_message()
				)
			);
		}

		$body_json = wp_remote_retrieve_body( $response );
		$body = json_decode( $body_json, true );

		if ( isset( $body['error']['code'] ) && isset( $body['error']['message'] ) ) {
			return new WP_Error(
				'api_error_' . $body['error']['code'],
				sprintf(
				/* translators: %s: Error message */
					__( 'OpenAI API error: %s', 'summpressai' ),
					esc_html( $body['error']['message'] )
				)
			);
		}

		if ( empty( $body['choices'][0]['message']['content'] ) ) {
			return new WP_Error(
				'invalid_api_response',
				__( 'Received invalid response from the OpenAI API', 'summpressai' )
			);
		}

		$text = $body['choices'][0]['message']['content'];
		$summary = $this->parse_summary_response( $text );


		if ( empty( $summary['title'] ) || empty( $summary['text'] ) ) {
			return new WP_Error(
				'parsing_failed',
				__( 'Failed to parse the summary from the OpenAI API response', 'summpressai' )
			);
		}

		return $summary;
	}

	/**
	 * Get the prompt for generating a summary.
	 *
	 * @since 1.1.0
	 * @param string $title Article title.
	 * @param string $content Article content.
	 * @return string
	 */
	protected function get_summary_prompt( $title, $content ) {
		$lang = $this->summpress->get_option( 'summary_language', 'original' );

		$prompt = sprintf(
			"Here is the title and full text of a news article.\n\nTITLE: %s\n\nTEXT: %s\n\n",
			$title,
			$content
		);

		$prompt .= "Please create a detailed summary in the following format:\n\n";
		$prompt .= "TITLE: [A concise, clear, and relevant summary headline]\n";
		$prompt .= "TEXT: [A detailed summary of the article, preserving all key facts, names, locations, events, and numbers. ";
		$prompt .= "Keep the summary well-structured, readable, and journalistic in tone.]\n\n";

		if ( 'original' !== $lang ) {
			$prompt .= sprintf( "Please write the summary text and title in %s.\n\n", $lang );
		} else {
			$prompt .= "Detect the language of the original input text above.\n";
			$prompt .= "Then return the 'TITLE' and 'TEXT' in the same detected language.\n";
			$prompt .= "Do not translate. Keep the original language.\n\n";
		}

		$prompt .= "Very important: Format the summary with proper paragraph structure.\n";
		$prompt .= "Decide where paragraphs should logically break, based on meaning, context, and flow.\n";
		$prompt .= "Use double HTML line breaks `<br><br>` between paragraphs.\n";
		$prompt .= "Example:\nThis is paragraph one.<br><br>This is paragraph two.<br><br>This is paragraph three.\n";
		$prompt .= "Do not use \\n for line breaks. Only use <br><br> between paragraphs in the final output.\n\n";


		$prompt .= "Only return the result in this format:\nTITLE: ...\nTEXT: ...";

		/**
		 * Filter the summary prompt.
		 *
		 * @since 1.1.0
		 * @param string $prompt The prompt text.
		 * @param string $title Article title.
		 * @param string $content Article content.
		 */
		return apply_filters( 'summpress_summary_prompt', $prompt, $title, $content );
	}

	/**
	 * Parse the summary response from the API.
	 *
	 * @since 1.1.0
	 * @param string $text API response text.
	 * @return array|false
	 */
	protected function parse_summary_response( $text ) {
		if ( empty( $text ) ) {
			return false;
		}

		if ( preg_match( '/TITLE:\s*(.+?)\n+TEXT:\s*(.+)/s', $text, $matches ) ) {
			return [
				'title' => trim( $matches[1] ),
				'text'  => trim( $matches[2] ),
			];
		}

		return false;
	}
}
