<?php

namespace Limb_Chatbot\Includes\AI_Providers\Open_Ai\Endpoints\Assistant\RequiredActions;

use Limb_Chatbot\Includes\AI_Providers\Open_Ai\Endpoints\Assistant\Tools\Function_Calling;
use Limb_Chatbot\Includes\AI_Providers\Open_AI\Endpoints\Thread_Message\Thread_Message;
use Limb_Chatbot\Includes\AI_Providers\Open_Ai\Factories\Assistant_Tool_Factory;
use Limb_Chatbot\Includes\AI_Providers\Open_Ai\Utilities\Thread_Utility;
use Limb_Chatbot\Includes\AI_Providers\OpenAI\Interfaces\Required_Actions_Interface;
use Limb_Chatbot\Includes\Exceptions\Exception;

/**
 * Class Submit_Tool_Outputs
 *
 * Handles submission of tool outputs required by the assistant thread.
 *
 * @package Limb_Chatbot\Includes\AI_Providers\Open_Ai\Endpoints\Assistant\RequiredActions
 * @since 1.0.0
 */
class Submit_Tool_Outputs implements Required_Actions_Interface {

	/**
	 * Utility for thread operations.
	 *
	 * @var Thread_Utility
	 * @since 1.0.0
	 */
	public Thread_Utility $thread_utility;

	/**
	 * The thread message instance.
	 *
	 * @var Thread_Message
	 * @since 1.0.0
	 */
	public Thread_Message $thread_message;

	/**
	 * Array of Function_Calling tool call instances processed during submission.
	 *
	 * @var Function_Calling[]
	 * @since 1.0.0
	 */
	public array $calls = [];

	/**
	 * Constructor.
	 *
	 * @param Thread_Utility $thread_utility Utility for managing thread-related functionality.
	 * @param Thread_Message $thread_message The thread message object.
	 *
	 * @since 1.0.0
	 */
	public function __construct( Thread_Utility $thread_utility, Thread_Message $thread_message ) {
		$this->thread_utility = $thread_utility;
		$this->thread_message = $thread_message;
	}

	/**
	 * Processes and submits the required tool outputs.
	 *
	 * Iterates over each tool call required by the thread message, executes them,
	 * collects the call instances, and submits the results.
	 *
	 * @return Thread_Message|null The result from thread utility's submit_tool_call method.
	 *
	 * @since 1.0.0
	 * @throws Exception
	 */
	public function submit() {
		$tool_calls = $this->thread_message->get_required_action()['submit_tool_outputs']['tool_calls'];
		foreach ( $tool_calls as $tool_call ) {
			$tool_call_instance = ( new Assistant_Tool_Factory() )->make( $this->thread_utility, $this->thread_message, $tool_call );
			$tool_call_instance->call();
			$this->calls[]      = $tool_call_instance;
		}
		return $this->thread_utility->submit_tool_call( $this->thread_message, $this );
	}
}