<?php
/**
 * Ability: wp-agent/set-post-status
 *
 * @package WPAgentCompanion
 */

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

function wpagent_ability_set_post_status(): array {
	return array(
		'label'               => __( 'Beitragsstatus setzen', 'wp-agent-companion' ),
		'description'         => __( 'Das ferngesteuerte Ändern eines Beitragsstatus ist nicht verfügbar, weil WordPress dafür keinen atomaren, vollständigen zustandsgebundenen Schreibvorgang bietet. Führe den Vorgang lokal in einer beaufsichtigten Administration aus.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'                 => 'object',
			'properties'           => array(
				'post_id'             => array( 'type' => 'integer', 'minimum' => 1 ),
				'expected_state_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'status'              => array( 'type' => 'string', 'enum' => array( 'publish', 'draft', 'pending', 'private', 'future' ) ),
				'date'                => array( 'type' => 'string', 'maxLength' => 200 ),
			),
			'required'             => array( 'post_id', 'expected_state_hash', 'status' ),
			'additionalProperties' => false,
		),
		'output_schema'       => array(
			'type'                 => 'object',
			'properties'           => array(
				'post_id'             => array( 'type' => 'integer', 'minimum' => 1 ),
				'status'              => array( 'type' => 'string' ),
				'date'                => array( 'type' => 'string' ),
				'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( 'post_id', 'status', 'date', 'verified', 'previous_state_hash', 'state_hash' ),
			'additionalProperties' => false,
		),
		'execute_callback'    => 'wpagent_exec_set_post_status',
		'permission_callback' => 'wpagent_perm_edit_posts',
		'meta'                => array(
			'show_in_rest' => true,
			'annotations'  => array(
				'readonly'    => false,
				'destructive' => false,
				'idempotent'  => false,
				'manual_only' => true,
			),
		),
	);
}

/** @return WP_Error */
function wpagent_set_post_status_manual_only_error(): WP_Error {
	return new WP_Error(
		'wpagent_post_lifecycle_manual_only',
		__( 'Das ferngesteuerte Ändern des Beitragsstatus ist nicht verfügbar. WordPress bietet dafür keinen atomaren, vollständigen zustandsgebundenen Schreibvorgang. Führe den Vorgang lokal in einer beaufsichtigten Administration aus und lies den Beitrag anschließend neu.', 'wp-agent-companion' ),
		array( 'status' => 409, 'manual_only' => true, 'recovery_required' => false )
	);
}

/**
 * @param mixed $input
 * @return WP_Error
 */
function wpagent_exec_set_post_status( $input ) {
	$input   = is_array( $input ) ? $input : array();
	$post_id = (int) ( $input['post_id'] ?? 0 );
	if ( ! current_user_can( 'edit_post', $post_id ) ) {
		return new WP_Error( 'wpagent_forbidden', __( 'Keine Berechtigung.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	$post = get_post( $post_id );
	if ( ! $post ) {
		return new WP_Error( 'wpagent_forbidden', __( 'Keine Berechtigung.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	$status = (string) ( $input['status'] ?? '' );
	if ( ! in_array( $status, array( 'publish', 'draft', 'pending', 'private', 'future' ), true ) ) {
		return new WP_Error( 'wpagent_bad_status', __( 'Ungültiger Beitragsstatus.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	// A status transition needs its stronger capability even though this public
	// endpoint is manual-only. Check it before probing the current state so an
	// unauthorized caller cannot turn a stale hash into a different response.
	$status_cap = wpagent_check_post_status_cap( $post->post_type, $status );
	if ( is_wp_error( $status_cap ) ) {
		return $status_cap;
	}
	$expected_state_hash = is_string( $input['expected_state_hash'] ?? null ) ? strtolower( $input['expected_state_hash'] ) : '';
	if ( 1 !== preg_match( '/^[a-f0-9]{64}$/D', $expected_state_hash ) ) {
		return new WP_Error( 'wpagent_post_expected_hash', __( 'expected_state_hash muss der vollständige state_hash aus get-post sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	clean_post_cache( $post_id );
	wp_cache_delete( $post_id, 'post_meta' );
	$current = get_post( $post_id );
	if ( ! $current instanceof WP_Post ) {
		return new WP_Error( 'wpagent_forbidden', __( 'Keine Berechtigung.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	$current_hash = wpagent_post_state_hash( $current );
	if ( ! hash_equals( $expected_state_hash, $current_hash ) ) {
		return new WP_Error( 'wpagent_post_conflict', __( 'Der Beitrag wurde seit dem Lesen verändert. Lies ihn neu und wiederhole den Vorgang mit dem aktuellen state_hash.', 'wp-agent-companion' ), array( 'status' => 409, 'current_state_hash' => $current_hash ) );
	}
	return wpagent_set_post_status_manual_only_error();
}
