<?php
/**
 * Ability: wp-agent/delete-comment
 *
 * WordPress offers no conditional, provider-atomic permanent comment delete.
 * Remote permanent deletion is therefore deliberately unavailable. The only
 * mutation this legacy ability retains is the reversible, single-comment
 * trash transition, guarded by a full state hash, an option lock and native
 * readback. Native wp-admin edits cannot acquire the WPAgently lock, so the
 * state hash is re-read after acquiring it and immediately before mutation.
 *
 * @package WPAgentCompanion
 */

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

if ( ! function_exists( 'wpagent_perm_moderate_comments' ) ) {
	/** @param mixed $input */
	function wpagent_perm_moderate_comments( $input = null ): bool {
		return current_user_can( 'moderate_comments' );
	}
}

function wpagent_ability_delete_comment(): array {
	return array(
		'label'               => __( 'Kommentar in den Papierkorb verschieben', 'wp-agent-companion' ),
		'description'         => __( 'Verschiebt einen regulären Kommentar konfliktgeschützt in den Papierkorb. Endgültiges Remote-Löschen ist nicht verfügbar, weil WordPress dafür keine atomare Zustandsprüfung anbietet.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'                 => 'object',
			'properties'           => array(
				'comment_id'          => array( 'type' => 'integer', 'minimum' => 1 ),
				'expected_state_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				// Retained only to return a deterministic, fail-closed response to
				// clients that used the historical permanent-delete request.
				'force'               => array( 'type' => 'boolean', 'default' => false ),
			),
			'required'             => array( 'comment_id', 'expected_state_hash' ),
			'additionalProperties' => false,
		),
		'output_schema'       => array(
			'type'                 => 'object',
			'properties'           => array(
				'comment_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}$' ),
				'state_hash'          => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
			),
			'required'             => array( 'comment_id', 'forced', 'trashed', 'deleted', 'verified', 'previous_state_hash', 'state_hash' ),
			'additionalProperties' => false,
		),
		'execute_callback'    => 'wpagent_exec_delete_comment',
		'permission_callback' => 'wpagent_perm_moderate_comments',
		'meta'                => array(
			'show_in_rest' => true,
			'annotations'  => array(
				'readonly'    => false,
				'destructive' => false,
				// A failed readback can hide a completed trash transition. POST
				// avoids a transparent retry that would mask that first outcome.
				'idempotent'  => false,
			),
		),
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_delete_comment( $input ) {
	$input = is_array( $input ) ? $input : array();
	if ( ! wpagent_core_mutator_is_strict_integer( $input['comment_id'] ?? null ) || (int) $input['comment_id'] < 1 ) {
		return new WP_Error( 'wpagent_bad_comment_id', __( 'comment_id muss eine positive Ganzzahl sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$comment_id = (int) $input['comment_id'];
	if ( ! current_user_can( 'edit_comment', $comment_id ) ) {
		return new WP_Error( 'wpagent_forbidden', __( 'Keine Berechtigung.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}

	if ( rest_sanitize_boolean( $input['force'] ?? false ) ) {
		return new WP_Error(
			'wpagent_comment_permanent_delete_unsupported',
			__( 'Endgültiges Remote-Löschen von Kommentaren ist nicht verfügbar. Verschiebe den Kommentar mit force=false in den Papierkorb und lösche ihn bei Bedarf manuell in WordPress.', 'wp-agent-companion' ),
			array( 'status' => 409 )
		);
	}
	$expected_hash = wpagent_comment_expected_hash( $input );
	if ( is_wp_error( $expected_hash ) ) {
		return $expected_hash;
	}
	$comment = wpagent_comment_snapshot( $comment_id );
	if ( is_wp_error( $comment ) ) {
		return new WP_Error( 'wpagent_forbidden', __( 'Keine Berechtigung.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	if ( ! wpagent_comment_is_safe_trash_target( $comment ) ) {
		return new WP_Error( 'wpagent_comment_type_unsupported', __( 'Nur reguläre Kommentare werden remote in den Papierkorb verschoben. Pingbacks, Trackbacks und Notizen bleiben unverändert.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	if ( ! wpagent_trash_is_available() ) {
		return new WP_Error( 'wpagent_comment_trash_disabled', __( 'Der Kommentar-Papierkorb ist deaktiviert. WPAgently führt dann kein Remote-Löschen aus, weil dieses endgültig wäre.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}

	$blog_id = (int) get_current_blog_id();
	$lock = wpagent_comment_acquire_lock( $comment_id );
	if ( is_wp_error( $lock ) ) {
		return $lock;
	}
	try {
		return wpagent_exec_delete_comment_locked( $comment_id, $expected_hash, $blog_id, $lock );
	} finally {
		wpagent_comment_release_lock_for_blog( $comment_id, $blog_id, $lock );
	}
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_delete_comment_locked( int $comment_id, string $expected_hash, int $blog_id, string $lock ) {
	if ( $blog_id !== (int) get_current_blog_id() || ! wpagent_comment_refresh_lock( $comment_id, $lock ) || ! wpagent_comment_lock_is_owned( $comment_id, $lock ) ) {
		return new WP_Error( 'wpagent_comment_locked', __( 'Die Sperre ging vor dem Papierkorb-Vorgang verloren. Es wurde nichts geändert.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$comment = wpagent_comment_snapshot( $comment_id );
	if ( is_wp_error( $comment ) ) {
		return new WP_Error( 'wpagent_forbidden', __( 'Keine Berechtigung.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	if ( ! current_user_can( 'edit_comment', $comment_id ) ) {
		return new WP_Error( 'wpagent_forbidden', __( 'Keine Berechtigung.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	if ( ! wpagent_comment_is_safe_trash_target( $comment ) ) {
		return new WP_Error( 'wpagent_comment_type_unsupported', __( 'Nur reguläre Kommentare werden remote in den Papierkorb verschoben. Pingbacks, Trackbacks und Notizen bleiben unverändert.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$previous_hash = wpagent_comment_state_hash( $comment );
	if ( ! hash_equals( $previous_hash, $expected_hash ) ) {
		return wpagent_comment_conflict( $previous_hash );
	}

	// A native wp-admin edit cannot observe this lock. Re-read after the last
	// lock renewal so that any earlier independent write is a conflict, not a
	// blind status overwrite.
	if ( $blog_id !== (int) get_current_blog_id() || ! wpagent_comment_refresh_lock( $comment_id, $lock ) || ! wpagent_comment_lock_is_owned( $comment_id, $lock ) ) {
		return new WP_Error( 'wpagent_comment_locked', __( 'Die Sperre ging vor der Zustandsprüfung verloren. Es wurde nichts geändert.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$prewrite = wpagent_comment_snapshot( $comment_id );
	if ( is_wp_error( $prewrite ) ) {
		return new WP_Error( 'wpagent_forbidden', __( 'Keine Berechtigung.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	$prewrite_hash = wpagent_comment_state_hash( $prewrite );
	if ( ! hash_equals( $previous_hash, $prewrite_hash ) ) {
		return wpagent_comment_conflict( $prewrite_hash );
	}
	if ( 'trash' === wp_get_comment_status( $prewrite ) ) {
		return array(
			'comment_id'          => $comment_id,
			'forced'              => false,
			'trashed'             => true,
			'deleted'             => false,
			'verified'            => true,
			'previous_state_hash' => $previous_hash,
			'state_hash'          => $prewrite_hash,
		);
	}

	$trashed = wp_trash_comment( $comment_id );
	if ( $blog_id !== (int) get_current_blog_id() || ! wpagent_comment_refresh_lock( $comment_id, $lock ) || ! wpagent_comment_lock_is_owned( $comment_id, $lock ) ) {
		return wpagent_comment_recovery_required( $comment_id, __( 'Die Sperre ging während des Papierkorb-Vorgangs verloren. Der Zustand wird nicht automatisch überschrieben.', 'wp-agent-companion' ) );
	}
	$fresh = wpagent_comment_snapshot( $comment_id );
	if ( is_wp_error( $fresh ) ) {
		return wpagent_comment_recovery_required( $comment_id, __( 'Der Papierkorb-Vorgang kann nicht sicher zurückgelesen werden. Prüfe den Zustand manuell.', 'wp-agent-companion' ) );
	}
	$fresh_hash = wpagent_comment_state_hash( $fresh );
	if ( $blog_id !== (int) get_current_blog_id() || ! current_user_can( 'edit_comment', $comment_id ) || ! wpagent_comment_lock_is_owned( $comment_id, $lock ) ) {
		return wpagent_comment_recovery_required( $comment_id, __( 'Berechtigung oder Sperre ging während der Rückleseprüfung verloren. Prüfe den Zustand manuell.', 'wp-agent-companion' ), $fresh_hash );
	}
	if ( $trashed && 'trash' === wp_get_comment_status( $fresh ) ) {
		return array(
			'comment_id'          => $comment_id,
			'forced'              => false,
			'trashed'             => true,
			'deleted'             => false,
			'verified'            => true,
			'previous_state_hash' => $previous_hash,
			'state_hash'          => $fresh_hash,
		);
	}
	if ( hash_equals( $previous_hash, $fresh_hash ) ) {
		return new WP_Error( 'wpagent_trash_failed', __( 'In den Papierkorb verschieben fehlgeschlagen.', 'wp-agent-companion' ), array( 'status' => 500 ) );
	}
	return wpagent_comment_recovery_required( $comment_id, __( 'Der Papierkorb-Vorgang hinterließ einen unerwarteten Zustand. Wiederhole ihn nicht automatisch und prüfe den aktuellen Zustand manuell.', 'wp-agent-companion' ), $fresh_hash );
}
