<?php
/**
 * Tool Call.
 *
 * Represents a single tool call from an LLM with arguments and execution.
 *
 * @package   Agenistrator
 * @since     1.0.0
 * @author    Alex Ruban <alex@maximum.guru>
 * @author    Maximum Software Inc <contact@maximum.software>
 * @license   GPL-3.0-only
 * @link      https://maximum.software/
 *
 * SPDX-FileCopyrightText: 2025-2026 Alex Ruban <alex@maximum.guru>
 * SPDX-FileCopyrightText: 2025-2026 Maximum Software Inc <contact@maximum.software>
 * SPDX-License-Identifier: GPL-3.0-only
 */

namespace Agenistrator;

// Direct access prevention
if ( ! defined( 'ABSPATH' ) ) {
	return;
}

/**
 * Tool_Call class.
 */
class Tool_Call {
	/**
	 * The tool instance
	 * @var        Tool
	 */
	private $tool;

	/**
	 * Arguments for the tool call
	 * @var        array
	 */
	private $arguments;

	/**
	 * Result of executing the tool call
	 * @var        mixed
	 */
	private $result = null;

	/**
	 * Flag indicating if the tool has been executed
	 * @var        bool
	 */
	private $executed = false;

	/**
	 * Flag indicating if the tool execution was successful
	 * @var        bool
	 */
	private $success = false;

	/**
	 * Required ID for the tool call from LLM provider (for tracking tool call/result pairs)
	 * @var        string
	 */
	private $id;

	/**
	 * Constructor
	 *
	 * @param      Tool $tool The tool instance
	 * @param      array $arguments Arguments for the tool as an associative array
	 * @param      string $id Required ID for the tool call from LLM provider
	 * @throws     \InvalidArgumentException If ID is empty
	 * @since     1.0.0
	 */
	public function __construct( $tool, $arguments, $id ) {
		if ( empty( $id ) ) {
			throw new \InvalidArgumentException( 'Tool call ID is required and must come from LLM provider' );
		}

		$this->tool      = $tool;
		$this->arguments = $arguments;
		$this->id        = $id;
	}

	/**
	 * Get the tool instance
	 *
	 * @return     Tool The tool instance
	 * @since     1.0.0
	 */
	public function get_tool() {
		return $this->tool;
	}

	/**
	 * Get the tool ID
	 *
	 * @return     string The tool ID
	 * @since     1.0.0
	 */
	public function get_tool_id() {
		return $this->tool->get_id();
	}

	/**
	 * Get the arguments for the tool call
	 *
	 * @return     array The arguments as an associative array
	 * @since     1.0.0
	 */
	public function get_arguments() {
		return $this->arguments;
	}

	/**
	 * Get the call ID (unique identifier for this specific tool call from LLM)
	 *
	 * @return     string The call ID
	 * @since     1.0.0
	 */
	public function get_call_id() {
		return $this->id;
	}

	/**
	 * Set the call ID
	 *
	 * @param      string $id The call ID
	 * @return     Tool_Call This instance for method chaining
	 * @since     1.0.0
	 */
	public function set_call_id( $id ) {
		$this->id = $id;
		return $this;
	}

	/**
	 * Check if the tool has been executed
	 *
	 * @return     bool True if executed, false otherwise
	 * @since     1.0.0
	 */
	public function is_executed() {
		return $this->executed;
	}

	/**
	 * Check if the tool execution was successful
	 *
	 * @return     bool True if execution succeeded, false if it failed
	 * @since     1.0.0
	 */
	public function is_success() {
		return $this->success;
	}

	/**
	 * Get the result of executing the tool
	 *
	 * @return     mixed The result, or null if not executed
	 * @since     1.0.0
	 */
	public function get_result() {
		return $this->result;
	}

	/**
	 * Execute the tool with the provided arguments
	 *
	 * @return     mixed The result of executing the tool
	 * @throws     \Exception If execution fails or tool is disabled
	 * @since     1.0.0
	 */
	public function execute() {
		if ( $this->executed ) {
			return $this->result;
		}

		try {
			// Check if tool is enabled before execution
			if ( ! $this->tool->is_enabled() ) {
				throw new \Exception(
					String_Utils::replace_tags(
						\__( 'Tool "{tool_name}" is disabled. Please enable it in settings ({settings-url}) or use a different tool.', 'agenistrator' ),
						array(
							'tool_name'    => $this->tool->get_name(),
							'settings-url' => admin_url( 'admin.php?page=agenistrator-settings#tools' ),
						)
					)
				);
			}

			$this->result   = $this->tool->run( $this->arguments );
			$this->executed = true;

			// Check if the result indicates success (tools return structured responses)
			if ( is_array( $this->result ) && isset( $this->result['success'] ) ) {
				$this->success = $this->result['success'];
			} else {
				// If no success field, assume success if no exception was thrown
				$this->success = true;
			}

			return $this->result;
		} catch ( \Throwable $e ) {
			// Mark as executed even if it failed
			$this->executed = true;
			$this->success  = false;
			$this->result   = 'Error: ' . $e->getMessage();
			throw $e;
		}
	}
}
