<?php
/**
 * Ability: wp-agent/delete-media
 *
 * Ohne force: verschiebt den Medienbeitrag über wp_trash_post() DIREKT in
 * den Papierkorb, statt sich auf wp_delete_attachment( $id, false ) zu
 * verlassen. Genau dieser Aufruf würde im WordPress-Kern trotz force=false
 * meist endgültig löschen: die eingebaute Trash-Weiche in
 * wp_delete_attachment() lautet
 * `! $force_delete && EMPTY_TRASH_DAYS && MEDIA_TRASH && 'trash' !== $post->post_status`
 * (wp-includes/post.php) und verlangt zusätzlich die Konstante MEDIA_TRASH,
 * die in einer WordPress-Installation per Default NICHT gesetzt ist. Ohne
 * diese eigene Absicherung wäre "delete-media ohne force" also in den
 * allermeisten Installationen ein stiller, unumkehrbarer Datenverlust,
 * exakt der Fallstrick, den delete-post.php für Beiträge bereits über einen
 * direkten wp_trash_post()-Aufruf umgeht. wp_trash_post() selbst ist
 * generisch für jeden Post-Type (keine Attachment-Sonderbehandlung) und
 * hängt nicht von MEDIA_TRASH ab.
 *
 * Mit force=true: endgültiges Löschen über wp_delete_attachment( $id, true )
 * (inklusive der Datei auf der Festplatte), unabhängig vom aktuellen Status.
 *
 * @package WPAgentCompanion
 */

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

function wpagent_ability_delete_media(): array {
	return array(
		'label'               => __( 'Medienbeitrag löschen', 'wp-agent-companion' ),
		'description'         => __( 'Ohne force: verschiebt den Medienbeitrag in den Papierkorb (unabhängig von der WordPress-Konstante MEDIA_TRASH). Mit force=true: löscht endgültig inklusive Datei über wp_delete_attachment(). Verifiziert per Re-Read.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'       => 'object',
			'properties' => array(
				'attachment_id' => array( 'type' => 'integer' ),
				'force'         => array(
					'type'        => 'boolean',
					'default'     => false,
					'description' => __( 'true = endgültig löschen (unumkehrbar, inklusive der Datei). false (Default) = in den Papierkorb verschieben.', 'wp-agent-companion' ),
				),
			),
			'required'   => array( 'attachment_id' ),
		),
		'output_schema'       => array(
			'type'       => 'object',
			'properties' => array(
				'attachment_id' => array( 'type' => 'integer' ),
				'forced'        => array( 'type' => 'boolean' ),
				'trashed'       => array( 'type' => 'boolean' ),
				'deleted'       => array( 'type' => 'boolean' ),
				'verified'      => array( 'type' => 'boolean' ),
			),
		),
		'execute_callback'    => 'wpagent_exec_delete_media',
		'permission_callback' => 'wpagent_perm_edit_posts',
		'meta'                => array(
			'show_in_rest' => true,
			'annotations'  => array(
				'readonly'    => false,
				// Der einzige echte Datenverlust-Fall unter den Medien-Abilities:
				// mit force=true unumkehrbar. Bewusst analog zu wp-agent/delete-post
				// und wp-agent/delete-comment als destructive:true markiert, obwohl
				// force=false standardmäßig sicher ist.
				'destructive' => true,
				'idempotent'  => true,
			),
		),
	);
}

/**
 * @param mixed $input
 * @return array|WP_Error
 */
function wpagent_exec_delete_media( $input ) {
	$input         = is_array( $input ) ? $input : array();
	$attachment_id = (int) ( $input['attachment_id'] ?? 0 );
	$force         = rest_sanitize_boolean( $input['force'] ?? false ); // DELETE liefert Booleans als Query-String; !empty("false") wäre fälschlich true.

	$attachment = get_post( $attachment_id );
	if ( ! $attachment || 'attachment' !== $attachment->post_type ) {
		return new WP_Error( 'wpagent_no_media', __( 'Medienbeitrag nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
	}
	if ( ! current_user_can( 'delete_post', $attachment_id ) ) {
		return new WP_Error( 'wpagent_forbidden', __( 'Keine Berechtigung.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}

	if ( $force ) {
		$res = wp_delete_attachment( $attachment_id, true );
		if ( ! $res || is_wp_error( $res ) ) {
			return new WP_Error( 'wpagent_delete_failed', __( 'Endgültiges Löschen fehlgeschlagen.', 'wp-agent-companion' ), array( 'status' => 500 ) );
		}

		$still_exists = (bool) get_post( $attachment_id );

		return array(
			'attachment_id' => $attachment_id,
			'forced'        => true,
			'trashed'       => false,
			'deleted'       => ! $still_exists,
			'verified'      => ! $still_exists,
		);
	}

	if ( 'trash' === $attachment->post_status ) {
		// Idempotent: liegt bereits im Papierkorb, nichts zu tun. Kein
		// erneuter wp_trash_post()-Aufruf: der liefert bei bereits getrashten
		// Beiträgen ohnehin `false` zurück (siehe Kern-Quelle), das würde
		// hier fälschlich wie ein Fehler aussehen.
		return array(
			'attachment_id' => $attachment_id,
			'forced'        => false,
			'trashed'       => true,
			'deleted'       => false,
			'verified'      => true,
		);
	}

	if ( ! wpagent_trash_is_available() ) {
		return wpagent_trash_disabled_error();
	}

	// Bewusst wp_trash_post() DIREKT statt wp_delete_attachment( $id, false ):
	// siehe Datei-Kommentar oben (MEDIA_TRASH-Fallstrick).
	$res = wp_trash_post( $attachment_id );
	if ( ! $res || is_wp_error( $res ) ) {
		return new WP_Error( 'wpagent_trash_failed', __( 'In den Papierkorb verschieben fehlgeschlagen.', 'wp-agent-companion' ), array( 'status' => 500 ) );
	}

	$fresh = get_post( $attachment_id );
	$ok    = ( $fresh instanceof WP_Post && 'trash' === $fresh->post_status );

	return array(
		'attachment_id' => $attachment_id,
		'forced'        => false,
		'trashed'       => $ok,
		'deleted'       => false,
		'verified'      => $ok,
	);
}
