<?php
/** Transactional Weglot settings writes. */

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

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

function wpagent_weglot_release_lock( string $token ): void {
	wpagent_companion_release_option_lock( WPAGENT_WEGLOT_LOCK_OPTION, $token );
}

function wpagent_weglot_lock_is_owned( string $token ): bool {
	return wpagent_companion_option_lock_is_owned( WPAGENT_WEGLOT_LOCK_OPTION, $token );
}

function wpagent_weglot_refresh_lock( string $token ): bool {
	return wpagent_companion_refresh_option_lock( WPAGENT_WEGLOT_LOCK_OPTION, $token, WPAGENT_WEGLOT_LOCK_TTL );
}

/** @return WP_Error */
function wpagent_weglot_recovery_required() {
	return new WP_Error(
		'wpagent_weglot_recovery_required',
		__( 'Der Weglot-Schreibvorgang hat begonnen, aber die exklusive Sperre oder Berechtigung ging vor der abschließenden Bestätigung verloren. Es wurde kein automatisches Rollback ausgeführt. Prüfe die Weglot-Einstellungen manuell und lies sie anschließend neu.', 'wp-agent-companion' ),
		array( 'status' => 409, 'recovery_required' => true )
	);
}

function wpagent_weglot_save( $service, array $options ): bool {
	try {
		$response = $service->save_options_to_weglot( $options );
	} catch ( Throwable $error ) {
		return false;
	}
	return is_array( $response ) && ! empty( $response['success'] );
}

/** Hashes the exact provider candidate without retaining credential material. */
function wpagent_weglot_candidate_identity_hash( array $options ): string {
	unset( $options['api_key_private'], $options['api_key'] );
	return hash( 'sha256', serialize( $options ) );
}

/** @return true|WP_Error */
function wpagent_weglot_rollback( $service, array $previous, string $previous_hash, array $candidate, string $candidate_hash, string $lock_token ) {
	if ( ! current_user_can( 'manage_options' ) || ! wpagent_weglot_refresh_lock( $lock_token ) ) {
		return wpagent_weglot_recovery_required();
	}
	delete_transient( 'weglot_cache_cdn' );
	$fresh_candidate = wpagent_weglot_read_options( $service, true );
	$fresh_settings = is_wp_error( $fresh_candidate ) ? $fresh_candidate : wpagent_weglot_project_settings( $fresh_candidate );
	if ( is_wp_error( $fresh_settings )
		|| ! hash_equals( $candidate_hash, wpagent_weglot_state_hash( $fresh_settings ) )
		|| ! hash_equals( wpagent_weglot_candidate_identity_hash( $candidate ), wpagent_weglot_candidate_identity_hash( $fresh_candidate ) )
		|| ! current_user_can( 'manage_options' )
		|| ! wpagent_weglot_lock_is_owned( $lock_token ) ) {
		return wpagent_weglot_recovery_required();
	}
	if ( ! wpagent_weglot_save( $service, $previous ) ) {
		if ( ! wpagent_weglot_lock_is_owned( $lock_token ) ) {
			return wpagent_weglot_recovery_required();
		}
		return new WP_Error( 'wpagent_weglot_rollback_failed', __( 'Weglot konnte die Änderung nicht bestätigen, und auch das Rollback wurde abgelehnt. Prüfe die Weglot-Einstellungen sofort manuell.', 'wp-agent-companion' ), array( 'status' => 500, 'rollback_verified' => false ) );
	}
	if ( ! current_user_can( 'manage_options' ) || ! wpagent_weglot_lock_is_owned( $lock_token ) ) {
		return wpagent_weglot_recovery_required();
	}
	delete_transient( 'weglot_cache_cdn' );
	$restored = wpagent_weglot_read_options( $service, true );
	$settings = is_wp_error( $restored ) ? $restored : wpagent_weglot_project_settings( $restored );
	if ( ! wpagent_weglot_lock_is_owned( $lock_token ) ) {
		return wpagent_weglot_recovery_required();
	}
	if ( is_wp_error( $settings ) || ! hash_equals( $previous_hash, wpagent_weglot_state_hash( $settings ) ) ) {
		return new WP_Error( 'wpagent_weglot_rollback_unverified', __( 'Das Weglot-Rollback konnte nicht verifiziert werden. Prüfe die Weglot-Einstellungen sofort manuell.', 'wp-agent-companion' ), array( 'status' => 500, 'rollback_verified' => false ) );
	}
	return true;
}

/** @return WP_Error */
function wpagent_weglot_manual_write_only() {
	return new WP_Error(
		'wpagent_weglot_conditional_write_unavailable',
		__( 'Die aktive Weglot-API stellt keine versionsgebundene bedingte Speicherung bereit. WPAgently ändert diese Projekteinstellungen deshalb nicht. Nimm die Änderung im Weglot-Dashboard vor und lies die Einstellungen anschließend neu.', 'wp-agent-companion' ),
		array( 'status' => 409, 'manual_only' => true )
	);
}

/** @return WP_Error */
function wpagent_exec_update_weglot_settings( $input ) {
	// Weglot exposes only a whole-project unconditional save. An application lock
	// cannot serialize dashboard or API writers, so a read-before-write CAS would race.
	// Preserve availability and connection failures so callers can distinguish a
	// provider that cannot be changed from a connected provider with no CAS API.
	$service = wpagent_weglot_service();
	if ( is_wp_error( $service ) ) {
		return $service;
	}
	$key = wpagent_weglot_private_key( $service );
	if ( is_wp_error( $key ) ) {
		return $key;
	}
	if ( '' === $key ) {
		return new WP_Error( 'wpagent_weglot_not_configured', __( 'Weglot ist noch nicht mit einem Projekt verbunden.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	return wpagent_weglot_manual_write_only();
}
