<?php
/** Read abilities for the live native WordPress block registry and documents. */

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

/** @return array<string,mixed> */
function wpagent_native_block_type_summary_schema(): array {
	$properties = array(
		'name' => array( 'type' => 'string' ), 'namespace' => array( 'type' => 'string' ),
		'title' => array( 'type' => 'string' ), 'category' => array( 'type' => 'string' ),
		'api_version' => array( 'type' => 'integer' ), 'dynamic' => array( 'type' => 'boolean' ),
		'attribute_count' => array( 'type' => 'integer' ),
	);
	return array( 'type' => 'object', 'properties' => $properties, 'required' => array_keys( $properties ), 'additionalProperties' => false );
}

/** @return array<string,mixed> */
function wpagent_native_block_document_schema(): array {
	$properties = array(
		'post_id' => array( 'type' => 'integer' ), 'post_type' => array( 'type' => 'string' ),
		'status' => array( 'type' => 'string' ), 'modified' => array( 'type' => 'string' ),
		'content' => array( 'type' => 'string' ), 'block_count' => array( 'type' => 'integer' ),
		'freeform_count' => array( 'type' => 'integer' ),
		'block_types' => array( 'type' => 'array', 'items' => array( 'type' => 'string' ) ),
		'primary' => array( 'type' => 'string' ),
		'hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
	);
	return array( 'type' => 'object', 'properties' => $properties, 'required' => array_keys( $properties ), 'additionalProperties' => false );
}

