<?php
/** Read-only abilities for persistent ACF field groups. */

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

function wpagent_ability_list_acf_field_groups(): array {
	return array(
		'label' => __( 'ACF-Feldgruppen auflisten', 'wp-agent-companion' ),
		'description' => __( 'Listet persistente ACF-Feldgruppen mit Inhaltstypen, Feldzahl, Portabilität und Konflikt-Hash. Lokale PHP- und JSON-Gruppen werden nicht als veränderbar ausgegeben.', '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 ),
			),
			'maxProperties' => 3,
			'additionalProperties' => false,
		),
		'output_schema' => array(
			'type' => 'object',
			'properties' => array(
				'groups' => array( 'type' => 'array', 'maxItems' => 50, 'items' => wpagent_acf_group_output_schema() ),
				'total' => array( 'type' => 'integer', 'minimum' => 0, 'maximum' => WPAGENT_ACF_GROUP_MAX_LIST_TOTAL ),
				'page' => array( 'type' => 'integer', 'minimum' => 1, 'maximum' => 2000 ),
				'per_page' => array( 'type' => 'integer', 'minimum' => 1, 'maximum' => 50 ),
				'total_pages' => array( 'type' => 'integer', 'minimum' => 0, 'maximum' => 2000 ),
			),
			'required' => array( 'groups', 'total', 'page', 'per_page', 'total_pages' ),
			'maxProperties' => 5,
			'additionalProperties' => false,
		),
		'execute_callback' => 'wpagent_exec_list_acf_field_groups',
		'permission_callback' => 'wpagent_perm_manage_options',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

function wpagent_ability_get_acf_field_group(): array {
	return array(
		'label' => __( 'ACF-Feldgruppe lesen', 'wp-agent-companion' ),
		'description' => __( 'Liest eine persistente ACF-Feldgruppe einschließlich ihrer begrenzten Felddefinitionen und eines Konflikt-Hashs über die native ACF-API.', 'wp-agent-companion' ),
		'category' => 'wp-agent',
		'input_schema' => array(
			'type' => 'object',
			'properties' => array( 'group_key' => array( 'type' => 'string', 'minLength' => 7, 'maxLength' => 127, 'pattern' => '^group_[A-Za-z0-9_-]{1,120}$' ) ),
			'required' => array( 'group_key' ),
			'maxProperties' => 1,
			'additionalProperties' => false,
		),
		'output_schema' => wpagent_acf_group_output_schema(),
		'execute_callback' => 'wpagent_exec_get_acf_field_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>|WP_Error */
function wpagent_exec_list_acf_field_groups( $input ) {
	$available = wpagent_acf_group_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 ) {
		return new WP_Error( 'wpagent_acf_group_search', __( 'search darf höchstens 100 Zeichen enthalten.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$page = array_key_exists( 'page', $input ) ? wpagent_core_schema_input_integer( $input['page'], 1, 2000, 'page' ) : 1;
	$per_page = array_key_exists( 'per_page', $input ) ? wpagent_core_schema_input_integer( $input['per_page'], 1, 50, 'per_page' ) : 20;
	if ( is_wp_error( $page ) || is_wp_error( $per_page ) ) {
		return is_wp_error( $page ) ? $page : $per_page;
	}
	$groups = acf_get_raw_field_groups();
	if ( ! is_array( $groups ) || ! array_is_list( $groups ) || count( $groups ) > WPAGENT_ACF_GROUP_MAX_LIST_TOTAL ) {
		return wpagent_acf_group_read_output_error( 'wpagent_acf_group_output_overflow', 'groups' );
	}
	$candidates = array();
	foreach ( $groups as $group ) {
		if ( ! is_array( $group ) || array_is_list( $group ) ) {
			return wpagent_acf_group_read_output_error( 'wpagent_acf_group_output_invalid', 'groups' );
		}
		if ( ! empty( $group['local'] ) ) {
			continue;
		}
		$id = wpagent_acf_group_read_integer( $group['ID'] ?? null, 1, 2147483647, 'groups.id' );
		$title = wpagent_acf_group_read_text( $group['title'] ?? null, 200, 'groups.title', false );
		$key = wpagent_acf_group_read_text( $group['key'] ?? null, 127, 'groups.key', false );
		if ( is_wp_error( $id ) || is_wp_error( $title ) || is_wp_error( $key ) ) {
			return is_wp_error( $id ) ? $id : ( is_wp_error( $title ) ? $title : $key );
		}
		if ( 'acf-field-group' !== get_post_type( $id ) || ! preg_match( '/^group_[A-Za-z0-9_-]{1,120}$/D', $key ) ) {
			return wpagent_acf_group_read_output_error( 'wpagent_acf_group_output_invalid', 'groups' );
		}
		if ( '' === $search || false !== stripos( $title, $search ) || false !== stripos( $key, $search ) ) {
			$candidates[] = array( 'group' => $group, 'title' => $title, 'key' => $key );
		}
	}
	usort(
		$candidates,
		static fn( array $left, array $right ): int => strnatcasecmp( $left['title'], $right['title'] ) ?: strcmp( $left['key'], $right['key'] )
	);
	$total = count( $candidates );
	$candidates = array_slice( $candidates, ( $page - 1 ) * $per_page, $per_page );
	$states = array();
	foreach ( $candidates as $candidate ) {
		$state = wpagent_acf_group_read_state( $candidate['group'] );
		if ( is_wp_error( $state ) ) {
			return $state;
		}
		$states[] = $state;
	}
	$states = wpagent_core_schema_output_list( $states, 50, 'groups' );
	if ( is_wp_error( $states ) ) {
		return $states;
	}
	$result = array(
		'groups' => $states,
		'total' => $total,
		'page' => $page,
		'per_page' => $per_page,
		'total_pages' => $total > 0 ? (int) ceil( $total / $per_page ) : 0,
	);
	$valid = wpagent_acf_group_read_output_bytes( $result, 'field_groups' );
	return is_wp_error( $valid ) ? $valid : $result;
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_get_acf_field_group( $input ) {
	$available = wpagent_acf_group_require_api();
	if ( is_wp_error( $available ) ) {
		return $available;
	}
	$input = is_array( $input ) ? $input : array();
	$group = wpagent_acf_group_get_persistent( is_string( $input['group_key'] ?? null ) ? $input['group_key'] : '' );
	return is_wp_error( $group ) ? $group : wpagent_acf_group_read_state( $group );
}
