<?php
/**
 * List Media Tool.
 *
 * Allows the agent to retrieve lists of media library items with filtering
 * by MIME type, date, search term, and pagination support.
 *
 * @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;
}

/**
 * List_Media_Tool class.
 */
class List_Media_Tool extends Tool {

	/**
	 * Get the tool ID.
	 *
	 * @return string The tool ID.
	 * @since     1.0.0
	 */
	public function get_id() {
		return 'list_media';
	}

	/**
	 * Get the tool name.
	 *
	 * @return string The tool name.
	 * @since     1.0.0
	 */
	public function get_name() {
		return __( 'List Media', 'agenistrator' );
	}

	/**
	 * Get the tool description.
	 *
	 * @return string The tool description.
	 * @since     1.0.0
	 */
	public function get_description() {
		return 'List media library items with optional filtering.';
	}

	/**
	 * Get instructions for the LLM on how to interpret output fields.
	 *
	 * @return string Instructions for the LLM.
	 * @since     1.0.0
	 */
	public function get_instructions() {
		return 'CAPTION FIELDS: `has_caption` indicates if a manual caption is set. If true, `caption` contains the stored value. If false, `auto_caption` contains a truncated auto-generated caption from description (not stored - do not use for updates).';
	}

	/**
	 * Get the parameters schema for this tool.
	 *
	 * @return array Parameters schema in JSON Schema format.
	 * @since     1.0.0
	 */
	public function get_parameters() {
		return array(
			'type'       => 'object',
			'properties' => array(
				'mime_type' => array(
					'type'        => 'string',
					'description' => 'Filter by MIME type (e.g., image, image/jpeg, video, application/pdf)',
				),
				'author'    => array(
					'type'        => 'integer',
					'description' => 'Filter by author user ID',
				),
				'search'    => array(
					'type'        => 'string',
					'description' => 'Search term to find in media titles or filenames',
				),
				'limit'     => array(
					'type'        => 'integer',
					'description' => 'Maximum number of items to return',
					'default'     => 20,
				),
				'offset'    => array(
					'type'        => 'integer',
					'description' => 'Number of items to skip',
					'default'     => 0,
				),
				'order'     => array(
					'type'        => 'string',
					'description' => 'Order direction',
					'enum'        => array( 'ASC', 'DESC' ),
					'default'     => 'DESC',
				),
				'orderby'   => array(
					'type'        => 'string',
					'description' => 'Field to order by',
					'enum'        => array( 'date', 'title', 'modified', 'rand' ),
					'default'     => 'date',
				),
			),
			'required'   => array(),
		);
	}

	/**
	 * Check if the current user can execute this tool.
	 *
	 * @return bool True if the current user has permission.
	 * @since     1.0.0
	 */
	public function current_user_can_execute() {
		return current_user_can( 'upload_files' );
	}

	/**
	 * Check if this tool is read-only.
	 *
	 * @return bool True if the tool only reads data.
	 * @since     1.0.0
	 */
	public function is_read_only() {
		return true;
	}

	/**
	 * Execute the tool with the given arguments.
	 *
	 * @param array $args The tool arguments.
	 *
	 * @return array The tool execution result.
	 * @since     1.0.0
	 */
	protected function execute( $args ) {
		$query_args = array(
			'post_type'      => 'attachment',
			'post_status'    => 'inherit',
			'posts_per_page' => isset( $args['limit'] ) ? intval( $args['limit'] ) : 20,
			'offset'         => isset( $args['offset'] ) ? intval( $args['offset'] ) : 0,
			'order'          => $args['order'] ?? 'DESC',
			'orderby'        => $args['orderby'] ?? 'date',
		);

		if ( isset( $args['mime_type'] ) && ! empty( $args['mime_type'] ) ) {
			$query_args['post_mime_type'] = $args['mime_type'];
		}

		if ( isset( $args['author'] ) && ! empty( $args['author'] ) ) {
			$query_args['author'] = intval( $args['author'] );
		}

		if ( isset( $args['search'] ) && ! empty( $args['search'] ) ) {
			$query_args['s'] = sanitize_text_field( $args['search'] );
		}

		$query = new \WP_Query( $query_args );

		if ( ! $query->have_posts() ) {
			return $this->success_response(
				'No media items found',
				array(
					'media'    => array(),
					'count'    => 0,
					'total'    => 0,
					'limit'    => intval( $query_args['posts_per_page'] ),
					'offset'   => intval( $query_args['offset'] ),
					'has_more' => false,
				)
			);
		}

		$media_items = array();
		foreach ( $query->posts as $attachment ) {
			$has_caption = has_excerpt( $attachment );
			$media_item  = array(
				'id'          => $attachment->ID,
				'title'       => $attachment->post_title,
				'has_caption' => $has_caption,
				'filename'    => basename( get_attached_file( $attachment->ID ) ),
				'url'         => wp_get_attachment_url( $attachment->ID ),
				'mime_type'   => $attachment->post_mime_type,
				'date'        => $attachment->post_date,
				'alt'         => get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ),
			);

			if ( $has_caption ) {
				$media_item['caption'] = $attachment->post_excerpt;
			} else {
				$auto_caption = html_entity_decode( wp_strip_all_tags( get_the_excerpt( $attachment ) ), ENT_QUOTES, 'UTF-8' );
				if ( ! empty( $auto_caption ) ) {
					$media_item['auto_caption'] = String_Utils::truncate_to_token_boundary_with_ellipsis( $auto_caption, 200 );
				}
			}

			$media_items[] = $media_item;
		}

		$limit  = intval( $query_args['posts_per_page'] );
		$offset = intval( $query_args['offset'] );

		return $this->success_response(
			'Media items retrieved successfully',
			array(
				'media'    => $media_items,
				'count'    => count( $media_items ),
				'total'    => $query->found_posts,
				'limit'    => $limit,
				'offset'   => $offset,
				'has_more' => ( $offset + count( $media_items ) ) < $query->found_posts,
			)
		);
	}
}
