<?php
/** Ability: wp-agent/set-seopress-post-redirection. */

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

function wpagent_ability_set_seopress_post_redirection(): array {
	return array(
		'label'               => __( 'SEOPress-Beitragsweiterleitung setzen', 'wp-agent-companion' ),
		'description'         => __( 'Setzt ausschließlich eine einfache lokale SEOPress-Free-Weiterleitung eines veröffentlichten Beitrags über die native SEOPress-REST-Schnittstelle. Konflikte, Zyklen und unbestätigte Providerzustände werden abgelehnt.', '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}$' ),
				'destination'         => array( 'type' => 'string', 'maxLength' => 4096 ),
				'http_code'           => array( 'type' => 'integer', 'enum' => array( 301, 302, 307 ) ),
				'enabled'             => array( 'type' => 'boolean' ),
			),
			'required'             => array( 'post_id', 'expected_state_hash' ),
			'additionalProperties' => false,
		),
		'output_schema'       => array(
			'type'                 => 'object',
			'properties'           => array(
				'redirection' => wpagent_seopress_post_redirection_schema(),
				'verified'    => array( 'type' => 'boolean' ),
			),
			'required'             => array( 'redirection', 'verified' ),
			'additionalProperties' => false,
		),
		'execute_callback'    => 'wpagent_exec_set_seopress_post_redirection',
		'permission_callback' => 'wpagent_perm_edit_seopress_post_redirection',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => true, 'idempotent' => false ) ),
	);
}

