<?php
/** Update verified per-post Astra design overrides. */

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

function wpagent_ability_update_astra_post_design(): array {
	return array(
		'label'               => __( 'Astra-Beitragsdesign aktualisieren', 'wp-agent-companion' ),
		'description'         => __( 'Ändert individuelle Astra-Layout- und Sichtbarkeitsvorgaben mit Konfliktschutz, Read-back und verifiziertem Rollback.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'                 => 'object',
			'properties'           => array(
				'post_id'       => array( 'type' => 'integer', 'minimum' => 1 ),
				'expected_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'settings'      => wpagent_astra_post_override_schema(),
			),
			'required'             => array( 'post_id', 'expected_hash', 'settings' ),
			'additionalProperties' => false,
		),
		'output_schema'       => array(
			'type'                 => 'object',
			'properties'           => array(
				'post_id'    => array( 'type' => 'integer' ),
				'post_type'  => array( 'type' => 'string' ),
				'overrides'  => wpagent_astra_post_override_schema( true ),
				'state_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'verified'   => array( 'type' => 'boolean' ),
			),
			'required'             => array( 'post_id', 'post_type', 'overrides', 'state_hash', 'verified' ),
			'additionalProperties' => false,
		),
		'execute_callback'    => 'wpagent_exec_update_astra_post_design',
		'permission_callback' => 'wpagent_perm_edit_posts',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => false ) ),
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_update_astra_post_design( $input ) {
	if ( ! wpagent_astra_is_active() ) {
		return new WP_Error( 'wpagent_astra_inactive', __( 'Astra oder ein Astra-Child-Theme ist nicht aktiv.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	if ( ! wpagent_astra_abilities_enabled() ) {
		return new WP_Error( 'wpagent_astra_abilities_disabled', __( 'Aktiviere zuerst die Abilities in den Astra-Einstellungen.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$input = is_array( $input ) ? $input : array();
	$post  = wpagent_astra_post_target( absint( $input['post_id'] ?? 0 ) );
	if ( is_wp_error( $post ) ) {
		return $post;
	}
	$settings_schema = wpagent_astra_post_override_schema();
	$valid           = rest_validate_value_from_schema( $input['settings'] ?? null, $settings_schema, 'settings' );
	if ( is_wp_error( $valid ) ) {
		return new WP_Error( 'wpagent_astra_post_invalid_settings', __( 'Die Astra-Beitragseinstellungen sind ungültig.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$settings = rest_sanitize_value_from_schema( $input['settings'] ?? null, $settings_schema, 'settings' );
	if ( is_wp_error( $settings ) || ! is_array( $settings ) || ! $settings ) {
		return new WP_Error( 'wpagent_astra_post_invalid_settings', __( 'Die Astra-Beitragseinstellungen sind ungültig.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}

	$lock = wpagent_astra_acquire_lock();
	if ( is_wp_error( $lock ) ) {
		return $lock;
	}
	try {
		$checkpoint = wpagent_astra_post_checkpoint( $post->ID, $lock );
		if ( is_wp_error( $checkpoint ) ) {
			return $checkpoint;
		}
		$previous = wpagent_astra_post_snapshot( $post );
		if ( is_wp_error( $previous ) ) {
			return $previous;
		}
		$previous_hash = wpagent_astra_post_state_hash( $previous );
		$expected_hash = strtolower( (string) ( $input['expected_hash'] ?? '' ) );
		if ( ! preg_match( '/^[a-f0-9]{64}$/', $expected_hash ) || ! hash_equals( $previous_hash, $expected_hash ) ) {
			return new WP_Error( 'wpagent_astra_post_conflict', __( 'Die Astra-Beitragseinstellungen haben sich seit dem Lesen geändert. Lies sie neu und wiederhole den Vorgang.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $previous_hash ) );
		}
		$expected = wpagent_astra_post_expected_snapshot( $previous, $settings );
		$checkpoint = wpagent_astra_post_checkpoint( $post->ID, $lock );
		if ( is_wp_error( $checkpoint ) ) {
			return $checkpoint;
		}
		try {
			$applied = wpagent_astra_post_apply_expected( $previous, $expected, $lock );
			if ( is_wp_error( $applied ) ) {
				$data = $applied->get_error_data();
				return is_array( $data ) && ! empty( $data['write_started'] )
					? wpagent_astra_post_recovery_required( $post->ID )
					: $applied;
			}
		} catch ( Throwable $error ) {
			return wpagent_astra_post_recovery_required( $post->ID );
		}

		$checkpoint = wpagent_astra_post_checkpoint( $post->ID, $lock, true );
		if ( is_wp_error( $checkpoint ) ) {
			return wpagent_astra_post_recovery_required( $post->ID );
		}
		$fresh = wpagent_astra_post_snapshot( $post );
		if ( is_wp_error( $fresh ) ) {
			return wpagent_astra_post_recovery_required( $post->ID );
		}
		if ( ! wpagent_astra_post_matches_expected( $expected, $fresh ) ) {
			return wpagent_astra_post_recovery_required( $post->ID );
		}
		$overrides = wpagent_astra_post_normalize( $fresh );
		foreach ( $settings as $field => $value ) {
			if ( ! isset( $overrides[ $field ] ) || $overrides[ $field ] !== $value ) {
				return wpagent_astra_post_fail_after_rollback( $previous, $fresh, $previous_hash, $lock );
			}
		}
		$checkpoint = wpagent_astra_post_checkpoint( $post->ID, $lock, true );
		if ( is_wp_error( $checkpoint ) ) {
			return wpagent_astra_post_recovery_required( $post->ID );
		}
		return array(
			'post_id'    => (int) $post->ID,
			'post_type'  => $post->post_type,
			'overrides'  => $overrides,
			'state_hash' => wpagent_astra_post_state_hash( $fresh ),
			'verified'   => true,
		);
	} finally {
		wpagent_astra_release_lock( $lock );
	}
}
