<?php
/**
 * AI Model Utility for DeepSeek AI Provider.
 *
 * Handles AI model-related operations (list, retrieve) for DeepSeek integration.
 * Acts as a utility wrapper around Model_Endpoint with context-aware configuration.
 *
 * @package Limb_Chatbot\Includes\AI_Providers\Deep_Seek\Utilities
 * @since  1.0.9
 */

namespace Limb_Chatbot\Includes\AI_Providers\Deep_Seek\Utilities;

use Limb_Chatbot\Includes\AI_Providers\Deep_Seek\Deep_Seek;
use Limb_Chatbot\Includes\AI_Providers\Deep_Seek\Endpoints\Model_Endpoint;
use Limb_Chatbot\Includes\Data_Objects\AI_Model;
use Limb_Chatbot\Includes\Data_Objects\Config;
use Limb_Chatbot\Includes\Exceptions\Error_Codes;
use Limb_Chatbot\Includes\Exceptions\Exception;
use Limb_Chatbot\Includes\Utilities\AI_Model_Utility as Global_Utility;

/**
 * Class AI_Model_Utility
 *
 * Handles AI model-related operations for DeepSeek integration.
 * DeepSeek API supports listing models via GET /models endpoint.
 *
 * @package Limb_Chatbot\Includes\AI_Providers\Deep_Seek\Utilities
 * @since  1.0.9
 */
class AI_Model_Utility {

	/**
	 * Global utility instance holding context (model, config, etc.)
	 *
	 * @var Global_Utility
	 * @since 1.0.0
	 */
	public Global_Utility $global_utility;

	/**
	 * API endpoint handler for AI model operations.
	 *
	 * @var Model_Endpoint
	 * @since 1.0.0
	 */
	public Model_Endpoint $endpoint;

	/**
	 * The current model associated with the utility context.
	 *
	 * @var AI_Model|null
	 * @since 1.0.0
	 */
	public ?AI_Model $model;

	/**
	 * DeepSeek API configuration object (e.g., API key, settings).
	 *
	 * @var Config|null
	 * @since 1.0.0
	 */
	public ?Config $config = null;

	/**
	 * HTTP request timeout in seconds.
	 *
	 * @var int|null
	 * @since 1.0.0
	 */
	public ?int $timeout = 60;

	/**
	 * AI_Model_Utility constructor.
	 *
	 * Initializes the utility with global context, loads the config if not set,
	 * and instantiates the related API endpoint.
	 *
	 * @param Global_Utility $global_utility Global utility object containing model and config.
	 *
	 * @since 1.0.0
	 */
	public function __construct( Global_Utility $global_utility ) {
		$this->global_utility = $global_utility;

		if ( is_null( $this->global_utility->config ) ) {
			$this->config = Config::where( array(
				'default'    => true,
				'related_to' => Deep_Seek::class,
			) )->first();
		} else {
			$this->config = $this->global_utility->config;
		}

		$this->endpoint = new Model_Endpoint( $this );
		$this->model    = $this->global_utility->model;
	}

	/**
	 * Deletes the current AI model.
	 *
	 * DeepSeek API does not support model deletion.
	 *
	 * @return bool Always throws exception - not supported.
	 * @throws Exception DeepSeek doesn't support model deletion.
	 * @since  1.0.0
	 */
	public function delete(): bool {
		throw new Exception(
			Error_Codes::NOT_SUPPORTED,
			__( 'DeepSeek API does not support model deletion', 'limb-chatbot' )
		);
	}

	/**
	 * Lists all available AI models via the DeepSeek API.
	 *
	 * @return array The list of available AI models.
	 * @throws Exception If the API request fails.
	 * @since  1.0.0
	 */
	public function list(): array {
		return $this->endpoint->list();
	}

	/**
	 * Retrieves the current AI model details.
	 *
	 * DeepSeek API does not support retrieving individual model details.
	 *
	 * @return AI_Model Always throws exception - not supported.
	 * @throws Exception DeepSeek doesn't support individual model retrieval.
	 * @since  1.0.0
	 */
	public function retrieve(): AI_Model {
		if ( is_null( $this->model ) ) {
			throw new Exception(
				Error_Codes::DATA_INVALID_AI_MODEL_ARGUMENT,
				__( 'Model is missing', 'limb-chatbot' )
			);
		}

		throw new Exception(
			Error_Codes::NOT_SUPPORTED,
			__( 'DeepSeek API does not support retrieving individual model details', 'limb-chatbot' )
		);
	}

	/**
	 * Gets the request timeout.
	 *
	 * @return int|null Timeout in seconds.
	 * @since  1.0.0
	 */
	public function get_timeout(): ?int {
		return $this->timeout;
	}

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

