<?php

namespace Limb_Chatbot\Includes\AI_Providers\Claude\Endpoints\Chat_Completion;

use Limb_Chatbot\Includes\Data_Objects\Tool_Calls_Message as Parent_Tool_Calls_Message;

/**
 * Class Tool_Calls_Message
 *
 * Represents a message that contains tool call instructions from Claude,
 * extending the base Tool_Calls_Message structure.
 *
 * Claude returns tool calls as content blocks with type "tool_use".
 *
 * @package Limb_Chatbot\Includes\AI_Providers\Claude\Endpoints\Chat_Completion
 * @since 1.0.9
 */
class Tool_Calls_Message extends Parent_Tool_Calls_Message {

	/**
	 * Array of tool use content blocks received from the Claude response.
	 *
	 * @var array|null
	 * @since 1.0.9
	 */
	public ?array $tool_uses = null;

	/**
	 * Raw content blocks from Claude response.
	 *
	 * @var array|null
	 * @since 1.0.9
	 */
	public ?array $content_blocks = null;

	/**
	 * Get the tool calls array in a normalized format.
	 *
	 * Returns tool calls in OpenAI-compatible format for use with Chatbot_Tools.
	 *
	 * @return array Array of tool call objects.
	 * @since 1.0.9
	 */
	public function get_tool_calls(): array {
		if ( empty( $this->tool_uses ) ) {
			return array();
		}

		$tool_calls = array();
		foreach ( $this->tool_uses as $tool_use ) {
			$tool_calls[] = (object) array(
				'id'       => $tool_use['id'],
				'type'     => 'function',
				'function' => (object) array(
					'name'      => $tool_use['name'],
					'arguments' => wp_json_encode( $tool_use['input'] ),
				),
			);
		}

		return $tool_calls;
	}

	/**
	 * Set the tool uses array from Claude response.
	 *
	 * @param  array|null  $tool_uses  Tool use blocks from Claude response.
	 *
	 * @return void
	 * @since 1.0.9
	 */
	public function set_tool_uses( ?array $tool_uses ): void {
		$this->tool_uses = $tool_uses;
	}

	/**
	 * Get the content blocks for API request.
	 *
	 * Returns the content in Claude's format for subsequent requests.
	 *
	 * @return array Array of content blocks.
	 * @since 1.0.9
	 */
	public function get_content_blocks(): array {
		if ( ! empty( $this->content_blocks ) ) {
			return $this->content_blocks;
		}

		if ( empty( $this->tool_uses ) ) {
			return array();
		}

		$blocks = array();
		foreach ( $this->tool_uses as $tool_use ) {
			$blocks[] = array(
				'type'  => 'tool_use',
				'id'    => $tool_use['id'],
				'name'  => $tool_use['name'],
				'input' => $tool_use['input'],
			);
		}

		return $blocks;
	}

	/**
	 * Set the raw content blocks.
	 *
	 * @param  array|null  $content_blocks  Content blocks from Claude response.
	 *
	 * @return void
	 * @since 1.0.9
	 */
	public function set_content_blocks( ?array $content_blocks ): void {
		$this->content_blocks = $content_blocks;
	}

	/**
	 * Create Tool_Calls_Message from Claude API response.
	 *
	 * @param  array  $response  The Claude API response body.
	 *
	 * @return self|null The Tool_Calls_Message instance or null if no tool uses.
	 * @since 1.0.9
	 */
	public static function from_response( array $response ): ?self {
		$content   = $response['content'] ?? array();
		$tool_uses = array_filter( $content, fn( $block ) => ( $block['type'] ?? '' ) === 'tool_use' );

		if ( empty( $tool_uses ) ) {
			return null;
		}

		$instance = self::make( array(
			'role' => 'assistant',
		) );

		$instance->set_tool_uses( array_values( $tool_uses ) );
		$instance->set_content_blocks( $content );

		return $instance;
	}
}