function wpagent_ability_list_block_types(): array {
	return array(
		'label' => __( 'Native Blocktypen auflisten', 'wp-agent-companion' ),
		'description' => __( 'Liest alle tatsächlich registrierten Blocktypen ohne Callbacks, Quellpfade oder Geheimnisattribute.', 'wp-agent-companion' ),
		'category' => 'wp-agent',
		'input_schema' => array(
			'type' => 'object', 'properties' => array(
				'search' => array( 'type' => 'string', 'maxLength' => 100 ),
				'namespace' => array( 'type' => 'string', 'pattern' => '^(?:all|[a-z0-9-]+)$', 'maxLength' => 64, 'default' => 'all' ),
				'page' => array( 'type' => 'integer', 'minimum' => 1, 'default' => 1 ),
				'per_page' => array( 'type' => 'integer', 'minimum' => 1, 'maximum' => 500, 'default' => 100 ),
			), 'additionalProperties' => false,
		),
		'output_schema' => array(
			'type' => 'object', 'properties' => array(
				'items' => array( 'type' => 'array', 'items' => wpagent_native_block_type_summary_schema() ),
				'total' => array( 'type' => 'integer' ), 'page' => array( 'type' => 'integer' ),
				'per_page' => array( 'type' => 'integer' ), 'pages' => array( 'type' => 'integer' ),
			), 'required' => array( 'items', 'total', 'page', 'per_page', 'pages' ), 'additionalProperties' => false,
		),
		'execute_callback' => 'wpagent_exec_list_block_types', 'permission_callback' => 'wpagent_perm_edit_posts',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

function wpagent_ability_get_block_type(): array {
	$properties = wpagent_native_block_type_summary_schema()['properties'];
	$properties['description'] = array( 'type' => 'string' );
	$properties['parent'] = array( 'type' => 'array', 'items' => array( 'type' => 'string' ) );
	$properties['ancestor'] = array( 'type' => 'array', 'items' => array( 'type' => 'string' ) );
	$properties['allowed_blocks'] = array( 'type' => 'array', 'items' => array( 'type' => 'string' ) );
	$properties['attributes'] = array( 'type' => 'object', 'additionalProperties' => true );
	$properties['supports'] = array( 'type' => 'object', 'additionalProperties' => true );
	return array(
		'label' => __( 'Nativen Blocktyp lesen', 'wp-agent-companion' ),
		'description' => __( 'Liest das serverseitig registrierte Schema eines Blocktyps in einer JSON-sicheren Darstellung.', 'wp-agent-companion' ),
		'category' => 'wp-agent',
		'input_schema' => array( 'type' => 'object', 'properties' => array( 'name' => array( 'type' => 'string', 'pattern' => '^[a-z0-9-]+/[a-z0-9-]+$', 'maxLength' => 200 ) ), 'required' => array( 'name' ), 'additionalProperties' => false ),
		'output_schema' => array( 'type' => 'object', 'properties' => $properties, 'required' => array_keys( $properties ), 'additionalProperties' => false ),
		'execute_callback' => 'wpagent_exec_get_block_type', 'permission_callback' => 'wpagent_perm_edit_posts',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

function wpagent_ability_get_native_block_document(): array {
	return array(
		'label' => __( 'Natives Blockdokument lesen', 'wp-agent-companion' ),
		'description' => __( 'Liest ein serialisiertes Gutenberg-, Kadence-, GenerateBlocks- oder Spectra-Dokument samt Konflikt-Hash und rekursivem Blockbericht.', 'wp-agent-companion' ),
		'category' => 'wp-agent',
		'input_schema' => array( 'type' => 'object', 'properties' => array( 'post_id' => array( 'type' => 'integer', 'minimum' => 1 ) ), 'required' => array( 'post_id' ), 'additionalProperties' => false ),
		'output_schema' => wpagent_native_block_document_schema(),
		'execute_callback' => 'wpagent_exec_get_native_block_document', 'permission_callback' => 'wpagent_perm_edit_posts',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

/** @param mixed $input @return array<string,mixed>|WP_Error */
function wpagent_exec_list_block_types( $input ) {
	if ( ! is_array( $input ) || array_diff_key( $input, array_flip( array( 'search', 'namespace', 'page', 'per_page' ) ) ) ) {
		return new WP_Error( 'wpagent_native_block_input', __( 'Ungültiger Block-Namespace.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$search    = $input['search'] ?? '';
	$namespace = $input['namespace'] ?? 'all';
	$page      = $input['page'] ?? 1;
	$per_page  = $input['per_page'] ?? 100;
	if (
		! is_string( $search )
		|| ! is_string( $namespace )
		|| ! is_int( $page )
		|| ! is_int( $per_page )
	) {
		return new WP_Error( 'wpagent_native_block_input', __( 'Ungültiger Block-Namespace.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	if (
		wpagent_native_block_string_length( $search ) > 100
		|| $page < 1
		|| $per_page < 1
		|| $per_page > 500
	) {
		return new WP_Error( 'wpagent_native_block_input', __( 'Ungültiger Block-Namespace.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	if ( ! preg_match( '/^(?:all|[a-z0-9-]+)$/', $namespace ) || strlen( $namespace ) > 64 ) {
		return new WP_Error( 'wpagent_native_block_namespace', __( 'Ungültiger Block-Namespace.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$search     = trim( $search );
	$items      = array();
	foreach ( WP_Block_Type_Registry::get_instance()->get_all_registered() as $type ) {
		if ( ! $type instanceof WP_Block_Type ) continue;
		$summary = wpagent_native_block_type_summary( $type );
		if ( 'all' !== $namespace && $namespace !== $summary['namespace'] ) continue;
		if ( '' !== $search && false === stripos( $summary['name'] . ' ' . $summary['title'], $search ) ) continue;
		$items[] = $summary;
	}
	usort( $items, static fn( array $a, array $b ): int => strcmp( $a['name'], $b['name'] ) );
	$total = count( $items );
	$pages = max( 1, (int) ceil( $total / $per_page ) );
	return array( 'items' => array_slice( $items, ( $page - 1 ) * $per_page, $per_page ), 'total' => $total, 'page' => $page, 'per_page' => $per_page, 'pages' => $pages );
}

/** @param mixed $input @return array<string,mixed>|WP_Error */
function wpagent_exec_get_block_type( $input ) {
	if ( ! is_array( $input ) || array_diff_key( $input, array_flip( array( 'name' ) ) ) || ! isset( $input['name'] ) || ! is_string( $input['name'] ) ) {
		return new WP_Error( 'wpagent_native_block_name', __( 'Ungültiger Blocktyp.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$name = $input['name'];
	if ( strlen( $name ) > 200 || ! preg_match( '/^[a-z0-9-]+\/[a-z0-9-]+$/', $name ) ) {
		return new WP_Error( 'wpagent_native_block_name', __( 'Ungültiger Blocktyp.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$type = WP_Block_Type_Registry::get_instance()->get_registered( $name );
	if ( ! $type instanceof WP_Block_Type ) {
		return new WP_Error( 'wpagent_native_block_type_not_found', __( 'Blocktyp ist auf dieser Website nicht registriert.', 'wp-agent-companion' ), array( 'status' => 404 ) );
	}
	$result = wpagent_native_block_type_summary( $type );
	$result['description'] = wpagent_native_block_public_string( wp_strip_all_tags( (string) $type->description ) ) ?? '';
	$result['parent'] = wpagent_native_block_public_block_names( $type->parent );
	$result['ancestor'] = wpagent_native_block_public_block_names( $type->ancestor );
	$result['allowed_blocks'] = wpagent_native_block_public_block_names( $type->allowed_blocks );
	$result['attributes'] = wpagent_native_block_public_attributes( $type );
	$result['supports'] = (array) wpagent_native_block_public_schema_value( (array) $type->supports );
	return $result;
}

/** @param mixed $input @return array<string,mixed>|WP_Error */
function wpagent_exec_get_native_block_document( $input ) {
	return wpagent_native_block_document_state( is_array( $input ) ? (int) ( $input['post_id'] ?? 0 ) : 0 );
}
