<?php
/** Conflict-safe Spectra editor-settings writes for the exact verified free provider. */

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

const WPAGENT_SPECTRA_SETTINGS_LOCK_OPTION = 'wp_agent_spectra_settings_lock';
const WPAGENT_SPECTRA_SETTINGS_LOCK_TTL    = 120;

/** @return array<string,mixed> */
function wpagent_ability_update_spectra_editor_settings(): array {
	$font = array(
		'type' => 'object', 'properties' => array(
			'family' => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => WPAGENT_SPECTRA_SETTINGS_MAX_FONT_FIELD_BYTES ),
			'weights' => array( 'type' => 'array', 'maxItems' => WPAGENT_SPECTRA_SETTINGS_MAX_FONT_VARIANTS, 'items' => array( 'type' => 'string' ) ),
			'styles' => array( 'type' => 'array', 'maxItems' => WPAGENT_SPECTRA_SETTINGS_MAX_FONT_VARIANTS, 'items' => array( 'type' => 'string' ) ),
		), 'required' => array( 'family', 'weights', 'styles' ), 'additionalProperties' => false,
	);
	$output = wpagent_spectra_editor_settings_schema();
	$output['properties']['changed']       = array( 'type' => 'boolean' );
	$output['properties']['verified']      = array( 'type' => 'boolean' );
	$output['properties']['previous_hash'] = array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' );
	$output['required'][]                  = 'changed';
	$output['required'][]                  = 'verified';
	$output['required'][]                  = 'previous_hash';

	$toggle_properties = array();
	foreach ( wpagent_spectra_editor_toggle_specs() as $spec ) {
		$toggle_properties[ $spec['output'] ] = array( 'type' => 'boolean' );
	}
	return array(
		'label'       => __( 'Spectra-Editor-Einstellungen aktualisieren', 'wp-agent-companion' ),
		'description' => __( 'Aktualisiert ausgewählte Spectra-Editor-Schalter und die begrenzte Google-Font-Konfiguration mit Zustands-Hash, atomarer Konfliktprüfung, Rücklesen und selektivem Rollback.', 'wp-agent-companion' ),
		'category'    => 'wp-agent',
		'input_schema' => array(
			'type' => 'object', 'properties' => array(
				'expected_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'editor_toggles' => array( 'type' => 'object', 'properties' => $toggle_properties, 'additionalProperties' => false ),
				'google_fonts' => array( 'type' => 'object', 'properties' => array(
					'selected_families_enabled' => array( 'type' => 'boolean' ),
					'selected_families' => array( 'type' => 'array', 'maxItems' => WPAGENT_SPECTRA_SETTINGS_MAX_FONT_FAMILIES, 'items' => $font ),
					'load_locally' => array( 'type' => 'boolean' ),
					'preload_local' => array( 'type' => 'boolean' ),
				), 'additionalProperties' => false ),
			), 'required' => array( 'expected_hash' ), 'additionalProperties' => false,
		),
		'output_schema'       => $output,
		'execute_callback'    => 'wpagent_exec_update_spectra_editor_settings',
		'permission_callback' => 'wpagent_perm_manage_options',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => false ) ),
	);
}

/** @return array<string,string> */
function wpagent_spectra_settings_font_options(): array {
	return array(
		'selected_families_enabled' => 'uag_load_select_font_globally',
		'selected_families'         => 'uag_select_font_globally',
		'load_locally'              => 'uag_load_gfonts_locally',
		'preload_local'             => 'uag_preload_local_fonts',
	);
}

/** @return array<int,string> */
function wpagent_spectra_settings_managed_options(): array {
	$options = array_column( wpagent_spectra_editor_toggle_specs(), 'option' );
	return array_merge( $options, array_values( wpagent_spectra_settings_font_options() ) );
}

