<?php

namespace Limb_Chatbot\Includes\AI_Providers\Open_Router\Utilities;

use Limb_Chatbot\Includes\AI_Providers\Open_Router\Endpoints\Model_Endpoint;
use Limb_Chatbot\Includes\AI_Providers\Open_Router\Open_Router;
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 (list, retrieve) for OpenRouter integration.
 * Acts as a utility wrapper around Model_Endpoint with context-aware configuration.
 *
 * @package Limb_Chatbot\Includes\AI_Providers\Open_Router\Utilities
 * @since 1.0.14
 */
class AI_Model_Utility {

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

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

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

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

	/**
	 * HTTP request timeout in seconds.
	 *
	 * @var int|null
	 * @since 1.0.14
	 */
	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.14
	 */
	public function __construct( Global_Utility $global_utility ) {
		$this->global_utility = $global_utility;

		// Use config from global utility if available, otherwise load default
		if ( ! is_null( $this->global_utility->config ) ) {
			$this->config = $this->global_utility->config;
		} else {
			$this->config = Config::where( [ 'default' => true, 'related_to' => Open_Router::class ] )->first();
		}

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

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

	/**
	 * Retrieves detailed information about the current model.
	 *
	 * @return AI_Model Retrieved model details.
	 * @throws Exception If model is not defined.
	 * @since 1.0.14
	 */
	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 );
	}

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

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