<?php
/** Read-only abilities for Custom Post Type UI definitions. */

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

/** @return array<string,mixed> */
function wpagent_cptui_list_ability( string $kind ): array {
	$is_post_type = 'post_type' === $kind;
	return array(
		'label' => $is_post_type ? __( 'CPT-UI-Inhaltstypen auflisten', 'wp-agent-companion' ) : __( 'CPT-UI-Taxonomien auflisten', 'wp-agent-companion' ),
		'description' => $is_post_type
			? __( 'Listet ausschließlich persistente Custom-Post-Type-UI-Inhaltstypdefinitionen mit Laufzeitstatus, Inhaltszahl und Gesamtzustands-Hash.', 'wp-agent-companion' )
			: __( 'Listet ausschließlich persistente Custom-Post-Type-UI-Taxonomiedefinitionen mit Laufzeitstatus, Begriffsanzahl und Gesamtzustands-Hash.', '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(
				'models' => array( 'type' => 'array', 'items' => wpagent_cptui_output_schema( $kind ) ),
				'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( 'models', 'total', 'page', 'per_page', 'total_pages', 'provider_version' ),
			'additionalProperties' => false,
		),
		'execute_callback' => $is_post_type ? 'wpagent_exec_list_cptui_post_types' : 'wpagent_exec_list_cptui_taxonomies',
		'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_cptui_get_ability( string $kind ): array {
	$is_post_type = 'post_type' === $kind;
	$max = $is_post_type ? 20 : 32;
	return array(
		'label' => $is_post_type ? __( 'CPT-UI-Inhaltstyp lesen', 'wp-agent-companion' ) : __( 'CPT-UI-Taxonomie lesen', 'wp-agent-companion' ),
		'description' => $is_post_type
			? __( 'Liest eine persistente CPT-UI-Inhaltstypdefinition für konfliktgeschützte Folgeoperationen.', 'wp-agent-companion' )
			: __( 'Liest eine persistente CPT-UI-Taxonomiedefinition für konfliktgeschützte Folgeoperationen.', 'wp-agent-companion' ),
		'category' => 'wp-agent',
		'input_schema' => array(
			'type' => 'object',
			'properties' => array( 'slug' => array( 'type' => 'string', 'pattern' => '^[a-z0-9_-]+$', 'maxLength' => $max ) ),
			'required' => array( 'slug' ),
			'additionalProperties' => false,
		),
		'output_schema' => wpagent_cptui_output_schema( $kind ),
		'execute_callback' => $is_post_type ? 'wpagent_exec_get_cptui_post_type' : 'wpagent_exec_get_cptui_taxonomy',
		'permission_callback' => 'wpagent_perm_manage_options',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

function wpagent_ability_list_cptui_post_types(): array {
	return wpagent_cptui_list_ability( 'post_type' );
}

function wpagent_ability_get_cptui_post_type(): array {
	return wpagent_cptui_get_ability( 'post_type' );
}

function wpagent_ability_list_cptui_taxonomies(): array {
	return wpagent_cptui_list_ability( 'taxonomy' );
}

function wpagent_ability_get_cptui_taxonomy(): array {
	return wpagent_cptui_get_ability( 'taxonomy' );
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_list_cptui_models( string $kind, $input ) {
	$provider = wpagent_cptui_require_provider();
	if ( is_wp_error( $provider ) ) {
		return $provider;
	}
	$definitions = wpagent_cptui_option_data( $kind );
	if ( is_wp_error( $definitions ) ) {
		return $definitions;
	}
	$input = is_array( $input ) ? $input : array();
	$search = wpagent_cptui_text( $input['search'] ?? '', 'search', 100, true );
	if ( is_wp_error( $search ) ) {
		return $search;
	}
	$page = $input['page'] ?? 1;
	$per_page = $input['per_page'] ?? 20;
	if ( ! is_int( $page ) || $page < 1 || $page > 1000000 || ! is_int( $per_page ) || $per_page < 1 || $per_page > 50 ) {
		return new WP_Error( 'wpagent_cptui_pagination', __( 'page und per_page liegen außerhalb des erlaubten Bereichs.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$needle = function_exists( 'mb_strtolower' ) ? mb_strtolower( $search, 'UTF-8' ) : strtolower( $search );
	$models = array();
	foreach ( $definitions as $slug => $definition ) {
		if ( (string) ( $definition['name'] ?? '' ) !== $slug ) {
			continue;
		}
		$haystack = $slug . ' ' . wpagent_cptui_display_text( $definition['singular_label'] ?? '' ) . ' ' . wpagent_cptui_display_text( $definition['label'] ?? '' );
		$haystack = function_exists( 'mb_strtolower' ) ? mb_strtolower( $haystack, 'UTF-8' ) : strtolower( $haystack );
		if ( '' !== $needle && false === strpos( $haystack, $needle ) ) {
			continue;
		}
		$models[] = $definition;
	}
	usort(
		$models,
		static fn( array $a, array $b ): int => strcasecmp( wpagent_cptui_display_text( $a['label'] ?? '' ), wpagent_cptui_display_text( $b['label'] ?? '' ) )
	);
	$total = count( $models );
	$page_models = array_slice( $models, ( $page - 1 ) * $per_page, $per_page );
	$counts = wpagent_cptui_content_counts( $kind, array_column( $page_models, 'name' ) );
	if ( is_wp_error( $counts ) ) {
		return $counts;
	}
	$model_states = array();
	foreach ( $page_models as $definition ) {
		$state = wpagent_cptui_state( $kind, $definition, $definitions, $counts[ $definition['name'] ] ?? 0 );
		if ( is_wp_error( $state ) ) {
			return $state;
		}
		$model_states[] = $state;
	}
	return array(
		'models' => $model_states,
		'total' => $total,
		'page' => $page,
		'per_page' => $per_page,
		'total_pages' => 0 === $total ? 0 : (int) ceil( $total / $per_page ),
		'provider_version' => (string) CPTUI_VERSION,
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_get_cptui_model( string $kind, $input ) {
	$provider = wpagent_cptui_require_provider();
	if ( is_wp_error( $provider ) ) {
		return $provider;
	}
	$input = is_array( $input ) ? $input : array();
	$slug = wpagent_cptui_slug( $input['slug'] ?? '', $kind, true );
	if ( is_wp_error( $slug ) ) {
		return $slug;
	}
	$definitions = wpagent_cptui_option_data( $kind );
	if ( is_wp_error( $definitions ) ) {
		return $definitions;
	}
	if ( ! isset( $definitions[ $slug ] ) || (string) ( $definitions[ $slug ]['name'] ?? '' ) !== $slug ) {
		return new WP_Error( 'wpagent_cptui_not_found', __( 'Persistente CPT-UI-Definition nicht gefunden. In PHP registrierte Definitionen werden nicht verändert.', 'wp-agent-companion' ), array( 'status' => 404 ) );
	}
	return wpagent_cptui_state( $kind, $definitions[ $slug ], $definitions );
}

function wpagent_exec_list_cptui_post_types( $input ) {
	return wpagent_exec_list_cptui_models( 'post_type', $input );
}

function wpagent_exec_get_cptui_post_type( $input ) {
	return wpagent_exec_get_cptui_model( 'post_type', $input );
}

function wpagent_exec_list_cptui_taxonomies( $input ) {
	return wpagent_exec_list_cptui_models( 'taxonomy', $input );
}

function wpagent_exec_get_cptui_taxonomy( $input ) {
	return wpagent_exec_get_cptui_model( 'taxonomy', $input );
}
