<?php
/** Read-only abilities for persistent ACF post-type and taxonomy definitions. */

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

/** @return array<string,mixed> */
function wpagent_acf_model_list_ability( string $kind ): array {
	$is_post_type = 'post_type' === $kind;
	return array(
		'label' => $is_post_type ? __( 'ACF-Inhaltstypen auflisten', 'wp-agent-companion' ) : __( 'ACF-Taxonomien auflisten', 'wp-agent-companion' ),
		'description' => $is_post_type
			? __( 'Listet persistente ACF-Inhaltstypdefinitionen mit Portabilität, Inhaltszahl und Konflikt-Hash. PHP- und Local-JSON-Definitionen bleiben ausgeschlossen.', 'wp-agent-companion' )
			: __( 'Listet persistente ACF-Taxonomiedefinitionen mit Portabilität, Begriffsanzahl und Konflikt-Hash. PHP- und Local-JSON-Definitionen bleiben ausgeschlossen.', '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, '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_acf_model_output_schema( $kind ) ),
				'total' => array( 'type' => 'integer' ), 'page' => array( 'type' => 'integer' ),
				'per_page' => array( 'type' => 'integer' ), 'total_pages' => array( 'type' => 'integer' ),
			),
			'required' => array( 'models', 'total', 'page', 'per_page', 'total_pages' ),
			'additionalProperties' => false,
		),
		'execute_callback' => $is_post_type ? 'wpagent_exec_list_acf_post_types' : 'wpagent_exec_list_acf_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_acf_model_get_ability( string $kind ): array {
	$is_post_type = 'post_type' === $kind;
	$prefix = $is_post_type ? 'post_type' : 'taxonomy';
	return array(
		'label' => $is_post_type ? __( 'ACF-Inhaltstyp lesen', 'wp-agent-companion' ) : __( 'ACF-Taxonomie lesen', 'wp-agent-companion' ),
		'description' => $is_post_type
			? __( 'Liest eine persistente ACF-Inhaltstypdefinition vollständig genug für konfliktgeschützte Folgeoperationen.', 'wp-agent-companion' )
			: __( 'Liest eine persistente ACF-Taxonomiedefinition vollständig genug für konfliktgeschützte Folgeoperationen.', 'wp-agent-companion' ),
		'category' => 'wp-agent',
		'input_schema' => array(
			'type' => 'object',
			'properties' => array( 'key' => array( 'type' => 'string', 'pattern' => '^' . $prefix . '_[A-Za-z0-9_-]{1,120}$' ) ),
			'required' => array( 'key' ),
			'additionalProperties' => false,
		),
		'output_schema' => wpagent_acf_model_output_schema( $kind ),
		'execute_callback' => $is_post_type ? 'wpagent_exec_get_acf_post_type' : 'wpagent_exec_get_acf_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_acf_post_types(): array {
	return wpagent_acf_model_list_ability( 'post_type' );
}

function wpagent_ability_get_acf_post_type(): array {
	return wpagent_acf_model_get_ability( 'post_type' );
}

function wpagent_ability_list_acf_taxonomies(): array {
	return wpagent_acf_model_list_ability( 'taxonomy' );
}

function wpagent_ability_get_acf_taxonomy(): array {
	return wpagent_acf_model_get_ability( 'taxonomy' );
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_list_acf_models( string $kind, $input ) {
	$available = wpagent_acf_model_require_api();
	if ( is_wp_error( $available ) ) {
		return $available;
	}
	$input = is_array( $input ) ? $input : array();
	$search = is_string( $input['search'] ?? null ) ? trim( $input['search'] ) : '';
	if ( wpagent_acf_group_text_length( $search ) > 100 || sanitize_text_field( $search ) !== $search ) {
		return new WP_Error( 'wpagent_acf_model_search', __( 'search muss reiner Text mit höchstens 100 Zeichen sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$page = max( 1, absint( $input['page'] ?? 1 ) );
	$per_page = max( 1, min( 50, absint( $input['per_page'] ?? 20 ) ) );
	$config = wpagent_acf_model_kinds()[ $kind ];
	$raw = call_user_func( $config['get_raw'] );
	$models = array();
	$needle = function_exists( 'mb_strtolower' ) ? mb_strtolower( $search, 'UTF-8' ) : strtolower( $search );
	foreach ( is_array( $raw ) ? $raw : array() as $model ) {
		if ( ! is_array( $model ) || absint( $model['ID'] ?? 0 ) < 1 || $config['acf_type'] !== get_post_type( absint( $model['ID'] ) ) ) {
			continue;
		}
		$loaded = call_user_func( $config['get'], (string) ( $model['key'] ?? '' ) );
		if ( ! is_array( $loaded ) || ! empty( $loaded['local'] ) ) {
			continue;
		}
		$labels = is_array( $loaded['labels'] ?? null ) ? $loaded['labels'] : array();
		$slug = (string) ( $loaded[ $config['slug_field'] ] ?? '' );
		$haystack = $slug . ' ' . (string) ( $labels['singular_name'] ?? '' ) . ' ' . (string) ( $labels['name'] ?? $loaded['title'] ?? '' );
		$haystack = function_exists( 'mb_strtolower' ) ? mb_strtolower( $haystack, 'UTF-8' ) : strtolower( $haystack );
		if ( '' !== $needle && false === strpos( $haystack, $needle ) ) {
			continue;
		}
		$models[] = $loaded;
	}
	usort(
		$models,
		static function ( array $a, array $b ): int {
			$a_labels = is_array( $a['labels'] ?? null ) ? $a['labels'] : array();
			$b_labels = is_array( $b['labels'] ?? null ) ? $b['labels'] : array();
			return strcasecmp( (string) ( $a_labels['name'] ?? $a['title'] ?? '' ), (string) ( $b_labels['name'] ?? $b['title'] ?? '' ) );
		}
	);
	$total = count( $models );
	return array(
		'models' => array_map( static fn( array $model ): array => wpagent_acf_model_state( $kind, $model ), array_slice( $models, ( $page - 1 ) * $per_page, $per_page ) ),
		'total' => $total, 'page' => $page, 'per_page' => $per_page,
		'total_pages' => 0 === $total ? 0 : (int) ceil( $total / $per_page ),
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_get_acf_model( string $kind, $input ) {
	$available = wpagent_acf_model_require_api();
	if ( is_wp_error( $available ) ) {
		return $available;
	}
	$input = is_array( $input ) ? $input : array();
	$key = is_string( $input['key'] ?? null ) ? $input['key'] : '';
	$model = wpagent_acf_model_get_persistent( $kind, $key );
	return is_wp_error( $model ) ? $model : wpagent_acf_model_state( $kind, $model );
}

function wpagent_exec_list_acf_post_types( $input ) {
	return wpagent_exec_list_acf_models( 'post_type', $input );
}

function wpagent_exec_get_acf_post_type( $input ) {
	return wpagent_exec_get_acf_model( 'post_type', $input );
}

function wpagent_exec_list_acf_taxonomies( $input ) {
	return wpagent_exec_list_acf_models( 'taxonomy', $input );
}

function wpagent_exec_get_acf_taxonomy( $input ) {
	return wpagent_exec_get_acf_model( 'taxonomy', $input );
}
