<?php
/** Conflict-safe native Pods field update and delete abilities. */

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

/** @return array<string,mixed> */
function wpagent_pods_field_write_properties(): array {
	return array(
		'model_name' => array( 'type' => 'string', 'pattern' => '^[a-z][a-z0-9_]{0,63}$' ),
		'expected_model_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
		'expected_field_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
		'name' => array( 'type' => 'string', 'pattern' => '^[a-z][a-z0-9_]{0,63}$' ),
		'label' => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 200 ),
		'description' => array( 'type' => 'string', 'maxLength' => 2000 ),
		'type' => array( 'type' => 'string', 'enum' => wpagent_pods_supported_field_types() ),
		'required' => array( 'type' => 'boolean' ), 'repeatable' => array( 'type' => 'boolean' ),
		'multiple' => array( 'type' => 'boolean' ), 'weight' => array( 'type' => 'integer', 'minimum' => 0, 'maximum' => 9999 ),
		'relationship_object' => array( 'type' => 'string', 'enum' => array( 'post_type', 'taxonomy', 'user', 'media' ) ),
		'relationship_target' => array( 'type' => 'string', 'maxLength' => 64 ),
		'file_type' => array( 'type' => 'string', 'enum' => array( 'images', 'images-any', 'video', 'video-any', 'audio', 'audio-any', 'text', 'any' ) ),
		'confirm_data_migration' => array( 'type' => 'boolean' ),
	);
}

function wpagent_ability_upsert_pods_field(): array {
	return array(
		'label'       => __( 'Pods-Feld aktualisieren', 'wp-agent-companion' ),
		'description' => __( 'Aktualisiert ein vorhandenes Pods-Feld über die native API nach einer erneuten Prüfung von Modell- und Feld-ID sowie Vollhash unmittelbar vor dem Speichern. Pods bietet kein Compare-and-swap: Fremdänderungen nach dieser Prüfung werden als nicht verifizierbar gemeldet und nicht automatisch überschrieben. Typwechsel mit gespeicherten Werten benötigen eine eigene Bestätigung. Neue Felder werden ohne atomare Pods-Create-only-API nicht angelegt.', 'wp-agent-companion' ),
		'category'    => 'wp-agent',
		'input_schema' => array(
			'type' => 'object', 'properties' => wpagent_pods_field_write_properties(),
			'required' => array( 'model_name', 'expected_model_hash', 'expected_field_hash', 'name' ), 'additionalProperties' => false,
		),
		'output_schema' => array(
			'type' => 'object',
			'properties' => array(
				'model' => wpagent_pods_model_output_schema(), 'field' => wpagent_pods_field_output_schema(),
				'created' => array( 'type' => 'boolean', 'enum' => array( false ) ), 'verified_persistence' => array( 'type' => 'boolean' ),
			),
			'required' => array( 'model', 'field', 'created', 'verified_persistence' ), 'additionalProperties' => false,
		),
		'execute_callback'    => 'wpagent_exec_upsert_pods_field',
		'permission_callback' => 'wpagent_perm_manage_options',
		// A provider can persist part of this write before verification fails.
		// Keep it POST-only so the client never retries a potentially partial mutation.
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => true, 'idempotent' => false ) ),
	);
}