/** @return array<string,array{raw:string,autoload:string}|null>|WP_Error */
function wpagent_spectra_settings_rows() {
	global $wpdb;
	$rows = array();
	foreach ( wpagent_spectra_settings_managed_options() as $name ) {
		$rows[ $name ] = wpagent_companion_read_option_row_direct( $name );
		if ( '' !== $wpdb->last_error ) {
			return new WP_Error( 'wpagent_spectra_settings_storage', __( 'Die Spectra-Einstellungen konnten nicht direkt und vollständig gelesen werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
		}
	}
	return $rows;
}

/** @param array{raw:string,autoload:string}|null $left @param array{raw:string,autoload:string}|null $right */
function wpagent_spectra_settings_rows_equal( ?array $left, ?array $right ): bool {
	return null === $left || null === $right
		? null === $left && null === $right
		: $left['raw'] === $right['raw'] && $left['autoload'] === $right['autoload'];
}

/** @param array<string,array{raw:string,autoload:string}|null> $left @param array<string,array{raw:string,autoload:string}|null> $right */
function wpagent_spectra_settings_row_sets_equal( array $left, array $right ): bool {
	if ( array_keys( $left ) !== array_keys( $right ) ) {
		return false;
	}
	foreach ( $left as $name => $row ) {
		if ( ! wpagent_spectra_settings_rows_equal( $row, $right[ $name ] ) ) {
			return false;
		}
	}
	return true;
}

/** @return array<int,array{value:string,label:string}> */
function wpagent_spectra_settings_provider_variants( array $values ): array {
	return array_map( static fn( string $value ): array => array( 'value' => $value, 'label' => $value ), $values );
}

/** @return array<int,array{value:string,label:string}>|WP_Error */
function wpagent_spectra_settings_merge_provider_variants( array $requested, $stored, string $kind ) {
	if ( ! is_array( $stored ) || ! array_is_list( $stored ) ) {
		return new WP_Error( 'wpagent_spectra_settings_conflict', __( 'Die gespeicherte Spectra-Font-Liste enthält nicht sichtbare Providerdaten und wird deshalb nicht ersetzt.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$stored_values = wpagent_spectra_editor_font_variants( $stored, $kind );
	if ( is_wp_error( $stored_values ) ) {
		return $stored_values;
	}
	$by_value = array_combine( $stored_values, $stored );
	$result   = array();
	foreach ( $requested as $item ) {
		$result[] = $by_value[ $item['value'] ] ?? $item;
	}
	return $result;
}

/** Preserve provider-only labels and available variants for retained font families. */
function wpagent_spectra_settings_merge_families( array $requested, ?array $row ) {
	$stored = null === $row ? array() : maybe_unserialize( $row['raw'] );
	if ( ! is_array( $stored ) || ! array_is_list( $stored ) ) {
		return new WP_Error( 'wpagent_spectra_settings_conflict', __( 'Die gespeicherte Spectra-Font-Liste enthält nicht sichtbare Providerdaten und wird deshalb nicht ersetzt.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$by_family = array();
	foreach ( $stored as $item ) {
		if ( ! is_array( $item ) || ! isset( $item['value'], $item['label'], $item['weight'], $item['style'] ) ) {
			return new WP_Error( 'wpagent_spectra_settings_conflict', __( 'Die gespeicherte Spectra-Font-Liste enthält nicht sichtbare Providerdaten und wird deshalb nicht ersetzt.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
		$by_family[ $item['value'] ] = $item;
	}
	$result = array();
	foreach ( $requested as $item ) {
		if ( ! isset( $by_family[ $item['value'] ] ) ) {
			$result[] = $item;
			continue;
		}
		$previous = $by_family[ $item['value'] ];
		$previous_weights = wpagent_spectra_editor_font_variants( $previous['weight'], 'weight' );
		$previous_styles  = wpagent_spectra_editor_font_variants( $previous['style'], 'style' );
		if ( ! is_wp_error( $previous_weights ) && ! is_wp_error( $previous_styles ) && $previous_weights === array_column( $item['weight'], 'value' ) && $previous_styles === array_column( $item['style'], 'value' ) ) {
			$result[] = $previous;
			continue;
		}
		$weights  = wpagent_spectra_settings_merge_provider_variants( $item['weight'], $previous['weight'], 'weight' );
		$styles   = wpagent_spectra_settings_merge_provider_variants( $item['style'], $previous['style'], 'style' );
		if ( is_wp_error( $weights ) || is_wp_error( $styles ) ) {
			return is_wp_error( $weights ) ? $weights : $styles;
		}
		$merged = array( 'value' => $item['value'], 'label' => $previous['label'], 'weight' => $weights, 'style' => $styles );
		foreach ( array( 'weights', 'styles' ) as $available ) {
			if ( array_key_exists( $available, $previous ) ) {
				$merged[ $available ] = $previous[ $available ];
			}
		}
		$result[] = $merged;
	}
	return $result;
}

/** @return string|WP_Error */
function wpagent_spectra_settings_input_text( $value ) {
	$text = wpagent_spectra_editor_settings_text( $value );
	if ( is_wp_error( $text ) || wp_check_invalid_utf8( $text, true ) !== $text || html_entity_decode( $text, ENT_QUOTES | ENT_HTML5, 'UTF-8' ) !== $text || preg_match( '/[\x00-\x1F\x7F\x{202A}-\x{202E}\x{2066}-\x{2069}]/u', $text ) ) {
		return new WP_Error( 'wpagent_spectra_settings_input', __( 'Eine Font-Familie enthält keine sichere reine Textbezeichnung.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	return $text;
}

/** @return array<int,array<string,mixed>>|WP_Error */
function wpagent_spectra_settings_validate_families( $value ) {
	if ( ! is_array( $value ) || ! array_is_list( $value ) || count( $value ) > WPAGENT_SPECTRA_SETTINGS_MAX_FONT_FAMILIES ) {
		return new WP_Error( 'wpagent_spectra_settings_input', __( 'selected_families muss eine begrenzte Liste sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$provider = array();
	$seen     = array();
	foreach ( $value as $item ) {
		if ( ! is_array( $item ) || 3 !== count( $item ) || array_diff( array_keys( $item ), array( 'family', 'weights', 'styles' ) ) || array_diff( array( 'family', 'weights', 'styles' ), array_keys( $item ) ) ) {
			return new WP_Error( 'wpagent_spectra_settings_input', __( 'Eine Font-Familie enthält unbekannte oder fehlende Felder.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		$family = wpagent_spectra_settings_input_text( $item['family'] );
		if ( is_wp_error( $family ) || isset( $seen[ $family ] ) ) {
			return new WP_Error( 'wpagent_spectra_settings_input', __( 'Eine Font-Familie ist ungültig oder doppelt vorhanden.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		$weights = wpagent_spectra_settings_validate_variants( $item['weights'], 'weight' );
		$styles  = wpagent_spectra_settings_validate_variants( $item['styles'], 'style' );
		if ( is_wp_error( $weights ) || is_wp_error( $styles ) ) {
			return new WP_Error( 'wpagent_spectra_settings_input', __( 'Eine Font-Variante ist ungültig oder doppelt vorhanden.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		$seen[ $family ] = true;
		$provider[] = array(
			'value' => $family, 'label' => $family,
			'weight' => wpagent_spectra_settings_provider_variants( $weights ),
			'style' => wpagent_spectra_settings_provider_variants( $styles ),
		);
	}
	$nodes = 0;
	$bytes = wpagent_spectra_editor_font_value_bytes( $provider, 0, $nodes );
	return is_wp_error( $bytes ) ? new WP_Error( 'wpagent_spectra_settings_input', __( 'Die Font-Konfiguration überschreitet die sicheren Grenzen.', 'wp-agent-companion' ), array( 'status' => 400 ) ) : $provider;
}

/** @return array<int,string>|WP_Error */
function wpagent_spectra_settings_validate_variants( $value, string $kind ) {
	if ( ! is_array( $value ) || ! array_is_list( $value ) || count( $value ) > WPAGENT_SPECTRA_SETTINGS_MAX_FONT_VARIANTS ) {
		return new WP_Error( 'wpagent_spectra_settings_input', '', array( 'status' => 400 ) );
	}
	$result = array();
	foreach ( $value as $variant ) {
		$valid = is_string( $variant ) && strlen( $variant ) <= WPAGENT_SPECTRA_SETTINGS_MAX_FONT_FIELD_BYTES
			&& ( 'weight' === $kind ? (bool) preg_match( '/^(?:[1-9]00|variable)$/D', $variant ) : in_array( $variant, array( 'normal', 'italic' ), true ) );
		if ( ! $valid || in_array( $variant, $result, true ) ) {
			return new WP_Error( 'wpagent_spectra_settings_input', '', array( 'status' => 400 ) );
		}
		$result[] = $variant;
	}
	return $result;
}

/** @return array{expected_hash:string,changes:array<string,mixed>}|WP_Error */
function wpagent_spectra_settings_validate_update( $input ) {
	if ( ! is_array( $input ) || array_diff( array_keys( $input ), array( 'expected_hash', 'editor_toggles', 'google_fonts' ) ) ) {
		return new WP_Error( 'wpagent_spectra_settings_input', __( 'Die Spectra-Einstellungsänderung enthält unbekannte Felder.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$expected_hash = $input['expected_hash'] ?? null;
	if ( ! is_string( $expected_hash ) || ! preg_match( '/^[a-f0-9]{64}$/D', $expected_hash ) ) {
		return new WP_Error( 'wpagent_spectra_settings_input', __( 'expected_hash muss ein SHA-256-Hash sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$changes = array();
	$toggles = $input['editor_toggles'] ?? array();
	if ( ! is_array( $toggles ) ) {
		return new WP_Error( 'wpagent_spectra_settings_input', __( 'editor_toggles muss ein Objekt sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$specs = array_column( wpagent_spectra_editor_toggle_specs(), null, 'output' );
	if ( array_diff( array_keys( $toggles ), array_keys( $specs ) ) ) {
		return new WP_Error( 'wpagent_spectra_settings_input', __( 'editor_toggles enthält ein unbekanntes Feld.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	foreach ( $toggles as $key => $enabled ) {
		if ( ! is_bool( $enabled ) ) {
			return new WP_Error( 'wpagent_spectra_settings_input', __( 'Jeder Spectra-Editor-Schalter muss boolesch sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		$spec                       = $specs[ $key ];
		$changes[ $spec['option'] ] = $enabled ? $spec['enabled'] : $spec['disabled'];
	}
	$fonts = $input['google_fonts'] ?? array();
	if ( ! is_array( $fonts ) || array_diff( array_keys( $fonts ), array_keys( wpagent_spectra_settings_font_options() ) ) ) {
		return new WP_Error( 'wpagent_spectra_settings_input', __( 'google_fonts enthält unbekannte oder ungültige Felder.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	foreach ( wpagent_spectra_settings_font_options() as $key => $option ) {
		if ( ! array_key_exists( $key, $fonts ) ) {
			continue;
		}
		if ( 'selected_families' === $key ) {
			$value = wpagent_spectra_settings_validate_families( $fonts[ $key ] );
			if ( is_wp_error( $value ) ) {
				return $value;
			}
			$changes[ $option ] = $value;
		} elseif ( ! is_bool( $fonts[ $key ] ) ) {
			return new WP_Error( 'wpagent_spectra_settings_input', __( 'Jeder Spectra-Font-Schalter muss boolesch sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		} else {
			$changes[ $option ] = $fonts[ $key ] ? 'enabled' : 'disabled';
		}
	}
	if ( array() === $changes ) {
		return new WP_Error( 'wpagent_spectra_settings_input', __( 'Mindestens eine Spectra-Einstellung muss angegeben werden.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	return compact( 'expected_hash', 'changes' );
}

/** @return array{raw:string,autoload:string} */
function wpagent_spectra_settings_desired_row( string $name, $value, ?array $before ): array {
	$raw = maybe_serialize( $value );
	return array(
		'raw' => $raw,
		'autoload' => is_array( $before ) ? $before['autoload'] : wp_determine_option_autoload_value( $name, $value, $raw, null ),
	);
}

/** @return true|WP_Error */
function wpagent_spectra_settings_cas_write( string $name, $value, ?array $before ) {
	global $wpdb;
	$old = is_array( $before ) ? maybe_unserialize( $before['raw'] ) : false;
	try {
		$prepared = sanitize_option( $name, $value );
		$prepared = apply_filters( "pre_update_option_{$name}", $prepared, $old, $name );
		$prepared = apply_filters( 'pre_update_option', $prepared, $name, $old );
	} catch ( Throwable $error ) {
		return new WP_Error( 'wpagent_spectra_settings_write', __( 'Spectra konnte den Providerwert nicht sicher vorbereiten.', 'wp-agent-companion' ), array( 'status' => 409, 'mutation_started' => false ) );
	}
	if ( maybe_serialize( $prepared ) !== maybe_serialize( $value ) ) {
		return new WP_Error( 'wpagent_spectra_settings_write', __( 'Ein Filter hat den geprüften Spectra-Wert verändert.', 'wp-agent-companion' ), array( 'status' => 409, 'mutation_started' => false ) );
	}
	if ( null === $before ) {
		try {
			$created = wpagent_companion_add_option_create_only( $name, $value, '', null );
		} catch ( Throwable $error ) {
			return new WP_Error( 'wpagent_spectra_settings_write', __( 'Die Spectra-Einstellung konnte nicht sicher angelegt werden.', 'wp-agent-companion' ), array( 'status' => 502, 'mutation_started' => false ) );
		}
		return $created ? true : new WP_Error( 'wpagent_spectra_settings_conflict', __( 'Die Spectra-Einstellung wurde gleichzeitig angelegt.', 'wp-agent-companion' ), array( 'status' => 409, 'mutation_started' => false ) );
	}
	$next = wpagent_spectra_settings_desired_row( $name, $value, $before );
	try {
		do_action( "update_option_{$name}", $old, $value, $name );
	} catch ( Throwable $error ) {
		return new WP_Error( 'wpagent_spectra_settings_write', __( 'Spectra konnte den Providerwert vor dem Schreiben nicht bestätigen.', 'wp-agent-companion' ), array( 'status' => 502, 'mutation_started' => false ) );
	}
	$changed = $wpdb->query( $wpdb->prepare(
		"UPDATE {$wpdb->options} SET option_value = %s, autoload = %s WHERE option_name = %s AND HEX(option_value) = HEX(%s) AND HEX(autoload) = HEX(%s)",
		$next['raw'], $next['autoload'], $name, $before['raw'], $before['autoload']
	) );
	wpagent_companion_forget_option_cache( $name, in_array( $before['autoload'], wp_autoload_values_to_autoload(), true ) || in_array( $next['autoload'], wp_autoload_values_to_autoload(), true ) );
	if ( 1 !== $changed ) {
		return new WP_Error( false === $changed ? 'wpagent_spectra_settings_write' : 'wpagent_spectra_settings_conflict', __( 'Die Spectra-Einstellung konnte nicht atomar gespeichert werden.', 'wp-agent-companion' ), array( 'status' => false === $changed ? 502 : 409, 'mutation_started' => false ) );
	}
	try {
		do_action( 'updated_option', $name, $old, $value );
	} catch ( Throwable $error ) {
		return new WP_Error( 'wpagent_spectra_settings_write', __( 'Spectra konnte den Providerwert nach dem Speichern nicht bestätigen.', 'wp-agent-companion' ), array( 'status' => 502, 'mutation_started' => true ) );
	}
	return true;
}

function wpagent_spectra_settings_restore_row( string $name, ?array $before, ?array $expected ): bool {
	global $wpdb;
	$current = wpagent_companion_read_option_row_direct( $name );
	if ( '' !== $wpdb->last_error ) {
		return false;
	}
	if ( wpagent_spectra_settings_rows_equal( $current, $before ) ) {
		return true;
	}
	if ( null === $current || ! wpagent_spectra_settings_rows_equal( $current, $expected ) ) {
		return false;
	}
	if ( null === $before ) {
		$changed = $wpdb->query( $wpdb->prepare(
			"DELETE FROM {$wpdb->options} WHERE option_name = %s AND HEX(option_value) = HEX(%s) AND HEX(autoload) = HEX(%s)",
			$name, $current['raw'], $current['autoload']
		) );
	} else {
		$changed = $wpdb->query( $wpdb->prepare(
			"UPDATE {$wpdb->options} SET option_value = %s, autoload = %s WHERE option_name = %s AND HEX(option_value) = HEX(%s) AND HEX(autoload) = HEX(%s)",
			$before['raw'], $before['autoload'], $name, $current['raw'], $current['autoload']
		) );
	}
	wpagent_companion_forget_option_cache( $name, in_array( $current['autoload'], wp_autoload_values_to_autoload(), true ) || ( is_array( $before ) && in_array( $before['autoload'], wp_autoload_values_to_autoload(), true ) ) );
	return 1 === $changed && wpagent_spectra_settings_rows_equal( wpagent_companion_read_option_row_direct( $name ), $before );
}

/** @param array<string,array{raw:string,autoload:string}|null> $before @param array<string,array{raw:string,autoload:string}|null> $expected */
function wpagent_spectra_settings_rollback( array $before, array $expected, array $written, string $token, int $blog_id ): bool {
	if ( get_current_blog_id() !== $blog_id || ! current_user_can( 'manage_options' ) || ! wpagent_companion_refresh_option_lock( WPAGENT_SPECTRA_SETTINGS_LOCK_OPTION, $token, WPAGENT_SPECTRA_SETTINGS_LOCK_TTL ) ) {
		return false;
	}
	foreach ( array_reverse( $written ) as $name ) {
		if ( ! wpagent_companion_refresh_option_lock( WPAGENT_SPECTRA_SETTINGS_LOCK_OPTION, $token, WPAGENT_SPECTRA_SETTINGS_LOCK_TTL ) ) {
			return false;
		}
		if ( ! wpagent_spectra_settings_restore_row( $name, $before[ $name ], $expected[ $name ] ) ) {
			return false;
		}
	}
	if ( ! wpagent_companion_refresh_option_lock( WPAGENT_SPECTRA_SETTINGS_LOCK_OPTION, $token, WPAGENT_SPECTRA_SETTINGS_LOCK_TTL ) ) {
		return false;
	}
	$fresh = wpagent_spectra_settings_rows();
	return is_array( $fresh ) && wpagent_spectra_settings_row_sets_equal( $fresh, $before );
}

function wpagent_spectra_settings_failure( array $before, array $expected, array $written, string $token, int $blog_id ): WP_Error {
	if ( wpagent_spectra_settings_rollback( $before, $expected, $written, $token, $blog_id ) ) {
		return new WP_Error( 'wpagent_spectra_settings_verification', __( 'Die Spectra-Änderung konnte nicht bestätigt werden. Der vorherige Zustand wurde atomar wiederhergestellt und verifiziert.', 'wp-agent-companion' ), array( 'status' => 502, 'rollback_verified' => true, 'recovery_required' => false ) );
	}
	return new WP_Error( 'wpagent_spectra_settings_recovery_required', __( 'Die Spectra-Änderung wurde begonnen, aber nicht vollständig verifiziert. Eine fremde oder unklare Änderung wurde nicht überschrieben. Prüfe die Einstellungen manuell und lies sie anschließend neu.', 'wp-agent-companion' ), array( 'status' => 500, 'rollback_verified' => false, 'recovery_required' => true ) );
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_update_spectra_editor_settings( $input ) {
	$validated = wpagent_spectra_settings_validate_update( $input );
	if ( is_wp_error( $validated ) ) {
		return $validated;
	}
	if ( ! current_user_can( 'manage_options' ) ) {
		return new WP_Error( 'wpagent_spectra_settings_permission', __( 'Du darfst die Spectra-Einstellungen nicht ändern.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	$token = wpagent_companion_acquire_option_lock( WPAGENT_SPECTRA_SETTINGS_LOCK_OPTION, WPAGENT_SPECTRA_SETTINGS_LOCK_TTL );
	if ( ! is_string( $token ) ) {
		return new WP_Error( 'wpagent_spectra_settings_locked', __( 'Die Spectra-Einstellungen werden gerade durch einen anderen Vorgang geändert.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	try {
		$blog_id      = (int) get_current_blog_id();
		$before_state = wpagent_spectra_editor_settings_state();
		$before_rows  = wpagent_spectra_settings_rows();
		if ( is_wp_error( $before_state ) || is_wp_error( $before_rows ) ) {
			return is_wp_error( $before_state ) ? $before_state : $before_rows;
		}
		$previous_hash = wpagent_spectra_editor_settings_hash( $before_state );
		if ( ! hash_equals( $previous_hash, $validated['expected_hash'] ) ) {
			return new WP_Error( 'wpagent_spectra_settings_conflict', __( 'Die Spectra-Einstellungen wurden seit dem Lesen verändert.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $previous_hash ) );
		}
		if ( array_key_exists( 'uag_select_font_globally', $validated['changes'] ) ) {
			$merged_families = wpagent_spectra_settings_merge_families( $validated['changes']['uag_select_font_globally'], $before_rows['uag_select_font_globally'] );
			if ( is_wp_error( $merged_families ) ) {
				return $merged_families;
			}
			$validated['changes']['uag_select_font_globally'] = $merged_families;
		}
		$expected = $before_rows;
		$pending  = array();
		foreach ( $validated['changes'] as $name => $value ) {
			$desired = wpagent_spectra_settings_desired_row( $name, $value, $before_rows[ $name ] );
			if ( ! wpagent_spectra_settings_rows_equal( $desired, $before_rows[ $name ] ) ) {
				$pending[ $name ]  = $value;
				$expected[ $name ] = $desired;
			}
		}
		if ( array() === $pending ) {
			$fresh_rows  = wpagent_spectra_settings_rows();
			$fresh_state = wpagent_spectra_editor_settings_state();
			if ( get_current_blog_id() !== $blog_id || ! current_user_can( 'manage_options' ) || ! wpagent_companion_refresh_option_lock( WPAGENT_SPECTRA_SETTINGS_LOCK_OPTION, $token, WPAGENT_SPECTRA_SETTINGS_LOCK_TTL ) || ! is_array( $fresh_rows ) || ! is_array( $fresh_state ) || ! wpagent_spectra_settings_row_sets_equal( $fresh_rows, $before_rows ) || ! hash_equals( $previous_hash, wpagent_spectra_editor_settings_hash( $fresh_state ) ) ) {
				return new WP_Error( 'wpagent_spectra_settings_conflict', __( 'Die Spectra-Einstellungen oder die Berechtigung änderten sich vor der No-op-Bestätigung.', 'wp-agent-companion' ), array( 'status' => 409 ) );
			}
			$fresh_state['state_hash']    = $previous_hash;
			$fresh_state['previous_hash'] = $previous_hash;
			$fresh_state['changed']       = false;
			$fresh_state['verified']      = true;
			return $fresh_state;
		}
		$written = array();
		foreach ( $pending as $name => $value ) {
			$gate = get_current_blog_id() === $blog_id
				&& current_user_can( 'manage_options' )
				&& wpagent_companion_refresh_option_lock( WPAGENT_SPECTRA_SETTINGS_LOCK_OPTION, $token, WPAGENT_SPECTRA_SETTINGS_LOCK_TTL )
				&& ! is_wp_error( wpagent_spectra_editor_settings_provider() );
			$current_rows = $gate ? wpagent_spectra_settings_rows() : null;
			if ( ! $gate || ! is_array( $current_rows ) || ! wpagent_spectra_settings_row_sets_equal( $current_rows, array_replace( $before_rows, array_intersect_key( $expected, array_flip( $written ) ) ) ) ) {
				return array() === $written
					? new WP_Error( 'wpagent_spectra_settings_conflict', __( 'Die Spectra-Einstellungen oder die Berechtigung änderten sich vor dem Speichern.', 'wp-agent-companion' ), array( 'status' => 409 ) )
					: wpagent_spectra_settings_failure( $before_rows, $expected, $written, $token, $blog_id );
			}
			$result = wpagent_spectra_settings_cas_write( $name, $value, $current_rows[ $name ] );
			if ( is_wp_error( $result ) ) {
				$error_data       = $result->get_error_data();
				$mutation_started = is_array( $error_data ) && true === ( $error_data['mutation_started'] ?? false );
				if ( $mutation_started ) {
					$written[] = $name;
				}
				return array() === $written ? $result : wpagent_spectra_settings_failure( $before_rows, $expected, $written, $token, $blog_id );
			}
			$written[] = $name;
			if ( ! wpagent_spectra_settings_rows_equal( wpagent_companion_read_option_row_direct( $name ), $expected[ $name ] ) ) {
				return wpagent_spectra_settings_failure( $before_rows, $expected, $written, $token, $blog_id );
			}
		}
		$fresh_rows = wpagent_spectra_settings_rows();
		$fresh      = wpagent_spectra_editor_settings_state();
		if ( get_current_blog_id() !== $blog_id || ! current_user_can( 'manage_options' ) || ! wpagent_companion_refresh_option_lock( WPAGENT_SPECTRA_SETTINGS_LOCK_OPTION, $token, WPAGENT_SPECTRA_SETTINGS_LOCK_TTL ) || ! is_array( $fresh_rows ) || ! is_array( $fresh ) || ! wpagent_spectra_settings_row_sets_equal( $fresh_rows, $expected ) ) {
			return wpagent_spectra_settings_failure( $before_rows, $expected, $written, $token, $blog_id );
		}
		$fresh['state_hash']    = wpagent_spectra_editor_settings_hash( $fresh );
		$fresh['previous_hash'] = $previous_hash;
		$fresh['changed']       = true;
		$fresh['verified']      = true;
		return $fresh;
	} finally {
		wpagent_companion_release_option_lock( WPAGENT_SPECTRA_SETTINGS_LOCK_OPTION, $token );
	}
}
