<?php

namespace Limb_Chatbot\Includes\AI_Providers\Grok\Utilities;

use Limb_Chatbot\Includes\AI_Providers\Grok\Grok;
use Limb_Chatbot\Includes\AI_Providers\Grok\Endpoints\Model\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
 *
 * Utility class for handling AI Model operations for the xAI provider.
 *
 * @package Limb_Chatbot\Includes\AI_Providers\Grok\Utilities
 * @since 1.0.12
 */
class AI_Model_Utility {

	/**
	 * Global AI model utility instance.
	 *
	 * @var Global_Utility
	 * @since 1.0.12
	 */
	public Global_Utility $global_utility;

	/**
	 * Model endpoint instance for API interactions.
	 *
	 * @var Model_Endpoint
	 * @since 1.0.12
	 */
	public Model_Endpoint $endpoint;

	/**
	 * The AI model instance.
	 *
	 * @var AI_Model|null
	 * @since 1.0.12
	 */
	public ?AI_Model $model;

	/**
	 * Config instance, nullable.
	 *
	 * @var Config|null
	 * @since 1.0.12
	 */
	public ?Config $config = null;

	/**
	 * Timeout in seconds for HTTP requests.
	 *
	 * @var int|null
	 * @since 1.0.12
	 */
	public ?int $timeout = 60;

	/**
	 * Constructor.
	 *
	 * @param  Global_Utility  $global_utility  Global utility instance.
	 *
	 * @since 1.0.12
	 */
	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' => Grok::class ) )->first();
		} else {
			$this->config = $this->global_utility->config;
		}

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

	/**
	 * List available AI models.
	 *
	 * @return array List of AI models.
	 * @throws Exception If API call fails.
	 * @since 1.0.12
	 */
	public function list() {
		return $this->endpoint->list();
	}

	/**
	 * Retrieve the AI model details.
	 *
	 * @return AI_Model The AI model.
	 *
	 * @throws Exception If model is missing.
	 * @since 1.0.12
	 */
	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' ) );
		}

		return $this->endpoint->retrieve( $this->model );
	}

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

	/**
	 * Get the config instance.
	 *
	 * @return Config|null
	 * @since 1.0.12
	 */
	public function get_config(): ?Config {
		return $this->config;
	}
}
