<?php

namespace Limb_Chatbot\Includes\Chatbot_Tools;

use Limb_Chatbot\Includes\Chatbot_Tools\Actions\Action_Chatbot_Tool;
use Limb_Chatbot\Includes\Chatbot_Tools\Tools\Knowledge_Search;
use Limb_Chatbot\Includes\Chatbot_Tools\Tools\Live_Agent_Connection;
use Limb_Chatbot\Includes\Traits\SingletonTrait;
use Limb_Chatbot\Includes\Utilities\Chatbot_Utility;

/**
 * Manages the registration and retrieval of chatbot tools.
 *
 * This class acts as a central registry for all available chatbot tools,
 * such as topic detection and knowledge generation. Implements the Singleton
 * pattern to ensure a single shared instance.
 *
 * @since 1.0.0
 */
class Chatbot_Tools {

	use SingletonTrait;

	/**
	 * Registered chatbot tools.
	 *
	 * Array structure: [ tool_name => Chatbot_Tool instance ]
	 *
	 * @var Chatbot_Tool[]
	 * @since 1.0.0
	 */
	private array $tools = [];

	/**
	 * Constructor.
	 *
	 * Registers default tools like Knowledge_Search.
	 *
	 * @since 1.0.0
	 */
	public function __construct( Chatbot_Utility $chatbot_utility ) {
		$this->register_tools( $chatbot_utility );
		$this->register_actions( $chatbot_utility );
		static::$instance = $this;
	}

	/**
	 * Register default chatbot tools.
	 *
	 * Registers tools based on the chatbot utility configuration,
	 * such as adding the Knowledge_Search tool if a knowledge base exists.
	 *
	 * @param  Chatbot_Utility  $chatbot_utility  Chatbot utility instance.
	 *
	 * @return void
	 * @since 1.0.0
	 */
	private function register_tools( Chatbot_Utility $chatbot_utility ) {
		if ( $chatbot_utility->get_knowledge_base() ) {
			$this->register_tool( new Knowledge_Search() );
		}

		// Register live agent connection tool if enabled
		if ( $chatbot_utility->live_agent && $chatbot_utility->live_agent_config_id ) {
			$this->register_tool( new Live_Agent_Connection() );
		}
	}

	/**
	 * Register a chatbot tool.
	 *
	 * Adds a new tool to the internal registry. If a tool with the same name
	 * exists, it will be overwritten.
	 *
	 * @param  Chatbot_Tool  $tool  Tool instance to register.
	 *
	 * @since 1.0.0
	 */
	public function register_tool( Chatbot_Tool $tool ): void {
		$this->tools[ $tool->get_name() ] = $tool;
	}

	/**
	 * Register chatbot action tools.
	 *
	 * Retrieves all actions from the chatbot utility and registers each
	 * as a Chatbot_Tool instance.
	 *
	 * @param  Chatbot_Utility  $chatbot_utility  Chatbot utility instance.
	 *
	 * @return void
	 * @since 1.0.0
	 */
	private function register_actions( Chatbot_Utility $chatbot_utility ) {
		if ( ( $actions = $chatbot_utility->get_actions() ) && ! $actions->is_empty() ) {
			foreach ( $actions->get() as $action ) {
				$this->tools[ $action->get_name() ] = new Action_Chatbot_Tool( $action );
			}
		}
	}

	/**
	 * Retrieve all registered chatbot tools.
	 *
	 * @return Chatbot_Tool[] Array of tool instances, keyed by tool name.
	 * @since 1.0.0
	 */
	public function get_tools(): array {
		return $this->tools;
	}

	/**
	 * Retrieve a specific chatbot tool by name.
	 *
	 * Returns the tool instance if it exists, or null if not found.
	 *
	 * @param  string  $name  Tool name to retrieve.
	 *
	 * @return Chatbot_Tool|null Tool instance or null.
	 * @since 1.0.0
	 */
	public function get_tool( string $name ): ?Chatbot_Tool {
		return $this->tools[ $name ] ?? null;
	}

	/**
	 * Unregister a chatbot tool by name.
	 *
	 * Removes a tool from the internal registry.
	 *
	 * @param  string  $name  Tool name to unregister.
	 *
	 * @return void
	 * @since 1.0.0
	 */
	public function unregister_tool( string $name ): void {
		unset( $this->tools[ $name ] );
	}
}
