<?php
/**
 * Reversible, conflict-protected trashing for reusable blocks.
 *
 * WordPress does not provide an atomic conditional permanent deletion. The
 * compatibility `force` input is retained, but permanent deletion is manual
 * only so a concurrent wp-admin edit cannot be erased by this endpoint.
 */

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

function wpagent_ability_delete_reusable_block(): array {
	return array(
		'label'               => __( 'Wiederverwendbaren Block löschen', 'wp-agent-companion' ),
		'description'         => __( 'Verschiebt einen wiederverwendbaren Block konfliktgeschützt in den Papierkorb. Endgültiges Löschen ist aus Sicherheitsgründen nur manuell in der WordPress-Verwaltung möglich.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'                 => 'object',
			'properties'           => array(
				'block_id'                 => array( 'type' => 'integer', 'minimum' => 1 ),
				'expected_state_hash'      => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'force'                    => array( 'type' => 'boolean', 'default' => false ),
				'confirm_permanent_delete' => array( 'type' => 'boolean', 'default' => false ),
			),
			'required'             => array( 'block_id', 'expected_state_hash' ),
			'additionalProperties' => false,
		),
		'output_schema'       => array(
			'type'                 => 'object',
			'properties'           => array(
				'block_id'            => array( 'type' => 'integer' ),
				'forced'              => array( 'type' => 'boolean' ),
				'trashed'             => array( 'type' => 'boolean' ),
				'deleted'             => array( 'type' => 'boolean' ),
				'verified'            => array( 'type' => 'boolean' ),
				'previous_state_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
			),
			'required'             => array( 'block_id', 'forced', 'trashed', 'deleted', 'verified', 'previous_state_hash' ),
			'additionalProperties' => false,
		),
		'execute_callback'    => 'wpagent_exec_delete_reusable_block',
		'permission_callback' => 'wpagent_perm_edit_posts',
		'meta'                => array(
			'show_in_rest' => true,
			'annotations'  => array(
				'readonly'    => false,
				'destructive' => true,
				// The expected hash becomes stale after trashing. A transparent HTTP
				// retry can otherwise mask the original outcome behind a conflict.
				'idempotent'  => false,
			),
		),
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_delete_reusable_block( $input ) {
	$input    = is_array( $input ) ? $input : array();
	$block_id = absint( $input['block_id'] ?? 0 );
	$block    = wpagent_reusable_block_snapshot( $block_id );
	if ( is_wp_error( $block ) ) {
		return $block;
	}
	if ( ! current_user_can( 'delete_post', $block_id ) ) {
		return new WP_Error( 'wpagent_forbidden', __( 'Keine Berechtigung.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	$expected_hash = wpagent_reusable_block_expected_hash( $input );
	if ( is_wp_error( $expected_hash ) ) {
		return $expected_hash;
	}
	$force = rest_sanitize_boolean( $input['force'] ?? false );
	if ( $force && ! rest_sanitize_boolean( $input['confirm_permanent_delete'] ?? false ) ) {
		return new WP_Error( 'wpagent_reusable_block_delete_confirmation_required', __( 'Endgültiges Löschen erfordert confirm_permanent_delete=true.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$previous_hash = wpagent_reusable_block_state_hash( $block );
	if ( ! hash_equals( $previous_hash, $expected_hash ) ) {
		return wpagent_reusable_block_conflict( $previous_hash );
	}
	if ( $force ) {
		return new WP_Error(
			'wpagent_reusable_block_delete_manual_only',
			__( 'Wiederverwendbare Blöcke werden nicht remote endgültig gelöscht. WordPress kann eine parallele Änderung nicht atomar gegen das endgültige Löschen absichern. Lösche den Block nur manuell in der WordPress-Verwaltung.', 'wp-agent-companion' ),
			array( 'status' => 409, 'block_id' => $block_id, 'previous_state_hash' => $previous_hash )
		);
	}
	$lock = wpagent_reusable_block_acquire_lock( $block_id );
	if ( is_wp_error( $lock ) ) {
		return $lock;
	}
	try {
		return wpagent_exec_delete_reusable_block_locked( $block_id, $expected_hash, $lock );
	} finally {
		wpagent_reusable_block_release_lock( $block_id, $lock );
	}
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_delete_reusable_block_locked( int $block_id, string $expected_hash, string $lock ) {
	$block = wpagent_reusable_block_snapshot( $block_id );
	if ( is_wp_error( $block ) ) {
		return $block;
	}
	if ( ! current_user_can( 'delete_post', $block_id ) ) {
		return new WP_Error( 'wpagent_forbidden', __( 'Keine Berechtigung.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	$previous_hash = wpagent_reusable_block_state_hash( $block );
	if ( ! hash_equals( $previous_hash, $expected_hash ) ) {
		return wpagent_reusable_block_conflict( $previous_hash );
	}
	if ( ! wpagent_reusable_block_refresh_lock( $block_id, $lock ) ) {
		return new WP_Error( 'wpagent_reusable_block_locked', __( 'Die Sperre ging vor dem Schreibvorgang verloren. Es wurde nichts geändert.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$prewrite = wpagent_reusable_block_snapshot( $block_id );
	if ( is_wp_error( $prewrite ) ) {
		return $prewrite;
	}
	$prewrite_hash = wpagent_reusable_block_state_hash( $prewrite );
	if ( ! hash_equals( $previous_hash, $prewrite_hash ) ) {
		return wpagent_reusable_block_conflict( $prewrite_hash );
	}

	if ( 'trash' === $block->post_status ) {
		if ( ! wpagent_reusable_block_lock_is_owned( $block_id, $lock ) ) {
			return wpagent_reusable_block_recovery_required( $block_id, __( 'Die Sperre ging vor der Statusbestätigung verloren. Der Zustand wird nicht automatisch überschrieben.', 'wp-agent-companion' ) );
		}
		return array(
			'block_id'            => $block_id,
			'forced'              => false,
			'trashed'             => true,
			'deleted'             => false,
			'verified'            => true,
			'previous_state_hash' => $previous_hash,
		);
	}
	if ( ! wpagent_trash_is_available() ) {
		return wpagent_trash_disabled_error();
	}
	$trashed = wp_trash_post( $block_id );
	if ( ! wpagent_reusable_block_refresh_lock( $block_id, $lock ) ) {
		return wpagent_reusable_block_recovery_required( $block_id, __( 'Die Sperre ging während des Papierkorb-Vorgangs verloren. Der Zustand wird nicht automatisch überschrieben.', 'wp-agent-companion' ) );
	}
	$fresh   = wpagent_reusable_block_snapshot( $block_id );
	if ( ! wpagent_reusable_block_lock_is_owned( $block_id, $lock ) ) {
		return wpagent_reusable_block_recovery_required( $block_id, __( 'Die Sperre ging während der Papierkorb-Rückleseprüfung verloren. Der Zustand wird nicht automatisch überschrieben.', 'wp-agent-companion' ) );
	}
	if ( ! $trashed || is_wp_error( $trashed ) ) {
		if ( $fresh instanceof WP_Post && 'trash' === $fresh->post_status ) {
			return wpagent_reusable_block_recovery_required( $block_id, __( 'Der Papierkorb-Vorgang meldete keinen Erfolg, obwohl der Block jetzt im Papierkorb liegt. Prüfe den Zustand manuell.', 'wp-agent-companion' ) );
		}
		return new WP_Error( 'wpagent_trash_failed', __( 'In den Papierkorb verschieben fehlgeschlagen.', 'wp-agent-companion' ), array( 'status' => 500 ) );
	}
	if ( $fresh instanceof WP_Post && 'trash' === $fresh->post_status ) {
		return array(
			'block_id'            => $block_id,
			'forced'              => false,
			'trashed'             => true,
			'deleted'             => false,
			'verified'            => true,
			'previous_state_hash' => $previous_hash,
		);
	}
	return wpagent_reusable_block_recovery_required( $block_id, __( 'Der Papierkorb-Vorgang konnte nicht verifiziert werden. Prüfe den Zustand manuell.', 'wp-agent-companion' ) );
}
