<?php
/** Read abilities for bounded ACPT Lite meta groups and registered values. */

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

/** @return array<string,mixed> */
function wpagent_acpt_meta_option_schema(): array {
	return array(
		'type' => 'object',
		'properties' => array(
			'id' => array( 'type' => 'string' ), 'label' => array( 'type' => 'string' ),
			'value' => array( 'type' => 'string' ), 'sort' => array( 'type' => 'integer' ),
		),
		'required' => array( 'id', 'label', 'value', 'sort' ), 'additionalProperties' => false,
	);
}

/** @return array<string,mixed> */
function wpagent_acpt_meta_field_schema(): array {
	return array(
		'type' => 'object',
		'properties' => array(
			'id' => array( 'type' => 'string' ), 'name' => array( 'type' => 'string' ), 'label' => array( 'type' => 'string' ),
			'type' => array( 'type' => 'string', 'enum' => array( 'date', 'email', 'select', 'text', 'textarea' ) ),
			'required' => array( 'type' => 'boolean' ), 'sort' => array( 'type' => 'integer' ),
			'options' => array( 'type' => 'array', 'items' => wpagent_acpt_meta_option_schema() ),
		),
		'required' => array( 'id', 'name', 'label', 'type', 'required', 'sort', 'options' ), 'additionalProperties' => false,
	);
}

/** @return array<string,mixed> */
function wpagent_acpt_meta_group_schema(): array {
	return array(
		'type' => 'object',
		'properties' => array(
			'id' => array( 'type' => 'string' ), 'binding_id' => array( 'type' => 'string' ),
			'name' => array( 'type' => 'string' ), 'label' => array( 'type' => 'string' ),
			'target' => array(
				'type' => 'object',
				'properties' => array( 'type' => array( 'type' => 'string', 'enum' => array( 'post_type', 'taxonomy', 'user', 'comment' ) ), 'name' => array( 'type' => 'string' ) ),
				'required' => array( 'type', 'name' ), 'additionalProperties' => false,
			),
			'context' => array( 'type' => 'string', 'enum' => array( 'normal', 'advanced', 'side' ) ),
			'priority' => array( 'type' => 'string', 'enum' => array( 'default', 'high', 'low' ) ),
			'boxes' => array(
				'type' => 'array',
				'items' => array(
					'type' => 'object',
					'properties' => array(
						'id' => array( 'type' => 'string' ), 'name' => array( 'type' => 'string' ), 'label' => array( 'type' => 'string' ),
						'sort' => array( 'type' => 'integer' ), 'fields' => array( 'type' => 'array', 'items' => wpagent_acpt_meta_field_schema() ),
					),
					'required' => array( 'id', 'name', 'label', 'sort', 'fields' ), 'additionalProperties' => false,
				),
			),
			'provider_version' => array( 'type' => 'string' ), 'definition_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
		),
		'required' => array( 'id', 'binding_id', 'name', 'label', 'target', 'context', 'priority', 'boxes', 'provider_version', 'definition_hash' ), 'additionalProperties' => false,
	);
}

/** @return array<string,mixed> */
function wpagent_acpt_meta_values_schema(): array {
	return array(
		'type' => 'object',
		'properties' => array(
			'group' => array( 'type' => 'string' ), 'object_type' => array( 'type' => 'string' ), 'object_id' => array( 'type' => 'integer' ),
			'values' => array( 'type' => 'object', 'additionalProperties' => array( 'type' => array( 'string', 'null' ) ) ),
			'values_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ), 'provider_version' => array( 'type' => 'string' ),
		),
		'required' => array( 'group', 'object_type', 'object_id', 'values', 'values_hash', 'provider_version' ), 'additionalProperties' => false,
	);
}

function wpagent_perm_acpt_meta_values( $input = null ): bool {
	if ( ! is_array( $input ) || ! is_string( $input['group'] ?? null ) || ! is_string( $input['object_type'] ?? null ) ) return current_user_can( 'read' );
	$name = wpagent_acpt_meta_identifier( $input['group'], 'group' );
	if ( is_wp_error( $name ) ) return current_user_can( 'read' );
	$group = wpagent_acpt_meta_group_state( $name );
	if ( is_wp_error( $group ) ) return current_user_can( 'read' );
	$context = wpagent_acpt_meta_object_context( $input['object_type'], $input['object_id'] ?? null, $group );
	return ! is_wp_error( $context ) && wpagent_acpt_meta_can_edit_object( $context );
}