function wpagent_ability_delete_pods_field(): array {
	return array(
		'label'       => __( 'Pods-Feld löschen', 'wp-agent-companion' ),
		'description' => __( 'Prüft die aktuelle Pods-Modell- und Feld-ID sowie den Vollhash. Die endgültige Remote-Löschung ist deaktiviert, weil Pods keine atomare Compare-and-Delete-Prüfung gegen parallele Provideränderungen bietet. Lösche das Feld manuell in der WordPress-Verwaltung.', 'wp-agent-companion' ),
		'category'    => 'wp-agent',
		'input_schema' => array(
			'type' => 'object',
			'properties' => array(
				'model_name' => array( 'type' => 'string', 'pattern' => '^[a-z][a-z0-9_]{0,63}$' ),
				'name' => array( 'type' => 'string', 'pattern' => '^[a-z][a-z0-9_]{0,63}$' ),
				'expected_model_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'expected_field_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'confirm' => array( 'type' => 'boolean' ), 'confirm_data_loss' => array( 'type' => 'boolean' ),
			),
			'required' => array( 'model_name', 'name', 'expected_model_hash', 'expected_field_hash', 'confirm' ),
			'additionalProperties' => false,
		),
		'output_schema' => array(
			'type' => 'object',
			'properties' => array(
				'model' => wpagent_pods_model_output_schema(), 'name' => array( 'type' => 'string' ),
				'deleted' => array( 'type' => 'boolean' ), 'retained_values' => array( 'type' => 'integer' ),
				'removed_relationships' => array( 'type' => 'integer' ),
			),
			'required' => array( 'model', 'name', 'deleted', 'retained_values', 'removed_relationships' ),
			'additionalProperties' => false,
		),
		'execute_callback'    => 'wpagent_exec_delete_pods_field',
		'permission_callback' => 'wpagent_perm_manage_options',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => true, 'idempotent' => false, 'manual_only' => true ) ),
	);
}

