<?php
/**
 * List Comments Tool.
 *
 * Retrieve lists of WordPress comments using get_comments() with filtering
 * by post, status, type, author, and search with 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_Comments_Tool class.
 */
class List_Comments_Tool extends Tool {

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

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

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

	/**
	 * Get usage instructions for the LLM.
	 *
	 * @return string Instructions for using this tool.
	 * @since     1.0.0
	 */
	public function get_instructions() {
		return <<<'INST'
TRUNCATION NOTE:
The `truncated_content` field is truncated for brevity. Use the `get_comment_details` tool with the comment ID to retrieve the full content.

FILTERING OPTIONS:
- post_id: Filter to comments on a specific post.
- status: Filter by status (approve, hold, spam, trash, all). Default returns approved comments only.
- user_id: Filter to comments by a specific registered user. Use 0 for anonymous comments only.
- author_email: Filter by author email address.
- search: Search within comment content.

PAGINATION:
- Use limit and offset for pagination. Default limit is 20.
- Response includes has_more boolean and total count for pagination logic.

STATUS VALUES:
- approve: Published, visible on site.
- hold: Pending moderation.
- spam: Marked as spam.
- trash: In trash.
- all: Include all statuses.

COMMON PATTERNS:
- Get pending comments: { status: "hold" }
- Get comments on post: { post_id: 123 }
- Get user's comments: { user_id: 5 }
- Get anonymous comments: { user_id: 0 }
- Search comments: { search: "keyword" }
INST;
	}

	/**
	 * 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(
				'post_id'      => array(
					'type'        => 'integer',
					'description' => 'Filter to comments on this post.',
				),
				'status'       => array(
					'type'        => 'string',
					'description' => 'Filter by comment status. Default returns approved only.',
					'enum'        => array( 'approve', 'hold', 'spam', 'trash', 'all' ),
				),
				'user_id'      => array(
					'type'        => 'integer',
					'description' => 'Filter by user ID. Use 0 for anonymous comments.',
				),
				'author_email' => array(
					'type'        => 'string',
					'description' => 'Filter by author email address.',
				),
				'search'       => array(
					'type'        => 'string',
					'description' => 'Search term to find in comment content.',
				),
				'limit'        => array(
					'type'        => 'integer',
					'description' => 'Maximum number of comments to return.',
					'default'     => 20,
				),
				'offset'       => array(
					'type'        => 'integer',
					'description' => 'Number of comments to skip for pagination.',
					'default'     => 0,
				),
				'order'        => array(
					'type'        => 'string',
					'description' => 'Sort order.',
					'enum'        => array( 'ASC', 'DESC' ),
					'default'     => 'DESC',
				),
				'orderby'      => array(
					'type'        => 'string',
					'description' => 'Field to sort by.',
					'enum'        => array( 'comment_date', 'comment_author', 'comment_post_ID' ),
					'default'     => 'comment_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( 'moderate_comments' );
	}

	/**
	 * 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(
			'number'  => intval( $args['limit'] ?? 20 ),
			'offset'  => intval( $args['offset'] ?? 0 ),
			'order'   => $args['order'] ?? 'DESC',
			'orderby' => $args['orderby'] ?? 'comment_date',
		);

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

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

		if ( isset( $args['user_id'] ) ) {
			$query_args['user_id'] = intval( $args['user_id'] );
		}

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

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

		$comments_query = new \WP_Comment_Query( $query_args );
		$comments       = $comments_query->comments;

		if ( empty( $comments ) ) {
			return $this->success_response(
				'No comments found.',
				array(
					'comments' => array(),
					'count'    => 0,
					'total'    => 0,
					'limit'    => $query_args['number'],
					'offset'   => $query_args['offset'],
					'has_more' => false,
				)
			);
		}

		$formatted_comments = array();
		foreach ( $comments as $comment ) {
			$post                 = get_post( $comment->comment_post_ID );
			$formatted_comments[] = array(
				'id'                => intval( $comment->comment_ID ),
				'post_id'           => intval( $comment->comment_post_ID ),
				'post_title'        => $post ? $post->post_title : '',
				'user_id'           => intval( $comment->user_id ),
				'author'            => $comment->comment_author,
				'author_email'      => $comment->comment_author_email,
				'date'              => $comment->comment_date,
				'truncated_content' => String_Utils::truncate_to_token_boundary_with_ellipsis( $comment->comment_content, 200 ),
				'status'            => Create_Comment_Tool::approved_to_status( wp_get_comment_status( $comment ) ),
				'parent'            => intval( $comment->comment_parent ),
			);
		}

		$total_query = new \WP_Comment_Query(
			array_merge(
				$query_args,
				array(
					'count'  => true,
					'number' => 0,
				)
			)
		);

		return $this->success_response(
			'Comments retrieved successfully.',
			array(
				'comments' => $formatted_comments,
				'count'    => count( $formatted_comments ),
				'total'    => $total_query->get_comments(),
				'limit'    => $query_args['number'],
				'offset'   => $query_args['offset'],
				'has_more' => ( $query_args['offset'] + count( $formatted_comments ) ) < $total_query->get_comments(),
			)
		);
	}
}
