<?php
/** Conflict-protected, bounded assignment of terms to one post and taxonomy. */

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

function wpagent_ability_set_post_terms(): array {
	return array(
		'label'               => __( 'Term-Zuordnung prüfen', 'wp-agent-companion' ),
		'description'         => __( 'Nimmt keine Remote-Änderung an Beitrags-Termzuordnungen vor, weil WordPress keine atomare Compare-and-Write-Operation gegen parallele Verwaltungsänderungen bereitstellt. Speichere die Zuordnung im WordPress-Backend.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'                 => 'object',
			'properties'           => array(
				'post_id'             => array( 'type' => 'integer', 'minimum' => 1 ),
				'taxonomy'            => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 32, 'pattern' => '^[a-z0-9_-]+$' ),
				'expected_state_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'terms'               => array(
					'type'     => 'array',
					'maxItems' => 100,
					'items'    => array( 'type' => array( 'integer', 'string' ), 'maxLength' => 200 ),
				),
				'append'              => array( 'type' => 'boolean', 'default' => false ),
			),
			'required'             => array( 'post_id', 'taxonomy', 'expected_state_hash', 'terms' ),
			'additionalProperties' => false,
		),
		'output_schema'       => array( 'type' => 'object', 'properties' => array(), 'additionalProperties' => false ),
		'execute_callback'    => 'wpagent_exec_set_post_terms',
		'permission_callback' => 'wpagent_perm_edit_posts',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => false, 'manual_only' => true ) ),
	);
}

/** @return WP_Error */
function wpagent_post_terms_manual_update_only(): WP_Error {
	return new WP_Error(
		'wpagent_post_terms_manual_write_required',
		__( 'WordPress stellt für Beitrags-Termzuordnungen keine nachweisbar atomare Compare-and-Write-Operation bereit. WPAgently ändert diese Zuordnung deshalb nicht. Speichere die Zuordnung im WordPress-Backend und lies den Beitrag anschließend neu.', 'wp-agent-companion' ),
		array( 'status' => 409, 'manual_only' => true )
	);
}

/** @return WP_Error */
function wpagent_wc_shipping_class_product_assignment_only(): WP_Error {
	return new WP_Error(
		'wpagent_wc_shipping_class_requires_product_ability',
		__( 'WooCommerce-Versandklassen müssen über die Produkt-Ability gesetzt werden. Sie nutzt die native WooCommerce-Produkt-API und prüft Sperre, Konfliktzustand und Read-back. Der generische Term-Pfad nimmt keine Änderung vor.', 'wp-agent-companion' ),
		array( 'status' => 409, 'manual_only' => true )
	);
}

/** @return WP_Error */
function wpagent_exec_set_post_terms( $input ) {
	// A preflight snapshot or local lock cannot make wp_set_object_terms()
	// conditional against concurrent wp-admin, REST, CLI, or provider writers.
	if ( is_array( $input ) && 'product_shipping_class' === ( $input['taxonomy'] ?? '' ) ) {
		return wpagent_wc_shipping_class_product_assignment_only();
	}
	return wpagent_post_terms_manual_update_only();
}
