<?php

namespace Limb_Chatbot\Includes\Services;

use Limb_Chatbot\Includes\Data_Objects\Config;
use WP_Http;


/**
 * Represents a generic API endpoint wrapper, handling configuration and utility binding.
 *
 * @since 1.0.0
 */
class Endpoint {

	/**
	 * The configuration instance associated with this endpoint.
	 *
	 * @since 1.0.0
	 * @var Config|null
	 */
	public ?Config $config = null;

	/**
	 * The utility object related to the endpoint (chatbot, file, embedding, etc.).
	 *
	 * @since 1.0.0
	 * @var mixed
	 */
	public $utility = null;

	/**
	 * A short label describing the endpoint.
	 *
	 * @since 1.0.0
	 * @var string|null
	 */
	public ?string $label = '';

	/**
	 * A longer description of the endpoint.
	 *
	 * @since 1.0.0
	 * @var string|null
	 */
	public ?string $description = '';

	/**
	 * Returns the endpoint label.
	 *
	 * @since 1.0.0
	 *
	 * @return string|null
	 */
	public function get_label() {
		return $this->label;
	}

	/**
	 * Returns the endpoint description.
	 *
	 * @since 1.0.0
	 *
	 * @return string|null
	 */
	public function get_description() {
		return $this->description;
	}

	/**
	 * Constructor.
	 *
	 * @since 1.0.0
	 *
	 * @param mixed $utility The utility instance to bind to this endpoint.
	 */
	public function __construct( $utility ) {
		$this->set_utility( $utility );
		$this->define_config();
	}

	/**
	 * Defines and sets the endpoint configuration based on available utility methods.
	 *
	 * @since 1.0.0
	 *
	 * @return void
	 */
	public function define_config(): void {
		if ( property_exists( $this->utility, 'global_utility' ) && method_exists( $this->utility->global_utility, 'get_config' ) ) {
			// For some utilities we must base on global utility config. Ex: Chatbot
			$config = $this->utility->global_utility->get_config();
		} elseif ( method_exists( $this->utility, 'get_config' ) ) {
			// For some utilities we must base on child utility config. Ex: Embedding, Fine-tuning, File, etc ...
			$config = $this->utility->get_config();
		}
		if ( isset( $config ) && $config instanceof Config ) {
			$this->set_config( $config );
		}
	}

	/**
	 * Sets the endpoint configuration.
	 *
	 * @since 1.0.0
	 *
	 * @param Config|null $config The configuration object.
	 * @return void
	 */
	public function set_config( ?Config $config ): void {
		$this->config = $config;
	}

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

	/**
	 * Returns the utility instance used by this endpoint.
	 *
	 * @since 1.0.0
	 *
	 * @return mixed
	 */
	public function get_utility() {
		return $this->utility;
	}

	/**
	 * Sets the utility instance.
	 *
	 * @since 1.0.0
	 *
	 * @param mixed $utility The utility object.
	 * @return void
	 */
	public function set_utility( $utility ) {
		$this->utility = $utility;
	}

	/**
	 * Returns an HTTP client instance.
	 * Can be a streaming client or a standard HTTP client.
	 *
	 * @since 1.0.0
	 *
	 * @param bool $is_stream Whether to return a streaming client.
	 * @return WP_Http|Event_Stream_Curl
	 */
	public function http_client_factory( $is_stream = false ) {
		return ! empty( $is_stream ) ? new Event_Stream_Curl() : new WP_Http();
	}
}