<?php

namespace Limb_Chatbot\Includes\AI_Providers\Gemini\Utilities;

use Limb_Chatbot\Includes\AI_Providers\Gemini\Gemini;
use Limb_Chatbot\Includes\Data_Objects\Config;
use Limb_Chatbot\Includes\AI_Providers\Gemini\Endpoints\File\File_Endpoint;
use Limb_Chatbot\Includes\Data_Objects\File;
use Limb_Chatbot\Includes\Exceptions\Exception;
use Limb_Chatbot\Includes\Utilities\File_Utility as Global_Utility;

/**
 * Utility class for managing file operations with the Gemini provider.
 *
 * @package Limb_Chatbot\Includes\AI_Providers\Gemini\Utilities
 * @since 1.0.0
 */
class File_Utility {
	const DEFAULT_TIMEOUT = 60;

	/**
	 * Configuration object related to this utility.
	 *
	 * May be null if no configuration is set or found.
	 *
	 * @since 1.0.0
	 * @var Config|null
	 */
	public ?Config $config;

	/**
	 * Global file utility instance used for shared operations.
	 *
	 * @since 1.0.0
	 * @var Global_Utility
	 */
	public Global_Utility $global_utility;

	/**
	 * Endpoint instance to handle file API interactions.
	 *
	 * @since 1.0.0
	 * @var File_Endpoint
	 */
	public File_Endpoint $endpoint;

	/**
	 * Constructor.
	 *
	 * Initializes the file utility with the global utility, sets config if missing,
	 * and creates the file endpoint instance.
	 *
	 * @since 1.0.0
	 *
	 * @param Global_Utility $global_utility Global file utility instance.
	 */
	public function __construct( Global_Utility $global_utility ) {
		$this->global_utility = $global_utility;
		if ( is_null( $this->global_utility->config ) ) {
			$this->config = Config::where( [ 'default' => true, 'related_to' => Gemini::class ] )->first();
		}
		$this->endpoint = new File_Endpoint( $this );
	}

	/**
	 * Returns the configuration object used by this utility.
	 *
	 * @since 1.0.0
	 *
	 * @return Config|null Configuration object or null if not set.
	 */
	public function get_config(): ?Config {
		return $this->config;
	}

	/**
	 * Retrieves a file via the file endpoint.
	 *
	 * Delegates the retrieval process to the File_Endpoint instance.
	 *
	 * @return string Result of the file retrieval operation.
	 * @throws Exception
	 * @since 1.0.0
	 *
	 */
	public function retrieve() {
		return $this->endpoint->retrieve();
	}

	/**
	 * Uploads a file via the file endpoint.
	 *
	 * Delegates the upload process to the File_Endpoint instance.
	 *
	 * @param File $file The File object to upload.
	 * @return array Array of Meta_Data_Object instances with file metadata.
	 * @throws Exception
	 * @since 1.0.0
	 */
	public function upload( File $file ) {
		return $this->endpoint->upload( $file );
	}

	public function refresh( File $file ) {
		return $this->endpoint->refresh( $file );
	}

	public function get_timeout(){
		return self::DEFAULT_TIMEOUT;
	}
}