/** @return object|false|WP_Error */
function wpagent_pods_find_field( object $pod, string $name ) {
	try {
		$field = pods_api()->load_field( array( 'pod_id' => (int) $pod->get_id(), 'name' => $name, 'bypass_cache' => true ) );
	} catch ( Throwable $error ) {
		return new WP_Error( 'wpagent_pods_field_read_failed', __( 'Das Pods-Feld konnte nicht gelesen werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
	}
	return is_object( $field ) && is_callable( array( $field, 'get_args' ) ) ? $field : false;
}

/** @return object|WP_Error */
function wpagent_pods_get_field_by_identity( object $pod, int $id, string $name ) {
	if ( $id < 1 ) {
		return new WP_Error( 'wpagent_pods_field_identity_conflict', __( 'Die Pods-Feld-ID ist nicht mehr gültig.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	try {
		$field = pods_api()->load_field( array( 'pod_id' => (int) $pod->get_id(), 'id' => $id, 'name' => $name, 'bypass_cache' => true ) );
	} catch ( Throwable $error ) {
		return new WP_Error( 'wpagent_pods_field_read_failed', __( 'Das Pods-Feld konnte nicht erneut gelesen werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
	}
	if ( ! is_object( $field ) || ! is_callable( array( $field, 'get_args' ) ) || ! is_callable( array( $field, 'get_id' ) ) || ! is_callable( array( $field, 'get_parent_id' ) ) ) {
		return new WP_Error( 'wpagent_pods_field_not_found', __( 'Pods-Feld nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
	}
	$args = $field->get_args();
	if ( $id !== (int) $field->get_id() || (int) $pod->get_id() !== (int) $field->get_parent_id() || $name !== (string) ( $args['name'] ?? '' ) ) {
		return new WP_Error( 'wpagent_pods_field_identity_conflict', __( 'Das Pods-Feld stimmt nicht mehr mit seiner gelesenen ID, seinem Modell und seinem Namen überein.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	return $field;
}

/** @return array{pod:object,model:array<string,mixed>,field:object,field_state:array<string,mixed>}|WP_Error */
function wpagent_pods_revalidate_field_target( int $pod_id, string $model_name, int $field_id, string $field_name, string $expected_model_hash, string $expected_field_hash ) {
	$target = wpagent_pods_revalidate_model_target( $pod_id, $model_name, $expected_model_hash );
	if ( is_wp_error( $target ) ) {
		return $target;
	}
	$field = wpagent_pods_get_field_by_identity( $target['pod'], $field_id, $field_name );
	if ( is_wp_error( $field ) ) {
		if ( 'wpagent_pods_field_read_failed' === $field->get_error_code() ) {
			return $field;
		}
		return new WP_Error( 'wpagent_pods_field_conflict', __( 'Das Pods-Feld wurde seit dem Lesen gelöscht oder verändert.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$current = wpagent_pods_field_state( $target['pod'], $field );
	if ( ! preg_match( '/^[a-f0-9]{64}$/', $expected_field_hash ) || ! hash_equals( $current['hash'], $expected_field_hash ) ) {
		return new WP_Error( 'wpagent_pods_field_conflict', __( 'Das Pods-Feld wurde seit dem Lesen verändert oder der Feld-Hash ist ungültig.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $current['hash'] ) );
	}
	return array( 'pod' => $target['pod'], 'model' => $target['state'], 'field' => $field, 'field_state' => $current );
}

/** @return bool|WP_Error */
function wpagent_pods_field_is_absent( int $pod_id, int $field_id, string $name ) {
	try {
		$by_id = pods_api()->load_field( array( 'pod_id' => $pod_id, 'id' => $field_id, 'bypass_cache' => true ) );
		$by_name = pods_api()->load_field( array( 'pod_id' => $pod_id, 'name' => $name, 'bypass_cache' => true ) );
	} catch ( Throwable $error ) {
		return new WP_Error( 'wpagent_pods_field_read_failed', __( 'Der Löschzustand des Pods-Feldes konnte nicht gelesen werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
	}
	return ! is_object( $by_id ) && ! is_object( $by_name );
}

/** @return array<string,mixed>|WP_Error */
function wpagent_pods_validate_field_input( array $input, object $pod, ?array $current = null ) {
	$create = null === $current;
	$name = wpagent_pods_name( $input['name'] ?? null );
	if ( is_wp_error( $name ) ) return $name;
	$state = $create ? array(
		'name' => $name, 'label' => '', 'description' => '', 'type' => '', 'required' => false,
		'repeatable' => false, 'multiple' => false, 'weight' => 0, 'relationship_object' => '',
		'relationship_target' => '', 'file_type' => '',
	) : $current;
	if ( ! $create && $name !== $current['name'] ) {
		return new WP_Error( 'wpagent_pods_field_rename', __( 'Pods-Felder werden aus Sicherheitsgründen nicht umbenannt. Erstelle ein neues Feld und migriere die Werte ausdrücklich.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	foreach ( array( 'label' => 200, 'description' => 2000 ) as $field => $max ) {
		if ( $create || array_key_exists( $field, $input ) ) {
			$text = wpagent_pods_text( $input[ $field ] ?? '', $field, $max, 'description' === $field );
			if ( is_wp_error( $text ) ) return $text;
			$state[ $field ] = $text;
		}
	}
	if ( $create || array_key_exists( 'type', $input ) ) {
		$type = is_string( $input['type'] ?? null ) ? $input['type'] : '';
		if ( ! in_array( $type, wpagent_pods_supported_field_types(), true ) ) {
			return new WP_Error( 'wpagent_pods_field_type', __( 'Dieser Pods-Feldtyp ist im verifizierten Schreibpfad nicht freigegeben.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		$state['type'] = $type;
	}
	foreach ( array( 'required', 'repeatable', 'multiple' ) as $field ) {
		if ( array_key_exists( $field, $input ) ) {
			$value = wpagent_pods_boolean( $input[ $field ], $field );
			if ( is_wp_error( $value ) ) return $value;
			$state[ $field ] = $value;
		}
	}
	if ( array_key_exists( 'weight', $input ) ) {
		$weight = is_int( $input['weight'] ) ? $input['weight'] : ( is_string( $input['weight'] ) && ctype_digit( $input['weight'] ) ? (int) $input['weight'] : -1 );
		if ( $weight < 0 || $weight > 9999 ) {
			return new WP_Error( 'wpagent_pods_field_weight', __( 'weight muss eine ganze Zahl zwischen 0 und 9999 sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		$state['weight'] = $weight;
	}
	$type = $state['type'];
	if ( 'pick' === $type ) {
		$object = array_key_exists( 'relationship_object', $input ) ? (string) $input['relationship_object'] : $state['relationship_object'];
		$target = array_key_exists( 'relationship_target', $input ) ? (string) $input['relationship_target'] : $state['relationship_target'];
		if ( ! in_array( $object, array( 'post_type', 'taxonomy', 'user', 'media' ), true ) ) {
			return new WP_Error( 'wpagent_pods_relationship_object', __( 'relationship_object muss post_type, taxonomy, user oder media sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		if ( 'post_type' === $object && ( sanitize_key( $target ) !== $target || ! post_type_exists( $target ) ) ) {
			return new WP_Error( 'wpagent_pods_relationship_target', __( 'Das Beziehungsziel ist kein registrierter Inhaltstyp.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		if ( 'taxonomy' === $object && ( sanitize_key( $target ) !== $target || ! taxonomy_exists( $target ) ) ) {
			return new WP_Error( 'wpagent_pods_relationship_target', __( 'Das Beziehungsziel ist keine registrierte Taxonomie.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		if ( in_array( $object, array( 'user', 'media' ), true ) && '' !== $target ) {
			return new WP_Error( 'wpagent_pods_relationship_target', __( 'user- und media-Beziehungen dürfen kein relationship_target enthalten.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		$state['relationship_object'] = $object;
		$state['relationship_target'] = $target;
		$state['file_type'] = '';
		if ( $state['repeatable'] ) {
			return new WP_Error( 'wpagent_pods_relationship_repeatable', __( 'Beziehungsfelder verwenden multiple statt repeatable.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
	} elseif ( in_array( $type, array( 'file', 'avatar' ), true ) ) {
		if ( array_key_exists( 'relationship_object', $input ) || array_key_exists( 'relationship_target', $input ) ) {
			return new WP_Error( 'wpagent_pods_file_relationship', __( 'Dateifelder besitzen ein festes Medienziel und akzeptieren keine Beziehungsoptionen.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		$file_type = array_key_exists( 'file_type', $input ) ? (string) $input['file_type'] : ( $state['file_type'] ?: 'images' );
		if ( ! in_array( $file_type, array( 'images', 'images-any', 'video', 'video-any', 'audio', 'audio-any', 'text', 'any' ), true ) ) {
			return new WP_Error( 'wpagent_pods_file_type', __( 'file_type ist nicht freigegeben.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		$state['file_type'] = $file_type;
		$state['relationship_object'] = 'media';
		$state['relationship_target'] = 'attachment';
		if ( $state['repeatable'] ) {
			return new WP_Error( 'wpagent_pods_file_repeatable', __( 'Dateifelder verwenden multiple statt repeatable.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
	} else {
		if ( array_key_exists( 'multiple', $input ) || array_key_exists( 'relationship_object', $input ) || array_key_exists( 'relationship_target', $input ) || array_key_exists( 'file_type', $input ) ) {
			return new WP_Error( 'wpagent_pods_field_options', __( 'Beziehungs-, Datei- und Mehrfachoptionen gelten nur für die passenden Pods-Feldtypen.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		$state['multiple'] = false;
		$state['relationship_object'] = '';
		$state['relationship_target'] = '';
		$state['file_type'] = '';
		if ( 'wysiwyg' === $type && $state['repeatable'] ) {
			return new WP_Error( 'wpagent_pods_wysiwyg_repeatable', __( 'Pods unterstützt wiederholbare TinyMCE-Felder nicht verlässlich.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
	}
	$pod_args = $pod->get_args();
	if ( in_array( $name, array( 'id', 'ID' ), true ) || ( 'post_type' === (string) $pod_args['type'] && taxonomy_exists( $name ) ) ) {
		return new WP_Error( 'wpagent_pods_field_reserved', __( 'Der Feldname kollidiert mit einer internen Pods- oder WordPress-Eigenschaft.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	return $state;
}

/** @return array<string,mixed> */
function wpagent_pods_field_api_params( array $state, object $pod, ?array $snapshot = null ): array {
	$params = null === $snapshot ? array() : $snapshot;
	$params['pod_id'] = (int) $pod->get_id();
	$params['pod'] = (string) $pod->get_name();
	$params['name'] = $state['name'];
	$params['label'] = $state['label'];
	$params['description'] = $state['description'];
	$params['type'] = $state['type'];
	$params['required'] = $state['required'] ? 1 : 0;
	$params['repeatable'] = $state['repeatable'] ? 1 : 0;
	$params['weight'] = $state['weight'];
	if ( 'pick' === $state['type'] ) {
		$params['pick_object'] = $state['relationship_object'];
		$params['pick_val'] = $state['relationship_target'];
		$params['pick_format_type'] = $state['multiple'] ? 'multi' : 'single';
		$params['pick_format_single'] = 'autocomplete';
		$params['pick_format_multi'] = 'autocomplete';
	} elseif ( in_array( $state['type'], array( 'file', 'avatar' ), true ) ) {
		$params[ $state['type'] . '_format_type' ] = $state['multiple'] ? 'multi' : 'single';
		$params[ $state['type'] . '_type' ] = $state['file_type'];
	}
	return $params;
}

function wpagent_pods_field_state_matches( array $actual, array $expected ): bool {
	foreach ( array( 'name', 'label', 'description', 'type', 'required', 'repeatable', 'multiple', 'weight', 'relationship_object', 'relationship_target', 'file_type' ) as $key ) {
		if ( $actual[ $key ] !== $expected[ $key ] ) return false;
	}
	return true;
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_upsert_pods_field( $input ) {
	$available = wpagent_pods_require_api();
	if ( is_wp_error( $available ) ) return $available;
	$permission = wpagent_pods_require_write_permission();
	if ( is_wp_error( $permission ) ) return $permission;
	$input = is_array( $input ) ? $input : array();
	$model_name = is_string( $input['model_name'] ?? null ) ? $input['model_name'] : '';
	$lock = wpagent_pods_acquire_lock( $model_name );
	if ( is_wp_error( $lock ) ) return $lock;
	try {
		$pod = wpagent_pods_get_model( $model_name );
		if ( is_wp_error( $pod ) ) return $pod;
		$model = wpagent_pods_model_state( $pod );
		$expected_model_hash = is_string( $input['expected_model_hash'] ?? null ) ? $input['expected_model_hash'] : '';
		if ( ! preg_match( '/^[a-f0-9]{64}$/', $expected_model_hash ) || ! hash_equals( $model['hash'], $expected_model_hash ) ) {
			return new WP_Error( 'wpagent_pods_conflict', __( 'Das Pods-Modell wurde seit dem Lesen verändert oder der Modell-Hash ist ungültig.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $model['hash'] ) );
		}
		$field_name = wpagent_pods_name( $input['name'] ?? null );
		if ( is_wp_error( $field_name ) ) return $field_name;
		$field = wpagent_pods_find_field( $pod, $field_name );
		if ( is_wp_error( $field ) ) return $field;
		if ( ! $field ) {
			return wpagent_pods_provider_atomicity_unavailable( 'field' );
		}
		$current = wpagent_pods_field_state( $pod, $field );
		$expected_field_hash = is_string( $input['expected_field_hash'] ?? null ) ? $input['expected_field_hash'] : '';
		if ( ! preg_match( '/^[a-f0-9]{64}$/', $expected_field_hash ) || ! hash_equals( $current['hash'], $expected_field_hash ) ) {
			return new WP_Error( 'wpagent_pods_field_conflict', __( 'Das Pods-Feld wurde seit dem Lesen verändert oder expected_field_hash fehlt.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $current['hash'] ) );
		}
		$next = wpagent_pods_validate_field_input( $input, $pod, $current );
		if ( is_wp_error( $next ) ) return $next;
		if ( $current && $current['type'] !== $next['type'] && ( $current['value_count'] > 0 || $current['relationship_count'] > 0 ) && true !== ( $input['confirm_data_migration'] ?? false ) ) {
			return new WP_Error( 'wpagent_pods_field_data_exists', __( 'Der Feldtyp ändert sich, obwohl Werte oder Beziehungen gespeichert sind. Dafür ist confirm_data_migration=true erforderlich.', 'wp-agent-companion' ), array( 'status' => 409, 'value_count' => $current['value_count'], 'relationship_count' => $current['relationship_count'] ) );
		}
		$target = wpagent_pods_revalidate_field_target( (int) $pod->get_id(), $model_name, (int) $field->get_id(), $field_name, $expected_model_hash, $expected_field_hash );
		if ( is_wp_error( $target ) ) return $target;
		$pod = $target['pod'];
		$field = $target['field'];
		$current = $target['field_state'];
		$snapshot = $field->get_args();
		$params = wpagent_pods_field_api_params( $next, $pod, $snapshot );
		$params['id'] = (int) $field->get_id();
		$permission = wpagent_pods_require_write_permission();
		if ( is_wp_error( $permission ) ) return $permission;
		try {
			$saved = pods_api()->save_field( $params );
			if ( is_wp_error( $saved ) || ! $saved ) throw new RuntimeException( 'Pods field save failed.' );
			$fresh_pod = wpagent_pods_get_model_by_identity( (int) $pod->get_id(), $model_name );
			$fresh_field = is_wp_error( $fresh_pod ) ? $fresh_pod : wpagent_pods_get_field_by_identity( $fresh_pod, (int) $field->get_id(), $field_name );
			$result = ! is_wp_error( $fresh_field ) && ! is_wp_error( $fresh_pod ) ? wpagent_pods_field_state( $fresh_pod, $fresh_field ) : null;
			if ( ! is_array( $result ) || ! wpagent_pods_field_state_matches( $result, $next ) ) throw new RuntimeException( 'Pods field read-back failed.' );
			return array( 'model' => wpagent_pods_model_state( $fresh_pod ), 'field' => $result, 'created' => false, 'verified_persistence' => true );
		} catch ( Throwable $error ) {
			unset( $error );
			return new WP_Error( 'wpagent_pods_field_save_unverified', __( 'Das Pods-Feld konnte nicht verifiziert gespeichert werden. Eine automatische Rücksetzung unterbleibt, weil Pods keine atomare Konfliktprüfung für eine sichere Wiederherstellung bereitstellt.', 'wp-agent-companion' ), array( 'status' => 500, 'recovery_required' => true ) );
		}
	} finally {
		wpagent_pods_release_lock( $model_name, $lock );
	}
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_delete_pods_field( $input ) {
	$available = wpagent_pods_require_api();
	if ( is_wp_error( $available ) ) return $available;
	$permission = wpagent_pods_require_write_permission();
	if ( is_wp_error( $permission ) ) return $permission;
	$input = is_array( $input ) ? $input : array();
	if ( true !== ( $input['confirm'] ?? false ) ) {
		return new WP_Error( 'wpagent_confirmation_required', __( 'Zum Löschen des Pods-Feldes ist confirm=true erforderlich.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$model_name = is_string( $input['model_name'] ?? null ) ? $input['model_name'] : '';
	$pod = wpagent_pods_get_model( $model_name );
	if ( is_wp_error( $pod ) ) return $pod;
	$model = wpagent_pods_model_state( $pod );
	$model_hash = is_string( $input['expected_model_hash'] ?? null ) ? $input['expected_model_hash'] : '';
	if ( ! preg_match( '/^[a-f0-9]{64}$/', $model_hash ) || ! hash_equals( $model['hash'], $model_hash ) ) {
		return new WP_Error( 'wpagent_pods_conflict', __( 'Das Pods-Modell wurde seit dem Lesen verändert oder der Modell-Hash ist ungültig.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $model['hash'] ) );
	}
	$name = wpagent_pods_name( $input['name'] ?? null );
	if ( is_wp_error( $name ) ) return $name;
	$field = wpagent_pods_find_field( $pod, $name );
	if ( is_wp_error( $field ) ) return $field;
	if ( ! $field ) return new WP_Error( 'wpagent_pods_field_not_found', __( 'Pods-Feld nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
	$current = wpagent_pods_field_state( $pod, $field );
	$field_hash = is_string( $input['expected_field_hash'] ?? null ) ? $input['expected_field_hash'] : '';
	if ( ! preg_match( '/^[a-f0-9]{64}$/', $field_hash ) || ! hash_equals( $current['hash'], $field_hash ) ) {
		return new WP_Error( 'wpagent_pods_field_conflict', __( 'Das Pods-Feld wurde seit dem Lesen verändert oder der Feld-Hash ist ungültig.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $current['hash'] ) );
	}
	return new WP_Error(
		'wpagent_pods_field_delete_manual_only',
		__( 'Pods-Felddefinitionen werden nicht remote endgültig gelöscht, weil Pods keine atomare Compare-and-Delete-Prüfung gegen parallele Provideränderungen anbietet. Lösche das Feld manuell in der WordPress-Verwaltung.', 'wp-agent-companion' ),
		array( 'status' => 409, 'model_name' => $model['name'], 'name' => $name, 'current_hash' => $current['hash'], 'retained_values' => $current['value_count'], 'relationship_count' => $current['relationship_count'] )
	);
}
