<?php

namespace Limb_Chatbot\Includes\AI_Providers\Gemini\Endpoints;

use Limb_Chatbot\Includes\Data_Objects\AI_Model;
use Limb_Chatbot\Includes\Data_Objects\Vector;
use Limb_Chatbot\Includes\AI_Providers\Gemini\Endpoints\Embed_Content\Handlers\Embed_Content_Response_Handler;
use Limb_Chatbot\Includes\Exceptions\Exception;

/**
 * Class Embed_Content_Endpoint
 *
 * Handles the embedding of content via the Gemini API.
 *
 * @since 1.0.0
 */
class Embed_Content_Endpoint extends Gemini_Endpoint {

	/**
	 * Constructor.
	 *
	 * @param  mixed  $utility  Utility instance.
	 *
	 * @since 1.0.0
	 */
	public function __construct( $utility ) {
		parent::__construct( $utility );
	}

	/**
	 * Generates an embedding vector for the given content vector.
	 *
	 * @param  Vector  $vector  The vector data object.
	 *
	 * @return Vector The updated vector with embedding data.
	 * @throws Exception
	 * @since 1.0.0
	 */
	public function generate( Vector $vector ) {
		$model       = $vector->get_ai_model();
		$http_client = $this->http_client_factory();
		$response    = $http_client->post( $this->generate_endpoint( $model, $vector ), [
			'body'    => wp_json_encode( array(
				'model'                => 'model/' . $model->get_name(),
				'content'              => $this->prepare_content( $vector ),
				'outputDimensionality' => $vector->get_dimension()
			) ),
			'headers' => $this->get_header(),
			'timeout' => $this->utility->get_timeout(),
		] );

		return ( new Embed_Content_Response_Handler( $response, $http_client, $vector->get_dimension(), $this ) )->get_vector();
	}

	/**
	 * Generates the API endpoint URL for the model embedding request.
	 *
	 * @param  ?AI_Model  $model  The AI model.
	 * @param  Vector  $vector  The Vector.
	 *
	 * @return string The full API endpoint URL.
	 * @throws Exception
	 * @since 1.0.0
	 */
	protected function generate_endpoint( ?AI_Model $model, Vector $vector ) {
		return self::API_BASE_URL . $this->utility->get_version() . '/models/' . $model->get_name() . ':embedContent?key=' . $this->get_auth_key( $vector->get_config() );
	}

	/**
	 * Prepares the content payload for embedding.
	 *
	 * @param  Vector  $vector  The vector containing input content.
	 *
	 * @return array The prepared content array.
	 * @since 1.0.0
	 */
	protected function prepare_content( Vector $vector ) {
		$content['parts'][] = [ 'text' => $vector->get_input() ];

		return $content;
	}
}