<?php
/**
 * Ability: wp-agent/get-acf-fields
 *
 * Read-only. Liest die einem unterstützten WordPress-Objekt zugeordneten ACF-Felder über die
 * offizielle ACF-API (acf_get_field_groups() + acf_get_fields()), nie über
 * rohe Metadaten. Jedes Feld liefert seinen echten field_-Key zurück, den
 * wp-agent/update-acf-field zwingend braucht, plus Name, Label, Typ und
 * aktuellen Wert. post_id bleibt als abwärtskompatible Beitrags-Kurzform erhalten.
 *
 * @package WPAgentCompanion
 */

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

function wpagent_ability_get_acf_fields(): array {
	return array(
		'label'               => __( 'ACF-Felder lesen', 'wp-agent-companion' ),
		'description'         => __( 'Liest zugeordnete ACF-Werte für Beiträge, Benutzer, Begriffe, Kommentare oder Optionsspeicher in einer sicheren portablen Rohform. Referenzen ohne Leserecht werden redigiert; jeder Wert enthält einen Konflikt-Hash.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'       => 'object',
			'properties' => array(
				'post_id' => array( 'type' => 'integer', 'minimum' => 1 ),
				'object_type' => array( 'type' => 'string', 'enum' => array( 'post', 'user', 'term', 'comment', 'options' ) ),
				'object_id' => array( 'type' => array( 'integer', 'string' ) ),
			),
			'additionalProperties' => false,
		),
		'output_schema'       => array(
			'type'       => 'object',
			'properties' => array(
				'post_id' => array( 'type' => 'integer' ),
				'object_type' => array( 'type' => 'string', 'enum' => array( 'post', 'user', 'term', 'comment', 'options' ) ),
				'object_id' => array( 'type' => array( 'integer', 'string' ) ),
				'acf_object_id' => array( 'type' => 'string' ),
				'fields'  => array(
					'type'  => 'array',
					'items' => array(
						'type'       => 'object',
						'properties' => array(
							'key'   => array(
								'type'        => 'string',
								'description' => __( 'ACF-Field-Key (beginnt mit "field_"), Pflichtparameter für wp-agent/update-acf-field.', 'wp-agent-companion' ),
							),
							'name'  => array( 'type' => 'string' ),
							'label' => array( 'type' => 'string' ),
							'type'  => array( 'type' => 'string' ),
							'state_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
							'writable' => array( 'type' => 'boolean' ),
							'redacted' => array( 'type' => 'integer', 'minimum' => 0 ),
							'unsupported_reason' => array( 'type' => 'string' ),
							'value' => array(
								'type'        => WPAGENT_MIXED_JSON_TYPES,
								'description' => __( 'Portabler unformatierter Feldwert. Objekt-Rückgabeformate werden auf geprüfte IDs reduziert.', 'wp-agent-companion' ),
							),
						),
						'required' => array( 'key', 'name', 'label', 'type', 'state_hash', 'writable', 'redacted', 'unsupported_reason', 'value' ),
						'additionalProperties' => false,
					),
				),
			),
			'required' => array( 'object_type', 'object_id', 'acf_object_id', 'fields' ),
			'additionalProperties' => false,
		),
		'execute_callback'    => 'wpagent_exec_get_acf_fields',
		'permission_callback' => 'wpagent_perm_acf_values',
		'meta'                => array(
			'show_in_rest' => true,
			'annotations'  => array(
				'readonly'    => true,
				'destructive' => false,
				'idempotent'  => true,
			),
		),
	);
}

/**
 * @param mixed $input
 * @return array|WP_Error
 */
function wpagent_exec_get_acf_fields( $input ) {
	$input   = is_array( $input ) ? $input : array();
	$context = wpagent_acf_value_context_from_input( $input );
	if ( is_wp_error( $context ) ) return $context;
	if ( ! wpagent_acf_value_can_edit_context( $context ) ) {
		return new WP_Error( 'wpagent_forbidden', __( 'Keine Berechtigung.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	$assigned = wpagent_acf_value_assigned_fields( $context );
	if ( is_wp_error( $assigned ) ) return $assigned;
	$fields = array();
	foreach ( $assigned as $key => $field ) {
		$state    = wpagent_acf_value_state( $context, $field );
		$json     = wp_json_encode( $state['raw'] );
		$nodes    = 0;
		$bounded  = false !== $json && strlen( $json ) <= WPAGENT_ACF_VALUE_MAX_BYTES && wpagent_acf_value_within_limits( $state['raw'], 0, $nodes );
		$complete = $bounded && wpagent_acf_value_side_effect_state_is_safe( $state['side_effects'] ) && wpagent_acf_value_is_complete( $field, $state['raw'] );
		$export   = $bounded ? wpagent_acf_value_export( $field, $state['raw'] ) : array( 'value' => null, 'redacted' => 1 );
		$writable = $complete && 0 === $export['redacted'] && wpagent_acf_value_can_write( $field, $context );
		$reason   = '';
		if ( ! $bounded ) $reason = __( 'Der bestehende Feldwert überschreitet die sichere Größen- oder Komplexitätsgrenze.', 'wp-agent-companion' );
		elseif ( ! $complete ) $reason = __( 'Der bestehende Feldwert enthält eine unbekannte verschachtelte Struktur.', 'wp-agent-companion' );
		elseif ( $export['redacted'] > 0 ) $reason = __( 'Der bestehende Feldwert enthält Referenzen, die dieses Konto nicht lesen darf.', 'wp-agent-companion' );
		elseif ( ! $writable ) $reason = __( 'Kein verlustfreier sicherer Schreibpfad oder keine erforderliche Berechtigung für diesen Feldtyp.', 'wp-agent-companion' );
		$fields[] = array(
			'key' => $key,
			'name' => (string) $field['name'],
			'label' => (string) ( $field['label'] ?? '' ),
			'type' => (string) ( $field['type'] ?? '' ),
			'state_hash' => $state['state_hash'],
			'writable' => $writable,
			'redacted' => $export['redacted'],
			'unsupported_reason' => $reason,
			'value' => $export['value'],
		);
	}

	$result = array(
		'object_type' => $context['object_type'],
		'object_id' => $context['object_id'],
		'acf_object_id' => (string) $context['acf_object_id'],
		'fields' => $fields,
	);
	if ( 'post' === $context['object_type'] ) $result['post_id'] = $context['post_id'];
	return $result;
}