/** @return true|WP_Error */
function wpagent_seopress_post_redirection_expected_hash( $value, string $actual ) {
	$expected = is_string( $value ) ? strtolower( $value ) : '';
	if ( ! preg_match( '/^[a-f0-9]{64}$/D', $expected ) ) {
		return new WP_Error( 'wpagent_seopress_redirection_expected_hash', __( 'expected_state_hash muss ein SHA-256-Hash mit 64 Kleinbuchstaben und Ziffern sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	return hash_equals( $actual, $expected )
		? true
		: new WP_Error( 'wpagent_seopress_redirection_conflict', __( 'Die SEOPress-Weiterleitung wurde seit dem Lesen verändert. Bitte erneut lesen.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $actual ) );
}

/** @return array<string,mixed>|WP_Error */
function wpagent_seopress_post_redirection_next( array $input, array $current ) {
	$allowed = array( 'post_id', 'expected_state_hash', 'destination', 'http_code', 'enabled' );
	foreach ( array_keys( $input ) as $key ) {
		if ( ! in_array( $key, $allowed, true ) ) {
			return new WP_Error( 'wpagent_seopress_redirection_input_invalid', __( 'Die SEOPress-Weiterleitung enthält ein nicht erlaubtes Eingabefeld.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
	}
	if ( ! array_key_exists( 'destination', $input ) && ! array_key_exists( 'http_code', $input ) && ! array_key_exists( 'enabled', $input ) ) {
		return new WP_Error( 'wpagent_seopress_redirection_no_changes', __( 'Es wurde keine Änderung an der SEOPress-Weiterleitung übergeben.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$destination = $current['destination'];
	if ( array_key_exists( 'destination', $input ) ) {
		$destination = wpagent_seopress_post_redirection_validate_destination( $input['destination'], (string) $current['source'] );
		if ( is_wp_error( $destination ) ) {
			return $destination;
		}
	}
	$http_code = $current['http_code'];
	if ( array_key_exists( 'http_code', $input ) ) {
		if ( ! is_int( $input['http_code'] ) || ! in_array( $input['http_code'], array( 301, 302, 307 ), true ) ) {
			return new WP_Error( 'wpagent_seopress_redirection_http_code_invalid', __( 'http_code muss 301, 302 oder 307 sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		$http_code = $input['http_code'];
	}
	$enabled = $current['enabled'];
	if ( array_key_exists( 'enabled', $input ) ) {
		if ( ! is_bool( $input['enabled'] ) ) {
			return new WP_Error( 'wpagent_seopress_redirection_enabled_invalid', __( 'enabled muss ein boolescher Wert sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		$enabled = $input['enabled'];
	}
	if ( $enabled && '' === $destination ) {
		return new WP_Error( 'wpagent_seopress_redirection_destination_required', __( 'Eine aktivierte SEOPress-Weiterleitung benötigt ein lokales Ziel.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	return array(
		'post_id'      => (int) $current['post_id'],
		'provider'     => 'seopress',
		'source'       => (string) $current['source'],
		'destination'  => $destination,
		'http_code'    => $http_code,
		'enabled'      => $enabled,
		'login_status' => 'both',
	);
}

/** @param array<string,mixed> $left @param array<string,mixed> $right */
function wpagent_seopress_post_redirection_matches( array $left, array $right ): bool {
	foreach ( array( 'post_id', 'provider', 'source', 'destination', 'http_code', 'enabled', 'login_status' ) as $key ) {
		if ( ( $left[ $key ] ?? null ) !== ( $right[ $key ] ?? null ) ) {
			return false;
		}
	}
	return true;
}

/** @param array<int,array{meta_id:int,meta_key:string,meta_value:string}> $snapshot @return array<string,array<int,array{meta_id:int,meta_key:string,meta_value:string}>> */
function wpagent_seopress_post_redirection_snapshot_by_key( array $snapshot ): array {
	$by_key = array();
	foreach ( $snapshot as $row ) {
		$key = isset( $row['meta_key'] ) ? (string) $row['meta_key'] : '';
		if ( '' !== $key ) {
			$by_key[ $key ][] = $row;
		}
	}
	return $by_key;
}

/** @param array<int,array{meta_id:int,meta_key:string,meta_value:string}> $left @param array<int,array{meta_id:int,meta_key:string,meta_value:string}> $right */
function wpagent_seopress_post_redirection_snapshots_equal( array $left, array $right ): bool {
	return wp_json_encode( $left ) === wp_json_encode( $right );
}

/** @param array<int,array{meta_id:int,meta_key:string,meta_value:string}> $before @param array<int,array{meta_id:int,meta_key:string,meta_value:string}> $attempt */
function wpagent_seopress_post_redirection_attempt_matches_candidate( array $before, array $attempt, array $candidate ): bool {
	$before_by_key  = wpagent_seopress_post_redirection_snapshot_by_key( $before );
	$attempt_by_key = wpagent_seopress_post_redirection_snapshot_by_key( $attempt );
	$known_keys     = array_fill_keys( wpagent_seopress_post_redirection_meta_keys(), true );
	$expected       = array(
		'_seopress_redirections_enabled' => $candidate['enabled'] ? 'yes' : null,
		'_seopress_redirections_type'    => (string) $candidate['http_code'],
		'_seopress_redirections_value'   => '' === $candidate['destination'] ? null : (string) $candidate['destination'],
	);
	foreach ( array_unique( array_merge( array_keys( $before_by_key ), array_keys( $attempt_by_key ), array_keys( $expected ) ) ) as $key ) {
		$before_rows  = $before_by_key[ $key ] ?? array();
		$attempt_rows = $attempt_by_key[ $key ] ?? array();
		if ( ! isset( $known_keys[ $key ] ) || ! array_key_exists( $key, $expected ) ) {
			if ( ! wpagent_seopress_post_redirection_snapshots_equal( $before_rows, $attempt_rows ) ) {
				return false;
			}
			continue;
		}
		if ( null === $expected[ $key ] ) {
			if ( array() !== $attempt_rows ) {
				return false;
			}
			continue;
		}
		if ( 1 !== count( $attempt_rows ) || (string) $expected[ $key ] !== (string) ( $attempt_rows[0]['meta_value'] ?? null ) ) {
			return false;
		}
	}
	return true;
}

/** @return WP_Error */
function wpagent_seopress_post_redirection_recovery_required_error( string $message ): WP_Error {
	return new WP_Error( 'wpagent_seopress_redirection_recovery_required', $message, array( 'status' => 500, 'recovery_required' => true ) );
}

/** @return string|WP_Error */
function wpagent_seopress_post_redirection_graph_meta_value( array $meta, string $key, string $default = '' ) {
	$values = $meta[ $key ] ?? array();
	if ( ! is_array( $values ) || count( $values ) > 1 ) {
		return new WP_Error( 'wpagent_seopress_redirection_provider_state_invalid', __( 'SEOPress enthält doppelte oder ungültige Weiterleitungswerte. Der Zyklenschutz bleibt geschlossen.', 'wp-agent-companion' ), array( 'status' => 409, 'meta_key' => $key ) );
	}
	if ( array() === $values ) {
		return $default;
	}
	return is_string( $values[0] )
		? $values[0]
		: new WP_Error( 'wpagent_seopress_redirection_provider_state_invalid', __( 'SEOPress enthält einen nicht skalaren Weiterleitungswert. Der Zyklenschutz bleibt geschlossen.', 'wp-agent-companion' ), array( 'status' => 409, 'meta_key' => $key ) );
}

/** @return array{source:string,destination:string}|WP_Error */
function wpagent_seopress_post_redirection_graph_edge( WP_Post $post, array $meta ) {
	$type = get_post_type_object( $post->post_type );
	if ( ! $type instanceof WP_Post_Type || ! is_post_type_viewable( $type ) || 'publish' !== $post->post_status ) {
		return new WP_Error( 'wpagent_seopress_redirection_provider_state_invalid', __( 'SEOPress enthält eine aktive Weiterleitung für keinen öffentlichen veröffentlichten Beitrag.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	foreach ( $meta as $key => $values ) {
		if ( str_starts_with( (string) $key, '_seopress_redirections_' ) && ( ! is_array( $values ) || count( $values ) > 1 ) ) {
			return new WP_Error( 'wpagent_seopress_redirection_provider_state_invalid', __( 'SEOPress enthält doppelte oder ungültige Weiterleitungswerte. Der Zyklenschutz bleibt geschlossen.', 'wp-agent-companion' ), array( 'status' => 409, 'meta_key' => $key ) );
		}
	}
	$enabled = wpagent_seopress_post_redirection_graph_meta_value( $meta, '_seopress_redirections_enabled' );
	$type    = wpagent_seopress_post_redirection_graph_meta_value( $meta, '_seopress_redirections_type', '301' );
	$value   = wpagent_seopress_post_redirection_graph_meta_value( $meta, '_seopress_redirections_value' );
	$login   = wpagent_seopress_post_redirection_graph_meta_value( $meta, '_seopress_redirections_logged_status', 'both' );
	$regex   = wpagent_seopress_post_redirection_graph_meta_value( $meta, '_seopress_redirections_enabled_regex' );
	$params  = wpagent_seopress_post_redirection_graph_meta_value( $meta, '_seopress_redirections_param', 'exact_match' );
	if ( is_wp_error( $enabled ) || is_wp_error( $type ) || is_wp_error( $value ) || is_wp_error( $login ) || is_wp_error( $regex ) || is_wp_error( $params ) ) {
		return new WP_Error( 'wpagent_seopress_redirection_provider_state_invalid', __( 'SEOPress enthält einen nicht bestätigten Weiterleitungszustand. Der Zyklenschutz bleibt geschlossen.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	if ( 'yes' !== $enabled || ! in_array( (int) $type, array( 301, 302, 307 ), true ) || 'both' !== $login || '' !== $regex || ! in_array( $params, array( '', 'exact_match' ), true ) ) {
		return new WP_Error( 'wpagent_seopress_redirection_provider_state_invalid', __( 'SEOPress enthält eine nicht unterstützte aktive Weiterleitungsregel. Der Zyklenschutz bleibt geschlossen.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$source = get_permalink( $post );
	if ( ! is_string( $source ) || '' === $source ) {
		return new WP_Error( 'wpagent_seopress_redirection_provider_state_invalid', __( 'SEOPress enthält eine Weiterleitung ohne sichere lokale Quelle.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$destination = wpagent_seopress_post_redirection_validate_destination( $value, $source );
	$source_path = wpagent_seopress_post_redirection_source_path( $source );
	$destination_path = is_wp_error( $destination ) ? $destination : wpagent_seopress_post_redirection_source_path( $destination );
	if ( is_wp_error( $destination ) || is_wp_error( $source_path ) || is_wp_error( $destination_path ) ) {
		return new WP_Error( 'wpagent_seopress_redirection_provider_state_invalid', __( 'SEOPress enthält eine Weiterleitung außerhalb des sicheren lokalen Graphen.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	return array( 'source' => $source_path, 'destination' => $destination_path );
}

/** @return array<int,array<string,array<int,string>>>|WP_Error */
function wpagent_seopress_post_redirection_graph_metadata( array $post_ids ) {
	global $wpdb;
	$post_ids = array_values( array_unique( array_filter( array_map( 'absint', $post_ids ) ) ) );
	if ( array() === $post_ids ) {
		return array();
	}
	$keys         = wpagent_seopress_post_redirection_meta_keys();
	$id_format    = implode( ', ', array_fill( 0, count( $post_ids ), '%d' ) );
	$key_format   = implode( ', ', array_fill( 0, count( $keys ), '%s' ) );
	$query        = "SELECT post_id, meta_key, meta_value FROM {$wpdb->postmeta} WHERE post_id IN ({$id_format}) AND meta_key IN ({$key_format}) ORDER BY post_id ASC, meta_id ASC LIMIT %d";
	$prepared     = $wpdb->prepare( $query, ...array_merge( $post_ids, $keys, array( WPAGENT_SEOPRESS_POST_REDIRECTION_MAX_GRAPH_ROWS ) ) );
	$rows         = $wpdb->get_results( $prepared, ARRAY_A );
	if ( ! is_array( $rows ) ) {
		return new WP_Error( 'wpagent_seopress_redirection_provider_state_invalid', __( 'Der SEOPress-Weiterleitungsgraph konnte nicht sicher geladen werden.', 'wp-agent-companion' ), array( 'status' => 502 ) );
	}
	if ( count( $rows ) >= WPAGENT_SEOPRESS_POST_REDIRECTION_MAX_GRAPH_ROWS ) {
		return new WP_Error( 'wpagent_seopress_redirection_cycle_limit', __( 'Der SEOPress-Weiterleitungsgraph enthält zu viele Werte für eine vollständige sichere Prüfung.', 'wp-agent-companion' ), array( 'status' => 413 ) );
	}
	$allowed_ids = array_fill_keys( $post_ids, true );
	$allowed_keys = array_fill_keys( $keys, true );
	$metadata    = array();
	$total_bytes = 0;
	foreach ( $rows as $row ) {
		$id    = absint( $row['post_id'] ?? 0 );
		$key   = isset( $row['meta_key'] ) ? (string) $row['meta_key'] : '';
		$value = isset( $row['meta_value'] ) ? (string) $row['meta_value'] : null;
		if ( ! isset( $allowed_ids[ $id ], $allowed_keys[ $key ] ) || ! is_string( $value ) ) {
			return new WP_Error( 'wpagent_seopress_redirection_provider_state_invalid', __( 'Der SEOPress-Weiterleitungsgraph enthält ungültige Metadaten.', 'wp-agent-companion' ), array( 'status' => 502 ) );
		}
		$value_bytes = strlen( $value );
		$total_bytes += strlen( $key ) + $value_bytes;
		if ( $value_bytes > WPAGENT_SEOPRESS_POST_REDIRECTION_MAX_RAW_VALUE_BYTES || $total_bytes > WPAGENT_SEOPRESS_POST_REDIRECTION_MAX_GRAPH_BYTES ) {
			return new WP_Error( 'wpagent_seopress_redirection_cycle_limit', __( 'Der SEOPress-Weiterleitungsgraph ist für eine vollständige sichere Prüfung zu groß.', 'wp-agent-companion' ), array( 'status' => 413 ) );
		}
		$metadata[ $id ][ $key ][] = $value;
	}
	return $metadata;
}

/** @return array<string,string>|WP_Error */
function wpagent_seopress_post_redirection_active_edges( int $updated_post_id, array $candidate ) {
	$post_types = array_values(
		array_map(
			static fn( WP_Post_Type $type ): string => $type->name,
			array_filter( get_post_types( array(), 'objects' ), static fn( WP_Post_Type $type ): bool => is_post_type_viewable( $type ) )
		)
	);
	$query      = new WP_Query(
		array(
			'post_type'              => $post_types,
			'post_status'            => 'publish',
			'meta_key'               => '_seopress_redirections_enabled',
			'meta_value'             => 'yes',
			'posts_per_page'         => WPAGENT_SEOPRESS_POST_REDIRECTION_MAX_RECORDS + 1,
			'fields'                 => 'all',
			'orderby'                => 'ID',
			'order'                  => 'ASC',
			'no_found_rows'          => true,
			'update_post_meta_cache' => false,
			'update_post_term_cache' => false,
			'suppress_filters'       => true,
		)
	);
	if ( count( $query->posts ) > WPAGENT_SEOPRESS_POST_REDIRECTION_MAX_RECORDS ) {
		return new WP_Error( 'wpagent_seopress_redirection_cycle_limit', __( 'Zu viele aktive SEOPress-Weiterleitungen für einen vollständigen Zyklenschutz.', 'wp-agent-companion' ), array( 'status' => 413 ) );
	}
	$posts = array_filter( $query->posts, static fn( $post ): bool => $post instanceof WP_Post );
	if ( count( $posts ) !== count( $query->posts ) ) {
		return new WP_Error( 'wpagent_seopress_redirection_provider_state_invalid', __( 'Der SEOPress-Weiterleitungsgraph enthält keinen vollständigen Beitragszustand.', 'wp-agent-companion' ), array( 'status' => 502 ) );
	}
	$metadata = wpagent_seopress_post_redirection_graph_metadata( array_map( static fn( WP_Post $post ): int => $post->ID, $posts ) );
	if ( is_wp_error( $metadata ) ) {
		return $metadata;
	}
	$edges = array();
	foreach ( $posts as $post ) {
		if ( $updated_post_id === $post->ID ) {
			continue;
		}
		$edge = wpagent_seopress_post_redirection_graph_edge( $post, $metadata[ $post->ID ] ?? array() );
		if ( is_wp_error( $edge ) ) {
			return $edge;
		}
		if ( isset( $edges[ $edge['source'] ] ) ) {
			return new WP_Error( 'wpagent_seopress_redirection_provider_state_invalid', __( 'SEOPress enthält mehrdeutige aktive Weiterleitungsquellen.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
		$edges[ $edge['source'] ] = $edge['destination'];
	}
	$candidate_source = wpagent_seopress_post_redirection_source_path( (string) $candidate['source'] );
	if ( is_wp_error( $candidate_source ) ) {
		return new WP_Error( 'wpagent_seopress_redirection_provider_state_invalid', __( 'Die vorgeschlagene Weiterleitung liegt außerhalb des sicheren lokalen Graphen.', 'wp-agent-companion' ), array( 'status' => 502 ) );
	}
	if ( $candidate['enabled'] ) {
		$candidate_destination = wpagent_seopress_post_redirection_source_path( (string) $candidate['destination'] );
		if ( is_wp_error( $candidate_destination ) ) {
			return new WP_Error( 'wpagent_seopress_redirection_provider_state_invalid', __( 'Die vorgeschlagene Weiterleitung liegt außerhalb des sicheren lokalen Graphen.', 'wp-agent-companion' ), array( 'status' => 502 ) );
		}
		$edges[ $candidate_source ] = $candidate_destination;
	} else {
		unset( $edges[ $candidate_source ] );
	}
	return $edges;
}

/** @return true|WP_Error */
function wpagent_seopress_post_redirection_validate_graph( int $post_id, array $candidate ) {
	$edges = wpagent_seopress_post_redirection_active_edges( $post_id, $candidate );
	if ( is_wp_error( $edges ) ) {
		return $edges;
	}
	$colour = array();
	foreach ( array_keys( $edges ) as $start ) {
		if ( 2 === ( $colour[ $start ] ?? 0 ) ) {
			continue;
		}
		$path    = array();
		$current = $start;
		while ( isset( $edges[ $current ] ) ) {
			$state = $colour[ $current ] ?? 0;
			if ( 1 === $state ) {
				return new WP_Error( 'wpagent_seopress_redirection_cycle', __( 'Der vollständige SEOPress-Weiterleitungsgraph enthält einen Zyklus.', 'wp-agent-companion' ), array( 'status' => 409 ) );
			}
			if ( 2 === $state ) {
				break;
			}
			$colour[ $current ] = 1;
			$path[]            = $current;
			$current           = $edges[ $current ];
		}
		foreach ( $path as $node ) {
			$colour[ $node ] = 2;
		}
	}
	return true;
}

/** @param mixed $input @return array<string,mixed>|WP_Error */
function wpagent_exec_set_seopress_post_redirection( $input ) {
	$runtime = wpagent_seopress_post_redirection_runtime();
	if ( is_wp_error( $runtime ) ) {
		return $runtime;
	}
	$input   = is_array( $input ) ? $input : array();
	$post_id = absint( $input['post_id'] ?? 0 );
	$target  = wpagent_seopress_post_redirection_target( $post_id );
	if ( is_wp_error( $target ) ) {
		return $target;
	}
	$graph_lock = wpagent_seopress_post_redirection_acquire_graph_lock();
	if ( is_wp_error( $graph_lock ) ) {
		return $graph_lock;
	}
	$lock = wpagent_seopress_post_redirection_acquire_lock( $post_id );
	if ( is_wp_error( $lock ) ) {
		wpagent_seopress_post_redirection_release_graph_lock( $graph_lock );
		return $lock;
	}
	$before                 = null;
	$attempt_raw            = null;
	$candidate              = null;
	$provider_write_started = false;
	try {
		$before = wpagent_seopress_post_redirection_read( $post_id, $target['source'] );
		if ( is_wp_error( $before ) ) {
			return $before;
		}
		$hash = wpagent_seopress_post_redirection_expected_hash( $input['expected_state_hash'] ?? null, (string) $before['state']['state_hash'] );
		if ( is_wp_error( $hash ) ) {
			return $hash;
		}
		$candidate = wpagent_seopress_post_redirection_next( $input, $before['state'] );
		if ( is_wp_error( $candidate ) ) {
			return $candidate;
		}
		if ( wpagent_seopress_post_redirection_matches( $before['state'], $candidate ) ) {
			return array(
				'redirection' => wpagent_seopress_post_redirection_public_state( $before['state'] ),
				'verified'    => true,
			);
		}
		$graph = wpagent_seopress_post_redirection_validate_graph( $post_id, $candidate );
		if ( is_wp_error( $graph ) ) {
			return $graph;
		}
		// The graph scan can take long enough for a concurrent editor to unpublish
		// the source post, change its permalink, or revoke the current user's
		// capability. Re-establish the exact target and full provider snapshot
		// before the native PUT. No provider mutation has started at this point.
		$target_before_write = wpagent_seopress_post_redirection_target( $post_id );
		if ( is_wp_error( $target_before_write ) ) {
			return $target_before_write;
		}
		$before_write = wpagent_seopress_post_redirection_read( $post_id, $target_before_write['source'] );
		if ( is_wp_error( $before_write ) ) {
			return $before_write;
		}
		if ( ! hash_equals( (string) $before['state']['state_hash'], (string) $before_write['state']['state_hash'] )
			|| ! wpagent_seopress_post_redirection_snapshots_equal( $before['raw'], $before_write['raw'] ) ) {
			return new WP_Error(
				'wpagent_seopress_redirection_conflict',
				__( 'Die SEOPress-Weiterleitung wurde während der Graph-Prüfung verändert. Bitte erneut lesen.', 'wp-agent-companion' ),
				array( 'status' => 409, 'current_hash' => (string) $before_write['state']['state_hash'] )
			);
		}
		if ( ! wpagent_seopress_post_redirection_refresh_graph_lock( $graph_lock ) ) {
			return new WP_Error( 'wpagent_seopress_redirection_graph_locked', __( 'Der globale SEOPress-Weiterleitungslock ging vor dem Provider-Write verloren. Bitte erneut versuchen.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
		if ( ! wpagent_seopress_post_redirection_refresh_lock( $post_id, $lock ) ) {
			return new WP_Error( 'wpagent_seopress_redirection_locked', __( 'Der SEOPress-Weiterleitungslock ging vor dem Provider-Write verloren. Bitte erneut versuchen.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
		$provider_write_started = true;
		$write = wpagent_seopress_post_redirection_provider_request(
			$post_id,
			'PUT',
			array(
				'_seopress_redirections_enabled' => $candidate['enabled'] ? 'yes' : '',
				'_seopress_redirections_type'    => $candidate['http_code'],
				'_seopress_redirections_value'   => $candidate['destination'],
			)
		);
		if ( ! wpagent_seopress_post_redirection_lock_owned( WPAGENT_SEOPRESS_REDIRECTION_GRAPH_LOCK_OPTION, $graph_lock ) || ! wpagent_seopress_post_redirection_lock_owned( wpagent_seopress_post_redirection_lock_option( $post_id ), $lock ) ) {
			return wpagent_seopress_post_redirection_recovery_required_error( __( 'Ein SEOPress-Weiterleitungslock ging während des Provider-Writes verloren. Bitte den Beitrag manuell prüfen.', 'wp-agent-companion' ) );
		}
		$attempt_raw = wpagent_seopress_post_redirection_capture_raw( $post_id );
		if ( is_wp_error( $attempt_raw ) ) {
			return wpagent_seopress_post_redirection_recovery_required_error( __( 'Der rohe SEOPress-Zustand konnte nach dem Write nicht gesichert werden. Bitte den Beitrag manuell prüfen.', 'wp-agent-companion' ) );
		}
		if ( ! is_wp_error( $write ) && ! wpagent_seopress_post_redirection_attempt_matches_candidate( $before['raw'], $attempt_raw, $candidate ) ) {
			return wpagent_seopress_post_redirection_recovery_required_error( __( 'SEOPress lieferte nach dem Write einen nicht eindeutig diesem Write zurechenbaren Rohzustand. WPAgently überschreibt ihn nicht. Bitte den Beitrag manuell prüfen.', 'wp-agent-companion' ) );
		}
		if ( is_wp_error( $write ) ) {
			return wpagent_seopress_post_redirection_recovery_required_error( __( 'SEOPress bestätigte nach dem gestarteten Write keinen sicheren Zustand. WPAgently stellt keine Rohdaten automatisch wieder her. Bitte den Beitrag manuell prüfen.', 'wp-agent-companion' ) );
		}
		$fresh = wpagent_seopress_post_redirection_read( $post_id, $target['source'] );
		if ( is_wp_error( $fresh ) || ! wpagent_seopress_post_redirection_matches( $fresh['state'], $candidate ) || ! wpagent_seopress_post_redirection_snapshots_equal( $attempt_raw, $fresh['raw'] ) ) {
			return wpagent_seopress_post_redirection_recovery_required_error( __( 'SEOPress bestätigte die Weiterleitung nach dem gestarteten Write nicht exakt. WPAgently stellt keine Rohdaten automatisch wieder her. Bitte den Beitrag manuell prüfen.', 'wp-agent-companion' ) );
		}
		$current_raw = wpagent_seopress_post_redirection_capture_raw( $post_id );
		if ( is_wp_error( $current_raw ) || ! wpagent_seopress_post_redirection_snapshots_equal( $fresh['raw'], $current_raw ) ) {
			return wpagent_seopress_post_redirection_recovery_required_error( __( 'Der rohe SEOPress-Zustand wurde während der Verifikation verändert. WPAgently stellt keine Rohdaten automatisch wieder her. Bitte den Beitrag manuell prüfen.', 'wp-agent-companion' ) );
		}
		if ( ! wpagent_seopress_post_redirection_lock_owned( WPAGENT_SEOPRESS_REDIRECTION_GRAPH_LOCK_OPTION, $graph_lock ) || ! wpagent_seopress_post_redirection_lock_owned( wpagent_seopress_post_redirection_lock_option( $post_id ), $lock ) ) {
			return wpagent_seopress_post_redirection_recovery_required_error( __( 'Ein SEOPress-Weiterleitungslock ging während der Verifikation verloren. Bitte den Beitrag manuell prüfen.', 'wp-agent-companion' ) );
		}
		return array(
			'redirection' => wpagent_seopress_post_redirection_public_state( $fresh['state'] ),
			'verified'    => true,
		);
	} catch ( Throwable ) {
		if ( $provider_write_started ) {
			return wpagent_seopress_post_redirection_recovery_required_error( __( 'SEOPress konnte nach dem gestarteten Write nicht sicher bestätigt werden. WPAgently stellt keine Rohdaten automatisch wieder her. Bitte den Beitrag manuell prüfen.', 'wp-agent-companion' ) );
		}
		return new WP_Error(
			'wpagent_seopress_redirection_write_failed',
			__( 'SEOPress konnte die Weiterleitung nicht sicher speichern.', 'wp-agent-companion' ),
			array(
				'status'            => 500,
				'recovery_required' => $provider_write_started,
			)
		);
	} finally {
		wpagent_seopress_post_redirection_release_lock( $post_id, $lock );
		wpagent_seopress_post_redirection_release_graph_lock( $graph_lock );
	}
}
