<?php
/** Atomic lock and rollback helpers for Astra design writes. */

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

/** @return string|WP_Error */
function wpagent_astra_acquire_lock() {
	$token = wpagent_companion_acquire_option_lock( WPAGENT_ASTRA_LOCK_OPTION, WPAGENT_ASTRA_LOCK_TTL );
	if ( is_string( $token ) ) {
		return $token;
	}
	return new WP_Error( 'wpagent_astra_locked', __( 'Die Astra-Einstellungen werden gerade durch einen anderen Vorgang geändert.', 'wp-agent-companion' ), array( 'status' => 409 ) );
}

function wpagent_astra_release_lock( string $token ): void {
	wpagent_companion_release_option_lock( WPAGENT_ASTRA_LOCK_OPTION, $token );
}

/** @param array{exists:bool,value:array,palette_exists:bool,palette_value:array} $snapshot @return true|WP_Error */
function wpagent_astra_rollback( array $snapshot, string $expected_hash ) {
	try {
		if ( $snapshot['exists'] ) {
			update_option( 'astra-settings', $snapshot['value'], false );
		} else {
			delete_option( 'astra-settings' );
		}
	} catch ( Throwable $error ) {
		// WordPress fires third-party hooks after changing the option. Verify the
		// persisted state below instead of trusting the hook outcome.
	}
	try {
		if ( $snapshot['palette_exists'] ) {
			update_option( 'astra-color-palettes', $snapshot['palette_value'], false );
		} else {
			delete_option( 'astra-color-palettes' );
		}
	} catch ( Throwable $error ) {
		// The two options are restored independently so one failing provider hook
		// cannot prevent the other half of the rollback.
	}
	wp_cache_delete( 'astra-settings', 'options' );
	wp_cache_delete( 'astra-color-palettes', 'options' );
	$fresh = wpagent_astra_snapshot();
	if ( is_wp_error( $fresh ) || ! hash_equals( $expected_hash, wpagent_astra_state_hash( $fresh ) ) ) {
		return new WP_Error(
			'wpagent_astra_rollback_unverified',
			__( 'Das Astra-Rollback konnte nicht verifiziert werden. Prüfe die Theme-Einstellungen sofort manuell.', 'wp-agent-companion' ),
			array( 'status' => 500, 'rollback_verified' => false )
		);
	}
	return true;
}

/** @return WP_Error */
function wpagent_astra_fail_after_rollback( array $snapshot, string $previous_hash ) {
	$rollback = wpagent_astra_rollback( $snapshot, $previous_hash );
	if ( is_wp_error( $rollback ) ) {
		return $rollback;
	}
	return new WP_Error(
		'wpagent_astra_write_unverified',
		__( 'Astra hat die Änderung nicht exakt bestätigt. Der vorherige Zustand wurde verifiziert wiederhergestellt.', 'wp-agent-companion' ),
		array( 'status' => 502, 'rollback_verified' => true )
	);
}
