<?php
/**
 * ppok/post/list — curated WP_Query wrapper for AI clients.
 *
 * Read-only. Cap: edit_posts. Filters: post_type, post_status, search,
 * per_page (1-100), page (>=1).
 *
 * @package Ppok\AIToolkit
 * @license GPL-2.0-or-later
 */

namespace Ppok\AIToolkit\Abilities;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

final class Post_List {

	public const SLUG          = 'ppok/list-posts';
	public const PER_PAGE_MAX  = 100;
	public const PER_PAGE_DEFAULT = 10;

	public static function descriptor(): array {
		return array(
			'label'               => __( 'List posts', 'ppok-ai-toolkit' ),
			'description'         => __( 'Lists posts matching a curated subset of WP_Query filters: post_type, post_status, search, per_page, page. Read-only.', 'ppok-ai-toolkit' ),
			'category'            => 'ppok',
			'input_schema'        => self::input_schema(),
			'output_schema'       => self::output_schema(),
			'permission_callback' => array( __CLASS__, 'permission_callback' ),
			'execute_callback'    => array( __CLASS__, 'execute_callback' ),
			'meta'                => array(
				'show_in_rest' => true,
				'mcp'          => array( 'public' => true ),
				'ppok'         => array( 'write' => false ),
			),
		);
	}

	public static function input_schema(): array {
		return array(
			'type'                 => 'object',
			'additionalProperties' => false,
			'properties'           => array(
				'post_type'   => array(
					'type'    => 'array',
					'items'   => array( 'type' => 'string' ),
					'default' => array( 'post' ),
				),
				'post_status' => array(
					'type'    => 'array',
					'items'   => array( 'type' => 'string' ),
					'default' => array( 'publish' ),
				),
				'search'      => array(
					'type'      => 'string',
					'maxLength' => 200,
				),
				'per_page'    => array(
					'type'    => 'integer',
					'minimum' => 1,
					'maximum' => self::PER_PAGE_MAX,
					'default' => self::PER_PAGE_DEFAULT,
				),
				'page'        => array(
					'type'    => 'integer',
					'minimum' => 1,
					'default' => 1,
				),
			),
		);
	}

	public static function output_schema(): array {
		return array(
			'type'       => 'object',
			'required'   => array( 'posts', 'total', 'pages' ),
			'properties' => array(
				'posts' => array(
					'type'  => 'array',
					'items' => array(
						'type'       => 'object',
						'properties' => array(
							'id'           => array( 'type' => 'integer' ),
							'title'        => array( 'type' => 'string' ),
							'post_status'  => array( 'type' => 'string' ),
							'post_type'    => array( 'type' => 'string' ),
							'date_gmt'     => array( 'type' => 'string' ),
							'modified_gmt' => array( 'type' => 'string' ),
							'author_id'    => array( 'type' => 'integer' ),
						),
					),
				),
				'total' => array( 'type' => 'integer' ),
				'pages' => array( 'type' => 'integer' ),
			),
		);
	}

	public static function example(): array {
		return array(
			'post_type'   => array( 'post' ),
			'post_status' => array( 'publish' ),
			'per_page'    => 5,
			'page'        => 1,
		);
	}

	public static function permission_callback( array $args = array() ): bool {
		return current_user_can( 'edit_posts' );
	}

	public static function execute_callback( array $args = array() ): array {
		$post_type   = self::normalize_string_list( $args['post_type'] ?? array( 'post' ) );
		$post_status = self::normalize_string_list( $args['post_status'] ?? array( 'publish' ) );
		$search      = isset( $args['search'] ) ? (string) $args['search'] : '';
		$per_page    = min( self::PER_PAGE_MAX, max( 1, (int) ( $args['per_page'] ?? self::PER_PAGE_DEFAULT ) ) );
		$page        = max( 1, (int) ( $args['page'] ?? 1 ) );

		$query = new \WP_Query(
			array(
				'post_type'      => $post_type,
				'post_status'    => $post_status,
				's'              => $search,
				'posts_per_page' => $per_page,
				'paged'          => $page,
				'no_found_rows'  => false,
				'orderby'        => 'date',
				'order'          => 'DESC',
				'ignore_sticky_posts' => true,
			)
		);

		return array(
			'posts' => array_map( array( __CLASS__, 'shape_post' ), $query->posts ),
			'total' => (int) $query->found_posts,
			'pages' => (int) $query->max_num_pages,
		);
	}

	private static function shape_post( \WP_Post $p ): array {
		return array(
			'id'           => (int) $p->ID,
			'title'        => (string) $p->post_title,
			'post_status'  => (string) $p->post_status,
			'post_type'    => (string) $p->post_type,
			'date_gmt'     => (string) $p->post_date_gmt,
			'modified_gmt' => (string) $p->post_modified_gmt,
			'author_id'    => (int) $p->post_author,
		);
	}

	/**
	 * @param mixed $value
	 * @return array<int,string>
	 */
	private static function normalize_string_list( $value ): array {
		if ( is_string( $value ) ) {
			$value = array( $value );
		}
		if ( ! is_array( $value ) ) {
			return array();
		}
		return array_values( array_map( 'strval', array_filter( $value, 'is_scalar' ) ) );
	}
}