/** @return array<string,mixed> */
function wpagent_ability_list_acpt_meta_groups(): array {
	return array(
		'label' => __( 'ACPT-Lite-Metagruppe auflisten', 'wp-agent-companion' ),
		'description' => __( 'Listet ausschließlich kleine, eindeutig gebundene ACPT-Lite-Metaprofile mit fünf einfachen Feldtypen und Konflikthash.', 'wp-agent-companion' ),
		'category' => 'wp-agent',
		'input_schema' => array(
			'type' => 'object', 'properties' => array(
				'search' => array( 'type' => 'string', 'maxLength' => 100 ),
				'page' => array( 'type' => 'integer', 'minimum' => 1, 'maximum' => 1000000, 'default' => 1 ),
				'per_page' => array( 'type' => 'integer', 'minimum' => 1, 'maximum' => 50, 'default' => 20 ),
			),
			'additionalProperties' => false,
		),
		'output_schema' => array(
			'type' => 'object', 'properties' => array(
				'items' => array( 'type' => 'array', 'items' => wpagent_acpt_meta_group_schema() ),
				'total' => array( 'type' => 'integer' ), 'page' => array( 'type' => 'integer' ), 'per_page' => array( 'type' => 'integer' ),
				'total_pages' => array( 'type' => 'integer' ), 'provider_version' => array( 'type' => 'string' ),
			),
			'required' => array( 'items', 'total', 'page', 'per_page', 'total_pages', 'provider_version' ), 'additionalProperties' => false,
		),
		'execute_callback' => 'wpagent_exec_list_acpt_meta_groups', 'permission_callback' => 'wpagent_perm_manage_options',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

/** @return array<string,mixed> */
function wpagent_ability_get_acpt_meta_group(): array {
	return array(
		'label' => __( 'ACPT-Lite-Metagruppe lesen', 'wp-agent-companion' ),
		'description' => __( 'Liest eine begrenzte ACPT-Lite-Metagruppe mit vollständiger Struktur und Konflikthash.', 'wp-agent-companion' ),
		'category' => 'wp-agent',
		'input_schema' => array( 'type' => 'object', 'properties' => array( 'name' => array( 'type' => 'string', 'pattern' => '^[a-z][a-z0-9_]{2,39}$' ) ), 'required' => array( 'name' ), 'additionalProperties' => false ),
		'output_schema' => wpagent_acpt_meta_group_schema(), 'execute_callback' => 'wpagent_exec_get_acpt_meta_group', 'permission_callback' => 'wpagent_perm_manage_options',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

/** @return array<string,mixed> */
function wpagent_ability_get_acpt_field_values(): array {
	return array(
		'label' => __( 'ACPT-Lite-Feldwerte lesen', 'wp-agent-companion' ),
		'description' => __( 'Liest die rohen Werte genau der registrierten einfachen Felder an einem passend gebundenen WordPress-Objekt.', 'wp-agent-companion' ),
		'category' => 'wp-agent',
		'input_schema' => array(
			'type' => 'object', 'properties' => array(
				'group' => array( 'type' => 'string', 'pattern' => '^[a-z][a-z0-9_]{2,39}$' ),
				'object_type' => array( 'type' => 'string', 'enum' => array( 'post', 'term', 'user', 'comment' ) ),
				'object_id' => array( 'type' => 'integer', 'minimum' => 1 ),
			),
			'required' => array( 'group', 'object_type', 'object_id' ), 'additionalProperties' => false,
		),
		'output_schema' => wpagent_acpt_meta_values_schema(), 'execute_callback' => 'wpagent_exec_get_acpt_field_values', 'permission_callback' => 'wpagent_perm_acpt_meta_values',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_list_acpt_meta_groups( $input ) {
	$provider = wpagent_acpt_meta_provider();
	if ( is_wp_error( $provider ) ) return $provider;
	$cache = wpagent_acpt_flush_provider_cache( $provider );
	if ( is_wp_error( $cache ) ) return $cache;
	$input = is_array( $input ) ? $input : array();
	$search = wpagent_acpt_meta_text( $input['search'] ?? '', 'search', 100, true );
	$page = $input['page'] ?? 1; $per_page = $input['per_page'] ?? 20;
	if ( is_wp_error( $search ) ) return $search;
	if ( ! is_int( $page ) || $page < 1 || $page > 1000000 || ! is_int( $per_page ) || $per_page < 1 || $per_page > 50 ) return new WP_Error( 'wpagent_acpt_meta_pagination', __( 'page und per_page liegen außerhalb des erlaubten Bereichs.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	try { $models = $provider['repository']::get( array() ); $count = $provider['repository']::count(); } catch ( Throwable $error ) { return new WP_Error( 'wpagent_acpt_meta_read', __( 'Die ACPT-Lite-Metaprofile konnten nicht vollständig gelesen werden.', 'wp-agent-companion' ), array( 'status' => 500 ) ); }
	if ( ! is_array( $models ) || ! is_int( $count ) || $count < 0 || $count > WPAGENT_ACPT_META_MAX_GROUPS || count( $models ) !== $count ) return new WP_Error( 'wpagent_acpt_meta_storage', __( 'ACPT Lite lieferte einen unvollständigen oder zu großen Metagruppenbestand.', 'wp-agent-companion' ), array( 'status' => 500 ) );
	$needle = function_exists( 'mb_strtolower' ) ? mb_strtolower( $search, 'UTF-8' ) : strtolower( $search );
	$items = array();
	foreach ( $models as $model ) {
		if ( ! is_object( $model ) ) return new WP_Error( 'wpagent_acpt_meta_storage', __( 'ACPT Lite lieferte eine beschädigte Metagruppe.', 'wp-agent-companion' ), array( 'status' => 500 ) );
		$state = wpagent_acpt_meta_group_state_from_model( $model, $provider['version'] );
		if ( is_wp_error( $state ) ) continue;
		$haystack = function_exists( 'mb_strtolower' ) ? mb_strtolower( $state['name'] . ' ' . $state['label'], 'UTF-8' ) : strtolower( $state['name'] . ' ' . $state['label'] );
		if ( '' === $needle || false !== strpos( $haystack, $needle ) ) $items[] = $state;
	}
	usort( $items, static fn( array $a, array $b ): int => strcmp( $a['name'], $b['name'] ) );
	$total = count( $items );
	return array( 'items' => array_slice( $items, ( $page - 1 ) * $per_page, $per_page ), 'total' => $total, 'page' => $page, 'per_page' => $per_page, 'total_pages' => 0 === $total ? 0 : (int) ceil( $total / $per_page ), 'provider_version' => $provider['version'] );
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_get_acpt_meta_group( $input ) {
	$input = is_array( $input ) ? $input : array();
	$name = wpagent_acpt_meta_identifier( $input['name'] ?? '', 'name' );
	return is_wp_error( $name ) ? $name : wpagent_acpt_meta_group_state( $name );
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_get_acpt_field_values( $input ) {
	$input = is_array( $input ) ? $input : array();
	$name = wpagent_acpt_meta_identifier( $input['group'] ?? '', 'group' );
	if ( is_wp_error( $name ) ) return $name;
	$group = wpagent_acpt_meta_group_state( $name );
	if ( is_wp_error( $group ) ) return $group;
	$context = wpagent_acpt_meta_object_context( is_string( $input['object_type'] ?? null ) ? $input['object_type'] : '', $input['object_id'] ?? null, $group );
	if ( is_wp_error( $context ) ) return $context;
	if ( ! wpagent_acpt_meta_can_edit_object( $context ) ) return new WP_Error( 'wpagent_acpt_meta_forbidden', __( 'Du darfst die ACPT-Lite-Werte dieses Objekts nicht lesen.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	return wpagent_acpt_meta_values_state( $group, $context );
}
