<?php

namespace Limb_Chatbot\Includes\AI_Providers\Gemini\Endpoints\File\Handlers;

use Limb_Chatbot\Includes\AI_Providers\Gemini\Gemini;
use Limb_Chatbot\Includes\Data_Objects\File;
use Limb_Chatbot\Includes\Data_Objects\Meta_Data_Object;
use Limb_Chatbot\Includes\Data_Objects\Vector;
use Limb_Chatbot\Includes\AI_Providers\Gemini\Handlers\Response_Handler;
use Limb_Chatbot\Includes\Exceptions\Exception;

/**
 * Class File_Response_Handler
 *
 * Parses and handles the response from a Gemini File API request.
 *
 * @package Limb_Chatbot\Includes\AI_Providers\Gemini\Endpoints\File\Handlers
 * @since 1.0.0
 */
class File_Response_Handler extends Response_Handler {

	/**
	 * Maps file metadata keys to response body keys.
	 *
	 * @var array
	 */
	private static $file_metadata_mapper = array(
		'external_id'         => 'name',
		'external_created_at' => 'createTime',
		'external_expires_at' => 'expirationTime',
		'external_bytes'      => 'sizeBytes',
		'external_status'     => 'state',
	);

	/**
	 * The vector resulting from the embedding response.
	 *
	 * @var Vector|null
	 */
	protected ?Vector $vector = null;

	/**
	 * Parses the HTTP response and sets the vector result if no error occurred.
	 *
	 * @return void
	 * @throws Exception
	 * @since 1.0.0
	 */
	public function parse() {
		parent::parse();
	}

	/**
	 * Returns the file metadata as an array of Meta_Data_Object instances.
	 *
	 * @return Meta_Data_Object[]
	 * @since 1.0.0
	 */
	public function get_file_metadata() {
		$metadata = array(
			Meta_Data_Object::make( [
				'meta_key'   => 'external_provider',
				'meta_value' => Gemini::$id,
			] )
		);
		$body     = $this->get_body()->file ?? $this->get_body();
		foreach ( self::$file_metadata_mapper as $meta_key => $body_key ) {
			if ( isset( $body->{$body_key} ) ) {
				$meta = new Meta_Data_Object();
				$meta->set_meta_key( $meta_key );
				if ( $meta_key === 'external_status' ) {
					$value = $this->map_status( $body->{$body_key} );
				} else {
					$value = $body->{$body_key};
				}
				$meta->set_meta_value( $value );
				$metadata[] = $meta;
			}
		}

		return $metadata;
	}

	/**
	 * Maps Gemini file status to internal status constants.
	 *
	 * @param  string  $param  The status string from Gemini.
	 *
	 * @return int Mapped internal status constant.
	 * @since 1.0.0
	 */
	private function map_status( $param ) {
		switch ( $param ) {
			case 'ACTIVE':
				return File::EXTERNAL_STATUS_ACTIVE;
			case 'PROCESSING':
			case 'STATE_UNSPECIFIED':
				return File::EXTERNAL_STATUS_PROCESSING;
			//... handle other status mappings as needed ...
			default:
				return File::EXTERNAL_STATUS_FAILED;
		}
	}
}
