<?php
/** Native, version-bound controls for the separate Spectra Blocks separator. */

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

const WPAGENT_SPECTRA_BLOCKS_SEPARATOR_VERSION            = '1.0.4';
const WPAGENT_SPECTRA_BLOCKS_SEPARATOR_MAX_CONTENT_BYTES = 1048576;

/** @return array<int,string> */
function wpagent_spectra_blocks_separator_styles(): array {
	return array( 'solid', 'dotted', 'dashed', 'double', 'rectangles', 'parallelogram', 'slash', 'leaves' );
}

/** @return array<string,mixed>|WP_Error */
function wpagent_spectra_blocks_separator_contract() {
	$version = defined( 'SPECTRA_BLOCKS_VER' ) ? (string) SPECTRA_BLOCKS_VER : '';
	if ( ! hash_equals( WPAGENT_SPECTRA_BLOCKS_SEPARATOR_VERSION, $version ) ) {
		return new WP_Error( 'wpagent_spectra_blocks_separator_provider', __( 'Die native Separator-Integration erfordert exakt Spectra Blocks 1.0.4.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$type = WP_Block_Type_Registry::get_instance()->get_registered( 'spectra/separator' );
	if ( ! $type instanceof WP_Block_Type || 3 !== (int) $type->api_version || ! is_callable( $type->render_callback ) ) {
		return new WP_Error( 'wpagent_spectra_blocks_separator_provider', __( 'Der serverseitige Spectra-Blocks-Separatorvertrag ist nicht verfügbar.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$attributes = $type->get_attributes();
	foreach ( array( 'separatorStyle', 'separatorAlign', 'separatorWidth', 'separatorHeight', 'separatorColor', 'separatorSize' ) as $attribute ) {
		if ( ! is_array( $attributes[ $attribute ] ?? null ) || 'string' !== ( $attributes[ $attribute ]['type'] ?? null ) ) {
			return new WP_Error( 'wpagent_spectra_blocks_separator_provider', __( 'Das registrierte Spectra-Blocks-Providerschema stimmt nicht mit dem Separatorvertrag überein.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
	}
	return array( 'provider_version' => $version, 'block_name' => $type->name );
}

/** @return array<string,mixed> */
function wpagent_spectra_blocks_separator_settings_schema(): array {
	$properties = array(
		'separator_style'  => array( 'type' => 'string', 'enum' => wpagent_spectra_blocks_separator_styles() ),
		'separator_align'  => array( 'type' => 'string', 'enum' => array( 'left', 'center', 'right' ) ),
		'separator_width'  => array( 'type' => 'string', 'pattern' => '^(?:[1-9][0-9]?|100)%$|^(?:[1-9][0-9]{0,2}|1[0-9]{3}|2000)px$' ),
		'separator_height' => array( 'type' => 'string', 'pattern' => '^(?:[1-9][0-9]?|[1-3][0-9]{2}|400)px$' ),
		'separator_color'  => array( 'type' => 'string', 'pattern' => '^#[a-f0-9]{6}$' ),
	);
	return array( 'type' => 'object', 'properties' => $properties, 'required' => array_keys( $properties ), 'additionalProperties' => false );
}

/** @return array<string,mixed> */
function wpagent_ability_get_spectra_blocks_separator(): array {
	$settings = wpagent_spectra_blocks_separator_settings_schema();
	return array(
		'label'       => __( 'Spectra-Blocks-Separator lesen', 'wp-agent-companion' ),
		'description' => __( 'Liest ausschließlich einen serverseitig registrierten Separator des separaten Spectra-Blocks-Pakets 1.0.4 an einem expliziten Blockpfad.', 'wp-agent-companion' ),
		'category'    => 'wp-agent',
		'input_schema' => array(
			'type'       => 'object',
			'properties' => array(
				'post_id' => array( 'type' => 'integer', 'minimum' => 1 ),
				'path'    => array( 'type' => 'array', 'minItems' => 1, 'maxItems' => 32, 'items' => array( 'type' => 'integer', 'minimum' => 0, 'maximum' => 10000 ) ),
			),
			'required' => array( 'post_id', 'path' ), 'additionalProperties' => false,
		),
		'output_schema' => wpagent_spectra_blocks_separator_result_schema( $settings, false ),
		'execute_callback' => 'wpagent_exec_get_spectra_blocks_separator',
		'permission_callback' => 'wpagent_perm_edit_posts',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

/** @return array<string,mixed> */
function wpagent_ability_update_spectra_blocks_separator(): array {
	$settings = wpagent_spectra_blocks_separator_settings_schema();
	return array(
		'label'       => __( 'Spectra-Blocks-Separator aktualisieren', 'wp-agent-companion' ),
		'description' => __( 'Aktualisiert nur Stil, Ausrichtung, Breite, Höhe und Farbe eines exakt verifizierten Spectra-Blocks-Separators. Der Write ist an Blog, Inhaltshash, atomaren Vergleich, Revision, Rückleseprüfung und eine erneuerbare exklusive Sperre gebunden.', 'wp-agent-companion' ),
		'category'    => 'wp-agent',
		'input_schema' => array(
			'type'       => 'object',
			'properties' => array(
				'post_id'       => array( 'type' => 'integer', 'minimum' => 1 ),
				'path'          => array( 'type' => 'array', 'minItems' => 1, 'maxItems' => 32, 'items' => array( 'type' => 'integer', 'minimum' => 0, 'maximum' => 10000 ) ),
				'settings'      => array( 'type' => 'object', 'minProperties' => 1, 'maxProperties' => 5, 'properties' => $settings['properties'], 'additionalProperties' => false ),
				'expected_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
			),
			'required' => array( 'post_id', 'path', 'settings', 'expected_hash' ), 'additionalProperties' => false,
		),
		'output_schema' => wpagent_spectra_blocks_separator_result_schema( $settings, true ),
		'execute_callback' => 'wpagent_exec_update_spectra_blocks_separator',
		'permission_callback' => 'wpagent_perm_edit_posts',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => false ) ),
	);
}

/** @param array<string,mixed> $settings @return array<string,mixed> */
function wpagent_spectra_blocks_separator_result_schema( array $settings, bool $write ): array {
	$properties = array(
		'post_id'              => array( 'type' => 'integer' ),
		'path'                 => array( 'type' => 'array', 'items' => array( 'type' => 'integer' ) ),
		'version'              => array( 'type' => 'string', 'enum' => array( WPAGENT_SPECTRA_BLOCKS_SEPARATOR_VERSION ) ),
		'settings'             => $settings,
		'rendered_html_length' => array( 'type' => 'integer', 'minimum' => 1 ),
		'hash'                 => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
	);
	if ( $write ) {
		$properties += array(
			'changed'       => array( 'type' => 'boolean' ),
			'verified'      => array( 'type' => 'boolean' ),
			'revision_id'   => array( 'type' => 'integer', 'minimum' => 0 ),
			'previous_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
		);
	}
	return array( 'type' => 'object', 'properties' => $properties, 'required' => array_keys( $properties ), 'additionalProperties' => false );
}

/** @param mixed $settings @return array<string,string>|WP_Error */
function wpagent_spectra_blocks_separator_validate_settings( $settings, bool $complete = false ) {
	if ( ! is_array( $settings ) || wp_is_numeric_array( $settings ) || array() === $settings || count( $settings ) > 5 ) {
		return new WP_Error( 'wpagent_spectra_blocks_separator_settings', __( 'settings muss ein nicht leeres Objekt mit höchstens fünf bekannten Separatorwerten sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$allowed = array( 'separator_style', 'separator_align', 'separator_width', 'separator_height', 'separator_color' );
	if ( array_diff( array_keys( $settings ), $allowed ) ) {
		return new WP_Error( 'wpagent_spectra_blocks_separator_settings', __( 'settings enthält einen unbekannten Separatorwert.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	if ( $complete && array_diff( $allowed, array_keys( $settings ) ) ) {
		return new WP_Error( 'wpagent_spectra_blocks_separator_settings', __( 'Der gespeicherte Separatorzustand ist unvollständig.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	foreach ( $settings as $key => $value ) {
		if ( ! is_string( $value ) ) {
			return new WP_Error( 'wpagent_spectra_blocks_separator_settings', __( 'Jeder Separatorwert muss ein String sein.', 'wp-agent-companion' ), array( 'status' => 400, 'field' => $key ) );
		}
		$valid = match ( $key ) {
			'separator_style'  => in_array( $value, wpagent_spectra_blocks_separator_styles(), true ),
			'separator_align'  => in_array( $value, array( 'left', 'center', 'right' ), true ),
			'separator_width'  => wpagent_spectra_blocks_separator_dimension_valid( $value, 2000 ),
			'separator_height' => 1 === preg_match( '/^([1-9][0-9]{0,2})px$/D', $value ) && (int) $value <= 400,
			'separator_color'  => 1 === preg_match( '/^#[a-f0-9]{6}$/D', $value ),
		};
		if ( ! $valid ) {
			return new WP_Error( 'wpagent_spectra_blocks_separator_settings', __( 'Ein Separatorwert liegt außerhalb des eng begrenzten Providervertrags.', 'wp-agent-companion' ), array( 'status' => 400, 'field' => $key ) );
		}
	}
	return $settings;
}

function wpagent_spectra_blocks_separator_dimension_valid( string $value, int $max_px ): bool {
	if ( 1 === preg_match( '/^(?:[1-9][0-9]?|100)%$/D', $value ) ) {
		return true;
	}
	return 1 === preg_match( '/^([1-9][0-9]{0,3})px$/D', $value ) && (int) $value <= $max_px;
}

/** @param array<string,mixed> $block @return array<string,string>|WP_Error */
function wpagent_spectra_blocks_separator_settings_from_block( array $block ) {
	if ( 'spectra/separator' !== ( $block['blockName'] ?? null ) || ! empty( $block['innerBlocks'] ) || '<div class="wp-block-spectra-separator"></div>' !== ( $block['innerHTML'] ?? null ) || array( '<div class="wp-block-spectra-separator"></div>' ) !== ( $block['innerContent'] ?? null ) ) {
		return new WP_Error( 'wpagent_spectra_blocks_separator_target', __( 'Der Zielblock erfüllt nicht den engen nativen Separator-Markupvertrag.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$attributes = is_array( $block['attrs'] ?? null ) ? $block['attrs'] : array();
	$accepted   = array( 'separatorStyle', 'separatorAlign', 'separatorWidth', 'separatorHeight', 'separatorColor', 'separatorSize', 'responsiveControls', 'isPreview' );
	if ( array_diff( array_keys( $attributes ), $accepted ) || ( isset( $attributes['isPreview'] ) && false !== $attributes['isPreview'] ) ) {
		return new WP_Error( 'wpagent_spectra_blocks_separator_target', __( 'Der Zielseparator enthält nicht freigegebene Providerattribute.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$desktop = $attributes['responsiveControls']['lg'] ?? null;
	if ( ! is_array( $attributes['responsiveControls'] ?? null ) || array_diff( array_keys( $attributes['responsiveControls'] ), array( 'lg' ) ) || ! is_array( $desktop ) || array_diff( array_keys( $desktop ), array( 'separatorStyle', 'separatorAlign', 'separatorWidth', 'separatorHeight', 'separatorSize' ) ) ) {
		return new WP_Error( 'wpagent_spectra_blocks_separator_target', __( 'Der Zielseparator enthält keine vollständig verifizierbare Spectra-Desktopsteuerung.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	foreach ( array( 'separatorStyle', 'separatorAlign', 'separatorWidth', 'separatorHeight', 'separatorSize' ) as $key ) {
		if ( ! isset( $attributes[ $key ] ) || ! is_string( $attributes[ $key ] ) || $attributes[ $key ] !== ( $desktop[ $key ] ?? null ) ) {
			return new WP_Error( 'wpagent_spectra_blocks_separator_target', __( 'Der gespeicherte und der tatsächlich gerenderte Spectra-Separatorzustand weichen voneinander ab.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
	}
	if ( ! isset( $attributes['separatorColor'] ) || ! is_string( $attributes['separatorColor'] ) ) {
		return new WP_Error( 'wpagent_spectra_blocks_separator_target', __( 'Dem Zielseparator fehlt eine eindeutig lesbare Farbe.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$settings = array(
		'separator_style'  => $attributes['separatorStyle'],
		'separator_align'  => $attributes['separatorAlign'],
		'separator_width'  => $attributes['separatorWidth'],
		'separator_height' => $attributes['separatorHeight'],
		'separator_color'  => $attributes['separatorColor'],
	);
	$valid = wpagent_spectra_blocks_separator_validate_settings( $settings, true );
	if ( is_wp_error( $valid ) ) {
		return new WP_Error( 'wpagent_spectra_blocks_separator_target', __( 'Der gespeicherte Separatorzustand verletzt den nativen Vertrag.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	if ( ! wpagent_spectra_blocks_separator_dimension_valid( $attributes['separatorSize'], 2000 ) ) {
		return new WP_Error( 'wpagent_spectra_blocks_separator_target', __( 'separatorSize verletzt den nativen Providervertrag.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	return $valid;
}

/** @param array<int,array<string,mixed>> $blocks @param array<int,int> $path @return array<string,mixed>|WP_Error */
function wpagent_spectra_blocks_separator_target_at_path( array $blocks, array $path, int $depth = 0 ) {
	$index = $path[ $depth ];
	if ( ! isset( $blocks[ $index ] ) || ! is_array( $blocks[ $index ] ) ) {
		return new WP_Error( 'wpagent_spectra_blocks_separator_path', __( 'Der Separatorpfad wurde im aktuellen Dokument nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
	}
	if ( $depth + 1 < count( $path ) ) {
		$inner = $blocks[ $index ]['innerBlocks'] ?? null;
		if ( ! is_array( $inner ) ) {
			return new WP_Error( 'wpagent_spectra_blocks_separator_path', __( 'Der Separatorpfad wurde im aktuellen Dokument nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
		}
		return wpagent_spectra_blocks_separator_target_at_path( $inner, $path, $depth + 1 );
	}
	return $blocks[ $index ];
}

/** @param array<int,array<string,mixed>> $blocks @param array<int,int> $path @param array<string,string> $settings @return array<string,mixed>|WP_Error */
function wpagent_spectra_blocks_separator_patch_path( array &$blocks, array $path, array $settings, int $depth = 0 ) {
	$index = $path[ $depth ];
	if ( ! isset( $blocks[ $index ] ) || ! is_array( $blocks[ $index ] ) ) {
		return new WP_Error( 'wpagent_spectra_blocks_separator_path', __( 'Der Separatorpfad wurde im aktuellen Dokument nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
	}
	if ( $depth + 1 < count( $path ) ) {
		if ( ! isset( $blocks[ $index ]['innerBlocks'] ) || ! is_array( $blocks[ $index ]['innerBlocks'] ) ) {
			return new WP_Error( 'wpagent_spectra_blocks_separator_path', __( 'Der Separatorpfad wurde im aktuellen Dokument nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
		}
		return wpagent_spectra_blocks_separator_patch_path( $blocks[ $index ]['innerBlocks'], $path, $settings, $depth + 1 );
	}
	$before = wpagent_spectra_blocks_separator_settings_from_block( $blocks[ $index ] );
	if ( is_wp_error( $before ) ) {
		return $before;
	}
	$after = array_replace( $before, $settings );
	$valid = wpagent_spectra_blocks_separator_validate_settings( $after, true );
	if ( is_wp_error( $valid ) ) {
		return $valid;
	}
	if ( $before === $valid ) {
		return array( 'settings' => $before, 'changed' => false );
	}
	$map = array( 'separator_style' => 'separatorStyle', 'separator_align' => 'separatorAlign', 'separator_width' => 'separatorWidth', 'separator_height' => 'separatorHeight', 'separator_color' => 'separatorColor' );
	foreach ( $settings as $key => $value ) {
		$blocks[ $index ]['attrs'][ $map[ $key ] ] = $value;
		if ( 'separator_color' !== $key ) {
			$blocks[ $index ]['attrs']['responsiveControls']['lg'][ $map[ $key ] ] = $value;
		}
	}
	return array( 'settings' => $valid, 'changed' => true );
}

function wpagent_spectra_blocks_separator_rendered_markup_matches( string $html ): bool {
	return 1 === preg_match( '/<div[^>]*data-spectra-id="spectra-[a-f0-9-]{36}"[^>]*class="[^"]*wp-block-spectra-separator[^"]*"[^>]*>\\s*<div\\s+class="spectra-separator-line"[^>]*>\\s*<\\/div>\\s*<\\/div>/is', $html );
}

/** @param array<string,mixed> $block @return string|WP_Error */
function wpagent_spectra_blocks_separator_render_target( array $block ) {
	$settings = wpagent_spectra_blocks_separator_settings_from_block( $block );
	if ( is_wp_error( $settings ) ) {
		return $settings;
	}
	try {
		$html = do_blocks( serialize_blocks( array( $block ) ) );
	} catch ( Throwable $error ) {
		return new WP_Error( 'wpagent_spectra_blocks_separator_render', __( 'Der Spectra-Blocks-Separator konnte nicht serverseitig gerendert werden.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	if ( ! is_string( $html ) || ! str_contains( $html, 'wp-block-spectra-separator' ) || ! str_contains( $html, 'spectra-separator-line' ) ) {
		return new WP_Error( 'wpagent_spectra_blocks_separator_render', __( 'Der serverseitige Spectra-Blocks-Separator-Output erfüllt den Frontendvertrag nicht.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	if ( ! wpagent_spectra_blocks_separator_rendered_markup_matches( $html ) ) {
		return new WP_Error( 'wpagent_spectra_blocks_separator_render', __( 'Der serverseitige Spectra-Blocks-Separator-Output erfüllt nicht den verifizierten Provider-Markupvertrag.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	return $html;
}

/** @param array<int,array<string,mixed>> $blocks @param array<int,int> $path @return array{settings:array<string,string>,html:string}|WP_Error */
function wpagent_spectra_blocks_separator_target_state( array $blocks, array $path ) {
	$target = wpagent_spectra_blocks_separator_target_at_path( $blocks, $path );
	if ( is_wp_error( $target ) ) {
		return $target;
	}
	$settings = wpagent_spectra_blocks_separator_settings_from_block( $target );
	if ( is_wp_error( $settings ) ) {
		return $settings;
	}
	$html = wpagent_spectra_blocks_separator_render_target( $target );
	return is_wp_error( $html ) ? $html : array( 'settings' => $settings, 'html' => $html );
}

/** @param array<int,array<string,mixed>> $blocks */
function wpagent_spectra_blocks_separator_has_patchable_block( array $blocks ): bool {
	if ( is_wp_error( wpagent_spectra_blocks_separator_contract() ) ) {
		return false;
	}
	foreach ( $blocks as $block ) {
		if ( ! is_array( $block ) ) {
			continue;
		}
		if ( 'spectra/separator' === ( $block['blockName'] ?? null ) && ! is_wp_error( wpagent_spectra_blocks_separator_settings_from_block( $block ) ) ) {
			return true;
		}
		if ( ! empty( $block['innerBlocks'] ) && is_array( $block['innerBlocks'] ) && wpagent_spectra_blocks_separator_has_patchable_block( $block['innerBlocks'] ) ) {
			return true;
		}
	}
	return false;
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_get_spectra_blocks_separator( $input ) {
	$input = is_array( $input ) ? $input : array();
	$post_id = absint( $input['post_id'] ?? 0 );
	$path = is_array( $input['path'] ?? null ) ? $input['path'] : array();
	$valid_path = wpagent_native_block_validate_path( $path );
	if ( is_wp_error( $valid_path ) ) {
		return $valid_path;
	}
	$contract = wpagent_spectra_blocks_separator_contract();
	if ( is_wp_error( $contract ) ) {
		return $contract;
	}
	$document = wpagent_native_block_document_state( $post_id );
	if ( is_wp_error( $document ) ) {
		return $document;
	}
	if ( strlen( $document['content'] ) > WPAGENT_SPECTRA_BLOCKS_SEPARATOR_MAX_CONTENT_BYTES || serialize_blocks( parse_blocks( $document['content'] ) ) !== $document['content'] ) {
		return new WP_Error( 'wpagent_spectra_blocks_separator_document', __( 'Das Separator-Dokument ist zu groß oder nicht stabil serialisierbar.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$target = wpagent_spectra_blocks_separator_target_state( parse_blocks( $document['content'] ), $path );
	if ( is_wp_error( $target ) ) {
		return $target;
	}
	return array( 'post_id' => $post_id, 'path' => $path, 'version' => $contract['provider_version'], 'settings' => $target['settings'], 'rendered_html_length' => strlen( $target['html'] ), 'hash' => $document['hash'] );
}

/** @return WP_Error */
function wpagent_spectra_blocks_separator_recovery_required( int $revision_id, array $rollback ) {
	return new WP_Error(
		'wpagent_spectra_blocks_separator_recovery_required',
		__( 'Die Spectra-Blocks-Änderung konnte nicht sicher rückgelesen werden. Eine fremde Änderung wird nicht überschrieben. Prüfe bei Bedarf die angelegte Revision.', 'wp-agent-companion' ),
		array( 'status' => 500, 'revision_id' => $revision_id, 'rolled_back' => $rollback['rolled_back'], 'rollback_verified' => $rollback['rollback_verified'], 'recovery_required' => $rollback['recovery_required'] )
	);
}

/** @return WP_Error */
function wpagent_spectra_blocks_separator_lock_lost( int $revision_id = 0 ) {
	return new WP_Error( 'wpagent_spectra_blocks_separator_lock_lost', __( 'Die erneuerbare exklusive Sperre ging während der Spectra-Blocks-Änderung verloren.', 'wp-agent-companion' ), array( 'status' => 409, 'revision_id' => $revision_id, 'recovery_required' => $revision_id > 0 ) );
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_update_spectra_blocks_separator( $input ) {
	$input = is_array( $input ) ? $input : array();
	$post_id = absint( $input['post_id'] ?? 0 );
	$path = is_array( $input['path'] ?? null ) ? $input['path'] : array();
	$valid_path = wpagent_native_block_validate_path( $path );
	if ( is_wp_error( $valid_path ) ) {
		return $valid_path;
	}
	$settings = wpagent_spectra_blocks_separator_validate_settings( $input['settings'] ?? null );
	if ( is_wp_error( $settings ) ) {
		return $settings;
	}
	$expected_hash = is_string( $input['expected_hash'] ?? null ) ? $input['expected_hash'] : '';
	if ( 1 !== preg_match( '/^[a-f0-9]{64}$/D', $expected_hash ) ) {
		return new WP_Error( 'wpagent_spectra_blocks_separator_hash', __( 'expected_hash muss ein SHA-256-Hash sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$contract = wpagent_spectra_blocks_separator_contract();
	if ( is_wp_error( $contract ) ) {
		return $contract;
	}
	$lock = wpagent_site_editor_acquire_lock( 'spectra-blocks-separator', (string) $post_id );
	if ( is_wp_error( $lock ) ) {
		return $lock;
	}
	try {
		$before = wpagent_native_block_document_state( $post_id );
		if ( is_wp_error( $before ) ) {
			return $before;
		}
		if ( ! hash_equals( $before['hash'], $expected_hash ) ) {
			return new WP_Error( 'wpagent_spectra_blocks_separator_conflict', __( 'Das Blockdokument wurde seit dem Lesen verändert.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $before['hash'] ) );
		}
		if ( strlen( $before['content'] ) > WPAGENT_SPECTRA_BLOCKS_SEPARATOR_MAX_CONTENT_BYTES || serialize_blocks( parse_blocks( $before['content'] ) ) !== $before['content'] ) {
			return new WP_Error( 'wpagent_spectra_blocks_separator_document', __( 'Das Separator-Dokument ist zu groß oder nicht stabil serialisierbar.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
		$blocks = parse_blocks( $before['content'] );
		$target = wpagent_spectra_blocks_separator_patch_path( $blocks, $path, $settings );
		if ( is_wp_error( $target ) ) {
			return $target;
		}
		if ( ! wpagent_site_editor_refresh_lock( 'spectra-blocks-separator', (string) $post_id, $lock ) ) {
			return wpagent_spectra_blocks_separator_lock_lost();
		}
		if ( ! $target['changed'] ) {
			$fresh = wpagent_native_block_raw_content( $post_id );
			if ( is_wp_error( $fresh ) || $fresh !== $before['content'] || ! wpagent_site_editor_lock_is_owned( 'spectra-blocks-separator', (string) $post_id, $lock ) ) {
				return wpagent_spectra_blocks_separator_lock_lost();
			}
			$no_op_target = wpagent_spectra_blocks_separator_target_state( $blocks, $path );
			if ( is_wp_error( $no_op_target ) ) {
				return $no_op_target;
			}
			return array( 'post_id' => $post_id, 'path' => $path, 'version' => $contract['provider_version'], 'settings' => $target['settings'], 'changed' => false, 'verified' => true, 'revision_id' => 0, 'rendered_html_length' => strlen( $no_op_target['html'] ), 'previous_hash' => $before['hash'], 'hash' => $before['hash'] );
		}
		$candidate = serialize_blocks( $blocks );
		if ( strlen( $candidate ) > WPAGENT_SPECTRA_BLOCKS_SEPARATOR_MAX_CONTENT_BYTES || serialize_blocks( parse_blocks( $candidate ) ) !== $candidate ) {
			return new WP_Error( 'wpagent_spectra_blocks_separator_document', __( 'Der geänderte Separatorzustand ist nicht stabil serialisierbar.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		$candidate_target = wpagent_spectra_blocks_separator_target_state( parse_blocks( $candidate ), $path );
		if ( is_wp_error( $candidate_target ) || $candidate_target['settings'] !== $target['settings'] ) {
			return new WP_Error( 'wpagent_spectra_blocks_separator_document', __( 'Der geänderte Separatorzustand verletzt den nativen Rendervertrag.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		if ( ! wpagent_site_editor_refresh_lock( 'spectra-blocks-separator', (string) $post_id, $lock ) ) {
			return wpagent_spectra_blocks_separator_lock_lost();
		}
		$revision_id = wpagent_native_block_create_revision( $post_id, $before['content'] );
		if ( is_wp_error( $revision_id ) ) {
			return $revision_id;
		}
		if ( ! wpagent_site_editor_refresh_lock( 'spectra-blocks-separator', (string) $post_id, $lock ) ) {
			return wpagent_spectra_blocks_separator_lock_lost( $revision_id );
		}
		$saved = wpagent_native_block_write_if_current( $post_id, $before['content'], $candidate );
		if ( is_wp_error( $saved ) ) {
			return $saved;
		}
		if ( ! wpagent_site_editor_lock_is_owned( 'spectra-blocks-separator', (string) $post_id, $lock ) ) {
			return wpagent_spectra_blocks_separator_lock_lost( $revision_id );
		}
		$after_raw = wpagent_native_block_raw_content( $post_id );
		$after = wpagent_native_block_document_state( $post_id );
		$after_target = ! is_wp_error( $after_raw ) && $after_raw === $candidate ? wpagent_spectra_blocks_separator_target_state( parse_blocks( $after_raw ), $path ) : null;
		$verified = is_string( $after_raw ) && $after_raw === $candidate && is_array( $after ) && ! is_wp_error( $after ) && $after['content'] === $candidate && is_array( $after_target ) && $after_target['settings'] === $target['settings'];
		if ( ! $verified ) {
			$rollback = wpagent_native_block_rollback( $post_id, $before['content'], $candidate );
			return wpagent_spectra_blocks_separator_recovery_required( $revision_id, $rollback );
		}
		if ( ! wpagent_site_editor_refresh_lock( 'spectra-blocks-separator', (string) $post_id, $lock ) ) {
			return wpagent_spectra_blocks_separator_lock_lost( $revision_id );
		}
		return array( 'post_id' => $post_id, 'path' => $path, 'version' => $contract['provider_version'], 'settings' => $after_target['settings'], 'changed' => true, 'verified' => true, 'revision_id' => $revision_id, 'rendered_html_length' => strlen( $after_target['html'] ), 'previous_hash' => $before['hash'], 'hash' => $after['hash'] );
	} finally {
		wpagent_site_editor_release_lock( 'spectra-blocks-separator', (string) $post_id, $lock );
	}
}
