<?php
/**
 * ppok/abilities — bundled discovery aggregator.
 *
 * Collapses what would otherwise be N+1 calls (one discover-abilities,
 * one get-ability-info per slug) into a single round-trip. Returns the
 * name, title, description, input_schema, output_schema, and an example
 * input payload for every ability registered by this plugin.
 *
 * Read-only. Cap: read (i.e. any logged-in user).
 *
 * @package Ppok\AIToolkit
 * @license GPL-2.0-or-later
 */

namespace Ppok\AIToolkit\Abilities;

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

final class Abilities_List {

	public const SLUG = 'ppok/abilities';

	public static function descriptor(): array {
		return array(
			'label'               => __( 'List Ppok abilities', 'ppok-ai-toolkit' ),
			'description'         => __( 'Returns a single bundled list of every ability registered by this plugin (name, title, description, input_schema, output_schema, example). Use this once at session start instead of discover-abilities + get-ability-info per slug.', 'ppok-ai-toolkit' ),
			'category'            => 'ppok',
			'input_schema'        => array(
				'type'       => 'object',
				'properties' => new \stdClass(),
			),
			'output_schema'       => array(
				'type'       => 'object',
				'required'   => array( 'abilities' ),
				'properties' => array(
					'abilities' => array(
						'type'  => 'array',
						'items' => array(
							'type'       => 'object',
							'required'   => array( 'name', 'title', 'description', 'input_schema', 'output_schema' ),
							'properties' => array(
								'name'          => array( 'type' => 'string' ),
								'title'         => array( 'type' => 'string' ),
								'description'   => array( 'type' => 'string' ),
								'input_schema'  => array( 'type' => 'object' ),
								'output_schema' => array( 'type' => 'object' ),
								'example'       => array( 'type' => 'object' ),
							),
						),
					),
				),
			),
			'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 example(): array {
		return array();
	}

	public static function permission_callback(): bool {
		return current_user_can( 'read' );
	}

	public static function execute_callback(): array {
		$items = array();
		foreach ( Ability_Registrar::abilities() as $slug => $descriptor ) {
			$item = array(
				'name'          => $slug,
				'title'         => (string) ( $descriptor['label'] ?? $slug ),
				'description'   => (string) ( $descriptor['description'] ?? '' ),
				'input_schema'  => isset( $descriptor['input_schema'] ) && is_array( $descriptor['input_schema'] )
					? $descriptor['input_schema']
					: array( 'type' => 'object', 'properties' => new \stdClass() ),
				'output_schema' => isset( $descriptor['output_schema'] ) && is_array( $descriptor['output_schema'] )
					? $descriptor['output_schema']
					: array( 'type' => 'object', 'properties' => new \stdClass() ),
			);

			$example = self::example_for( $slug );
			if ( null !== $example ) {
				$item['example'] = $example;
			}

			$items[] = $item;
		}
		return array( 'abilities' => $items );
	}

	/**
	 * Resolve the ability class for a slug and pull its static example()
	 * payload if one is defined. Returns null when no example exists.
	 */
	private static function example_for( string $slug ): ?array {
		$class_map = array(
			System_Ping::SLUG          => System_Ping::class,
			Rest_Call::SLUG            => Rest_Call::class,
			Post_List::SLUG            => Post_List::class,
			Post_Get_Blocks::SLUG      => Post_Get_Blocks::class,
			Post_Set_Blocks::SLUG      => Post_Set_Blocks::class,
			Replace_In_Content::SLUG   => Replace_In_Content::class,
			Preview_Url::SLUG          => Preview_Url::class,
			Blocks_Registered::SLUG    => Blocks_Registered::class,
			Blocks_Find_Usage::SLUG    => Blocks_Find_Usage::class,
			Patterns_Registered::SLUG  => Patterns_Registered::class,
			self::SLUG                 => self::class,
		);

		if ( ! isset( $class_map[ $slug ] ) ) {
			return null;
		}
		$class = $class_map[ $slug ];
		if ( ! method_exists( $class, 'example' ) ) {
			return null;
		}
		$example = call_user_func( array( $class, 'example' ) );
		return is_array( $example ) ? $example : null;
	}
}
