<?php
/**
 * Compatibility endpoint for term deletion.
 *
 * WordPress lacks an atomic "delete only while unassigned" primitive. A check
 * followed by a deletion can remove a relationship created by another editor.
 * This endpoint stays registered for a clear compatibility response, but it
 * deliberately never mutates a term.
 */

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

function wpagent_ability_delete_term(): array {
	return array(
		'label'               => __( 'Term löschen', 'wp-agent-companion' ),
		'description'         => __( 'Ist aus Sicherheitsgründen nur ein Kompatibilitäts-Endpunkt: WordPress kann parallele neue Term-Zuordnungen beim endgültigen Löschen nicht atomar ausschließen. Lösche Terme manuell in der WordPress-Verwaltung.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'                 => 'object',
			'properties'           => array(
				'term_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}$' ),
				'confirm_permanent_delete' => array( 'type' => 'boolean' ),
			),
			'required'             => array( 'term_id', 'taxonomy', 'expected_state_hash', 'confirm_permanent_delete' ),
			'additionalProperties' => false,
		),
		'output_schema'       => array(
			'type'                 => 'object',
			'properties'           => array(
				'term_id'             => array( 'type' => 'integer' ),
				'taxonomy'            => array( 'type' => 'string' ),
				'deleted'             => array( 'type' => 'boolean' ),
				'verified'            => array( 'type' => 'boolean' ),
				'previous_state_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
			),
			'required'             => array( 'term_id', 'taxonomy', 'deleted', 'verified', 'previous_state_hash' ),
			'additionalProperties' => false,
		),
		'execute_callback'    => 'wpagent_exec_delete_term',
		'permission_callback' => 'wpagent_perm_edit_posts',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => true, 'idempotent' => false, 'manual_only' => true ) ),
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_delete_term( $input ) {
	$input    = is_array( $input ) ? $input : array();
	$term_id  = absint( $input['term_id'] ?? 0 );
	$taxonomy = (string) ( $input['taxonomy'] ?? '' );
	if ( '' === $taxonomy || ! taxonomy_exists( $taxonomy ) ) {
		return new WP_Error( 'wpagent_bad_taxonomy', sprintf( __( 'Unbekannte Taxonomie "%s".', 'wp-agent-companion' ), $taxonomy ), array( 'status' => 400 ) );
	}
	// Authorization comes before every term read or special-case response. This
	// keeps private taxonomies from becoming an existence oracle for users who
	// only hold the broad ability-level edit_posts capability.
	$tax_object = get_taxonomy( $taxonomy );
	$delete_cap = ( $tax_object && isset( $tax_object->cap->delete_terms ) && '' !== (string) $tax_object->cap->delete_terms ) ? (string) $tax_object->cap->delete_terms : 'do_not_allow';
	if ( ! current_user_can( $delete_cap ) ) {
		return new WP_Error( 'wpagent_forbidden', __( 'Keine Berechtigung, Terme in dieser Taxonomie zu löschen.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	if ( 'product_shipping_class' === $taxonomy ) {
		return new WP_Error( 'wpagent_wc_shipping_class_requires_specialized_delete', __( 'WooCommerce-Versandklassen können nicht remote gelöscht werden. WordPress kann parallele Fremdzuweisungen nicht race-frei verifizieren. Entferne eine leere Versandklasse nur manuell in der WooCommerce-Verwaltung.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$term = wpagent_term_snapshot( $term_id, $taxonomy );
	if ( is_wp_error( $term ) ) {
		return $term;
	}
	$expected_hash = wpagent_term_expected_hash( $input );
	if ( is_wp_error( $expected_hash ) ) {
		return $expected_hash;
	}
	if ( ! rest_sanitize_boolean( $input['confirm_permanent_delete'] ?? false ) ) {
		return new WP_Error( 'wpagent_term_delete_confirmation_required', __( 'Endgültiges Löschen erfordert confirm_permanent_delete=true.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$previous_hash = wpagent_term_state_hash( $term );
	if ( ! hash_equals( $previous_hash, $expected_hash ) ) {
		return wpagent_term_conflict( $previous_hash );
	}
	return new WP_Error(
		'wpagent_term_delete_manual_only',
		__( 'Terme werden nicht remote endgültig gelöscht. WordPress kann eine parallele neue Zuordnung nicht atomar gegen den Löschvorgang absichern. Lösche den Term nur manuell in der WordPress-Verwaltung.', 'wp-agent-companion' ),
		array(
			'status'              => 409,
			'term_id'             => $term_id,
			'taxonomy'            => $taxonomy,
			'previous_state_hash' => $previous_hash,
		)
	);
}
