<?php
/**
 * Ability: wp-agent/restore-post
 *
 * Holt einen Beitrag oder eine Seite aus dem Papierkorb zurück. WordPress' Kern
 * wp_untrash_post() liest zwar das Meta-Feld _wp_trash_meta_status, setzt den
 * Status nach dem Restore aber standardmäßig IMMER auf 'draft' (bzw. 'inherit'
 * bei Attachments), weil der Filter, der den vorherigen Status wiederherstellen
 * würde (wp_untrash_post_set_previous_status via 'wp_untrash_post_status'), im
 * WordPress-Kern nicht automatisch verdrahtet ist. Diese Ability liest den
 * vorherigen Status deshalb selbst VOR dem Untrash aus und stellt ihn danach
 * bei Bedarf explizit wieder her.
 *
 * @package WPAgentCompanion
 */

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

function wpagent_ability_restore_post(): array {
	return array(
		'label'               => __( 'Beitrag aus dem Papierkorb wiederherstellen', 'wp-agent-companion' ),
		'description'         => __( 'Holt einen Beitrag oder eine Seite aus dem Papierkorb zurück und stellt dabei den Status wieder her, den er vor dem Trashen hatte (nicht einfach den WordPress-Default "draft"). Verifiziert per Re-Read, dass der Status nicht mehr "trash" ist.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'       => 'object',
			'properties' => array(
				'post_id' => array( 'type' => 'integer' ),
			),
			'required'   => array( 'post_id' ),
		),
		'output_schema'       => array(
			'type'       => 'object',
			'properties' => array(
				'post_id'  => array( 'type' => 'integer' ),
				'status'   => array( 'type' => 'string' ),
				'restored' => array( 'type' => 'boolean' ),
				'verified' => array( 'type' => 'boolean' ),
			),
		),
		'execute_callback'    => 'wpagent_exec_restore_post',
		'permission_callback' => 'wpagent_perm_edit_posts',
		'meta'                => array(
			'show_in_rest' => true,
			'annotations'  => array(
				'readonly'    => false,
				'destructive' => false,
				'idempotent'  => true,
			),
		),
	);
}

/**
 * @param mixed $input
 * @return array|WP_Error
 */
function wpagent_exec_restore_post( $input ) {
	$input   = is_array( $input ) ? $input : array();
	$post_id = (int) ( $input['post_id'] ?? 0 );
	$post    = get_post( $post_id );

	if ( ! $post ) {
		return new WP_Error( 'wpagent_no_post', __( 'Beitrag nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
	}
	if ( ! current_user_can( 'delete_post', $post_id ) ) {
		return new WP_Error( 'wpagent_forbidden', __( 'Keine Berechtigung.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}

	if ( 'trash' !== $post->post_status ) {
		// Idempotent: liegt gar nicht im Papierkorb, nichts zu tun.
		return array(
			'post_id'  => $post_id,
			'status'   => $post->post_status,
			'restored' => false,
			'verified' => true,
		);
	}

	// VOR dem Untrash auslesen: wp_untrash_post() löscht dieses Meta-Feld als
	// Teil des Restores wieder.
	$previous_status = (string) get_post_meta( $post_id, '_wp_trash_meta_status', true );

	// Nur in bekannte, sichere Stati zurückversetzen. 'future' bewusst
	// ausgeschlossen: ein blind wiederhergestelltes future-Datum könnte in der
	// Vergangenheit liegen und würde über WP-Cron sofort veröffentlichen, ohne
	// die Zukunfts-Prüfung von wp-agent/set-post-status zu durchlaufen.
	$restorable    = array( 'draft', 'publish', 'pending', 'private' );
	$target_status = in_array( $previous_status, $restorable, true )
		? $previous_status
		: ( 'attachment' === $post->post_type ? 'inherit' : 'draft' );
	if ( in_array( $target_status, $restorable, true ) ) {
		$status_cap = wpagent_check_post_status_cap( $post->post_type, $target_status );
		if ( is_wp_error( $status_cap ) ) {
			return $status_cap;
		}
	}

	$res = wp_untrash_post( $post_id );
	if ( ! $res || is_wp_error( $res ) ) {
		return new WP_Error( 'wpagent_untrash_failed', __( 'Wiederherstellen fehlgeschlagen.', 'wp-agent-companion' ), array( 'status' => 500 ) );
	}

	$fresh = get_post( $post_id );
	if ( ! $fresh instanceof WP_Post ) {
		return new WP_Error( 'wpagent_restore_unverified', __( 'Der wiederhergestellte Beitrag konnte nicht erneut gelesen werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
	}
	if ( $target_status !== $fresh->post_status ) {
		$updated = wp_update_post( array( 'ID' => $post_id, 'post_status' => $target_status ), true );
		if ( is_wp_error( $updated ) ) {
			return $updated;
		}
		if ( (int) $updated !== $post_id ) {
			return new WP_Error( 'wpagent_restore_status_failed', __( 'Der frühere Beitragsstatus konnte nicht wiederhergestellt werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
		}
	}

	$fresh = get_post( $post_id );
	if ( ! $fresh instanceof WP_Post || $target_status !== $fresh->post_status ) {
		return new WP_Error(
			'wpagent_restore_status_unverified',
			__( 'Der Beitrag wurde aus dem Papierkorb geholt, aber der beabsichtigte frühere Status konnte nicht exakt bestätigt werden.', 'wp-agent-companion' ),
			array( 'status' => 502, 'expected_status' => $target_status, 'actual_status' => $fresh instanceof WP_Post ? $fresh->post_status : '' )
		);
	}

	return array(
		'post_id'  => $post_id,
		'status'   => $fresh->post_status,
		'restored' => true,
		'verified' => true,
	);
}
