<?php
/** Abilities für den bestätigten Live-Arbeitsbereich im geöffneten WordPress-Editor. */

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

/** @return array<string,mixed> */
function wpagent_live_editor_command_output_schema(): array {
	return array(
		'type'       => 'object',
		'properties' => array(
			'command_id' => array( 'type' => 'string' ),
			'action' => array( 'type' => 'string' ),
			'status' => array( 'type' => 'string' ),
			'requires_confirmation' => array( 'type' => 'boolean' ),
			'created_at' => array( 'type' => 'string' ),
			'expires_at' => array( 'type' => 'string' ),
			'result' => array( 'type' => 'object' ),
			'error' => array( 'type' => 'string' ),
		),
	);
}

function wpagent_perm_live_editor( $input = null ): bool {
	$user = wp_get_current_user();
	return $user instanceof WP_User && $user->exists() && wpagent_companion_is_safe_connection_user( $user );
}

/** @return array<string,mixed> */
function wpagent_ability_get_live_editor_status(): array {
	return array(
		'label' => __( 'Live-Editor-Status lesen', 'wp-agent-companion' ),
		'description' => __( 'Liest die aktive, im WordPress-Backend geöffnete Live-Editor-Sitzung dieses Agent-Nutzers. Öffne den Live-Editor zuerst als Administrator. Verwende danach live-editor-read oder live-editor-write und frage das Ergebnis über get-live-editor-result ab.', 'wp-agent-companion' ),
		'category' => 'wp-agent',
		'input_schema' => array( 'type' => 'object', 'properties' => array(), 'default' => array() ),
		'output_schema' => array(
			'type' => 'object',
			'properties' => array(
				'session_id' => array( 'type' => 'string' ),
				'status' => array( 'type' => 'string' ),
				'executor_id' => array( 'type' => 'integer' ),
				'created_at' => array( 'type' => 'string' ),
				'expires_at' => array( 'type' => 'string' ),
				'last_seen_at' => array( 'type' => 'string' ),
				'pending_commands' => array( 'type' => 'integer' ),
				'page' => array( 'type' => 'object' ),
			),
		),
		'execute_callback' => 'wpagent_exec_get_live_editor_status',
		'permission_callback' => 'wpagent_perm_live_editor',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

/** @return array<string,mixed> */
function wpagent_ability_live_editor_read(): array {
	return array(
		'label' => __( 'Im Live-Editor lesen', 'wp-agent-companion' ),
		'description' => __( 'Stellt einen lesenden Befehl in die aktive Browser-Arbeitsfläche. Unterstützt Seiteninspektion, Gutenberg-Struktur, Blocktypen, Blockschema und Blockattribute. Die Antwort enthält eine command_id. Frage den Abschluss über get-live-editor-result ab.', 'wp-agent-companion' ),
		'category' => 'wp-agent',
		'input_schema' => array(
			'type' => 'object',
			'properties' => array(
				'action' => array( 'type' => 'string', 'enum' => array( 'inspect-page', 'gutenberg-structure', 'list-block-types', 'get-block-schema', 'get-block-attributes' ) ),
				'block_name' => array( 'type' => 'string' ),
				'client_id' => array( 'type' => 'string' ),
				'include_text' => array( 'type' => 'boolean', 'default' => false ),
				'text_limit' => array( 'type' => 'integer', 'minimum' => 1, 'maximum' => 10000, 'default' => 3000 ),
				'search' => array( 'type' => 'string' ),
			),
			'required' => array( 'action' ),
		),
		'output_schema' => wpagent_live_editor_command_output_schema(),
		'execute_callback' => 'wpagent_exec_live_editor_read',
		'permission_callback' => 'wpagent_perm_live_editor',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => false ) ),
	);
}

/** @return array<string,mixed> */
function wpagent_ability_live_editor_write(): array {
	return array(
		'label' => __( 'Im Live-Editor bestätigt handeln', 'wp-agent-companion' ),
		'description' => __( 'Stellt eine sichtbare Aktion in die aktive Browser-Arbeitsfläche. Der Administrator muss jeden Befehl dort einzeln bestätigen. Blockänderungen bleiben zunächst ungespeichert. Erst save-post persistiert den sichtbaren Editorzustand. Jede zustandsändernde Aktion verlangt den aktuellen expected_state_hash.', 'wp-agent-companion' ),
		'category' => 'wp-agent',
		'input_schema' => array(
			'type' => 'object',
			'properties' => array(
				'action' => array( 'type' => 'string', 'enum' => array( 'open-post', 'create-block', 'update-block', 'delete-block', 'move-block', 'replace-inner-blocks', 'undo', 'redo', 'save-post', 'finalize-provider-attributes' ) ),
				'reason' => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 500 ),
				'expected_state_hash' => array( 'type' => 'string' ),
				'expected_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'post_id' => array( 'type' => 'integer', 'minimum' => 1 ),
				'client_id' => array( 'type' => 'string' ),
				'parent_client_id' => array( 'type' => 'string' ),
				'block_name' => array( 'type' => 'string' ),
				'index' => array( 'type' => 'integer', 'minimum' => 0, 'maximum' => 10000 ),
				'attributes' => array( 'type' => 'object' ),
				'blocks' => array( 'type' => 'array', 'maxItems' => 200, 'items' => array( 'type' => 'object' ) ),
			),
			'required' => array( 'action', 'reason' ),
		),
		'output_schema' => wpagent_live_editor_command_output_schema(),
		'execute_callback' => 'wpagent_exec_live_editor_write',
		'permission_callback' => 'wpagent_perm_live_editor',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => true, 'idempotent' => false ) ),
	);
}

/** @return array<string,mixed> */
function wpagent_ability_live_editor_elementor_write(): array {
	return array(
		'label' => __( 'Elementor im Live-Editor bestätigt ändern', 'wp-agent-companion' ),
		'description' => __( 'Stellt eine einzelne Elementor-Free-Dokumentänderung in die sichtbare Arbeitsfläche. Ein Administrator muss jede Operation einzeln bestätigen. Die Änderung läuft anschließend ausschließlich über Elementors geprüfte Server-API mit Konfliktschutz, Revision, Rückleseprüfung, Frontend-Prüfung und Rollback.', 'wp-agent-companion' ),
		'category' => 'wp-agent',
		'input_schema' => array(
			'type' => 'object',
			'properties' => array(
				'operation' => array( 'type' => 'string', 'enum' => array( 'open-document', 'update-document', 'update-element', 'create-element', 'duplicate-element', 'move-element', 'delete-element', 'restore-revision' ) ),
				'reason' => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 500 ),
				'post_id' => array( 'type' => 'integer', 'minimum' => 1 ),
				'expected_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'element_id' => array( 'type' => 'string', 'pattern' => '^[A-Za-z0-9_-]{1,64}$' ),
				'parent_id' => array( 'type' => 'string', 'pattern' => '^[A-Za-z0-9_-]{1,64}$' ),
				'index' => array( 'type' => 'integer', 'minimum' => 0, 'maximum' => WPAGENT_ELEMENTOR_MAX_ELEMENTS ),
				'element' => array( 'type' => 'object', 'additionalProperties' => true ),
				'elements' => wpagent_elementor_elements_input_schema(),
				'settings' => array( 'type' => 'object', 'additionalProperties' => true ),
				'settings_patch' => array( 'type' => 'object', 'additionalProperties' => true ),
				'remove_settings' => array( 'type' => 'array', 'maxItems' => 100, 'items' => array( 'type' => 'string' ) ),
				'style_patch' => array( 'type' => 'object', 'additionalProperties' => true ),
				'revision_id' => array( 'type' => 'integer', 'minimum' => 1 ),
			),
			'required' => array( 'operation', 'reason', 'post_id' ),
		),
		'output_schema' => wpagent_live_editor_command_output_schema(),
		'execute_callback' => 'wpagent_exec_live_editor_elementor_write',
		'permission_callback' => 'wpagent_perm_live_editor',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => true, 'idempotent' => false ) ),
	);
}

/** @return array<string,mixed> */
function wpagent_ability_get_live_editor_result(): array {
	return array(
		'label' => __( 'Live-Editor-Ergebnis lesen', 'wp-agent-companion' ),
		'description' => __( 'Liest Status und Ergebnis eines zuvor eingereihten Live-Editor-Befehls. pending, running oder awaiting_confirmation bedeutet, dass du nach kurzer Wartezeit erneut fragen sollst.', 'wp-agent-companion' ),
		'category' => 'wp-agent',
		'input_schema' => array(
			'type' => 'object',
			'properties' => array( 'command_id' => array( 'type' => 'string' ) ),
			'required' => array( 'command_id' ),
		),
		'output_schema' => wpagent_live_editor_command_output_schema(),
		'execute_callback' => 'wpagent_exec_get_live_editor_result',
		'permission_callback' => 'wpagent_perm_live_editor',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_get_live_editor_status( $input = array() ) {
	if ( ! wpagent_perm_live_editor() ) {
		return new WP_Error( 'wpagent_live_editor_forbidden', __( 'Der Live-Editor ist nur für den gebundenen Nicht-Administrator mit Inhaltsrechten verfügbar.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	$session = wpagent_companion_live_editor_agent_session();
	return is_wp_error( $session ) ? $session : wpagent_companion_live_editor_public_session( $session );
}

function wpagent_live_editor_clean_identifier( $value, string $field ) {
	if ( ! is_string( $value ) || ! preg_match( '/^[A-Za-z0-9_-]{1,100}$/D', $value ) ) {
		return new WP_Error(
			'wpagent_live_editor_' . $field,
			sprintf(
				/* translators: %s: machine-readable Live Editor field name. */
				__( '%s ist ungültig.', 'wp-agent-companion' ),
				$field
			),
			array( 'status' => 400 )
		);
	}
	return $value;
}

function wpagent_live_editor_clean_block_name( $value ) {
	if ( ! is_string( $value ) || ! preg_match( '#^[a-z0-9][a-z0-9-]{0,63}/[a-z0-9][a-z0-9-]{0,63}$#D', $value ) ) {
		return new WP_Error( 'wpagent_live_editor_block_name', __( 'block_name muss ein gültiger registrierter Blockname sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	return $value;
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_live_editor_read( $input ) {
	if ( ! wpagent_perm_live_editor() ) {
		return new WP_Error( 'wpagent_live_editor_forbidden', __( 'Keine Berechtigung.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	$input   = is_array( $input ) ? $input : array();
	$action  = is_string( $input['action'] ?? null ) ? $input['action'] : '';
	$allowed = array( 'inspect-page', 'gutenberg-structure', 'list-block-types', 'get-block-schema', 'get-block-attributes' );
	if ( ! in_array( $action, $allowed, true ) ) {
		return new WP_Error( 'wpagent_live_editor_action', __( 'Unbekannter lesender Live-Editor-Befehl.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$args = array();
	if ( 'inspect-page' === $action ) {
		$args['include_text'] = true === ( $input['include_text'] ?? false );
		$args['text_limit']   = max( 1, min( 10000, absint( $input['text_limit'] ?? 3000 ) ) );
	} elseif ( 'list-block-types' === $action ) {
		$search = is_string( $input['search'] ?? null ) ? sanitize_text_field( $input['search'] ) : '';
		if ( strlen( $search ) > 100 ) {
			return new WP_Error( 'wpagent_live_editor_search', __( 'search darf höchstens 100 Byte lang sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		$args['search'] = $search;
	} elseif ( 'get-block-schema' === $action ) {
		$name = wpagent_live_editor_clean_block_name( $input['block_name'] ?? null );
		if ( is_wp_error( $name ) ) return $name;
		$args['block_name'] = $name;
	} elseif ( 'get-block-attributes' === $action ) {
		$id = wpagent_live_editor_clean_identifier( $input['client_id'] ?? null, 'client_id' );
		if ( is_wp_error( $id ) ) return $id;
		$args['client_id'] = $id;
	}
	return wpagent_companion_live_editor_queue_command( $action, $args, false );
}

function wpagent_live_editor_state_hash( array $input, string $action ) {
	if ( 'open-post' === $action ) return '';
	$value = $input['expected_state_hash'] ?? null;
	if ( ! is_string( $value ) || ! preg_match( '/^[a-f0-9]{64}$/D', $value ) ) {
		return new WP_Error( 'wpagent_live_editor_state_hash', __( 'expected_state_hash muss der aktuelle 64-stellige SHA-256-Zustand des geöffneten Editors sein.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	return $value;
}

/** @return string|WP_Error */
function wpagent_live_editor_elementor_identifier( $value, string $field ) {
	if ( ! is_string( $value ) || ! preg_match( '/^[A-Za-z0-9_-]{1,64}$/D', $value ) ) {
		return new WP_Error( 'wpagent_live_editor_elementor_' . $field, sprintf( __( '%s ist ungültig.', 'wp-agent-companion' ), $field ), array( 'status' => 400 ) );
	}
	return $value;
}

/** @return array<string,mixed>|WP_Error */
function wpagent_live_editor_elementor_command_args( array $input ) {
	$operation = is_string( $input['operation'] ?? null ) ? $input['operation'] : '';
	if ( ! in_array( $operation, wpagent_companion_live_editor_elementor_operations(), true ) ) {
		return new WP_Error( 'wpagent_live_editor_elementor_operation', __( 'Unbekannte Elementor-Live-Editor-Operation.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$reason = is_string( $input['reason'] ?? null ) ? trim( sanitize_text_field( $input['reason'] ) ) : '';
	$post_id = absint( $input['post_id'] ?? 0 );
	if ( '' === $reason || strlen( $reason ) > 500 || $post_id < 1 ) {
		return new WP_Error( 'wpagent_live_editor_elementor_input', __( 'reason und post_id sind erforderlich.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$allowed = array(
		'open-document' => array( 'operation', 'reason', 'post_id' ),
		'update-document' => array( 'operation', 'reason', 'post_id', 'expected_hash', 'elements', 'settings' ),
		'update-element' => array( 'operation', 'reason', 'post_id', 'expected_hash', 'element_id', 'settings_patch', 'remove_settings', 'style_patch' ),
		'create-element' => array( 'operation', 'reason', 'post_id', 'expected_hash', 'parent_id', 'index', 'element' ),
		'duplicate-element' => array( 'operation', 'reason', 'post_id', 'expected_hash', 'element_id', 'parent_id', 'index' ),
		'move-element' => array( 'operation', 'reason', 'post_id', 'expected_hash', 'element_id', 'parent_id', 'index' ),
		'delete-element' => array( 'operation', 'reason', 'post_id', 'expected_hash', 'element_id' ),
		'restore-revision' => array( 'operation', 'reason', 'post_id', 'expected_hash', 'revision_id' ),
	);
	if ( array_diff( array_keys( $input ), $allowed[ $operation ] ) ) {
		return new WP_Error( 'wpagent_live_editor_elementor_fields', __( 'Die Elementor-Operation enthält nicht erlaubte Felder.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$args = array( 'operation' => $operation, 'reason' => $reason, 'post_id' => $post_id );
	if ( 'open-document' === $operation ) {
		return $args;
	}
	$expected_hash = is_string( $input['expected_hash'] ?? null ) ? $input['expected_hash'] : '';
	if ( ! preg_match( '/^[a-f0-9]{64}$/D', $expected_hash ) ) {
		return new WP_Error( 'wpagent_live_editor_elementor_hash', __( 'expected_hash muss der aktuelle Elementor-SHA-256-Zustand sein.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$args['expected_hash'] = $expected_hash;
	foreach ( array( 'element_id', 'parent_id' ) as $field ) {
		if ( array_key_exists( $field, $input ) ) {
			$value = wpagent_live_editor_elementor_identifier( $input[ $field ], $field );
			if ( is_wp_error( $value ) ) {
				return $value;
			}
			$args[ $field ] = $value;
		}
	}
	if ( in_array( $operation, array( 'update-element', 'duplicate-element', 'move-element', 'delete-element' ), true ) && ! isset( $args['element_id'] ) ) {
		return new WP_Error( 'wpagent_live_editor_elementor_element_id', __( 'element_id ist für diese Elementor-Operation erforderlich.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	if ( in_array( $operation, array( 'create-element', 'duplicate-element', 'move-element' ), true ) ) {
		$args['index'] = max( 0, min( WPAGENT_ELEMENTOR_MAX_ELEMENTS, absint( $input['index'] ?? 0 ) ) );
	}
	if ( 'create-element' === $operation ) {
		if ( ! is_array( $input['element'] ?? null ) || array_is_list( $input['element'] ) ) {
			return new WP_Error( 'wpagent_live_editor_elementor_element', __( 'element muss ein Elementor-Objekt sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		$args['element'] = $input['element'];
	}
	if ( 'update-document' === $operation ) {
		if ( ! array_key_exists( 'elements', $input ) && ! array_key_exists( 'settings', $input ) ) {
			return new WP_Error( 'wpagent_live_editor_elementor_input', __( 'elements oder settings ist erforderlich.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		foreach ( array( 'elements', 'settings' ) as $field ) {
			if ( array_key_exists( $field, $input ) ) {
				$args[ $field ] = $input[ $field ];
			}
		}
	}
	if ( 'update-element' === $operation ) {
		if ( ! array_key_exists( 'settings_patch', $input ) && ! array_key_exists( 'remove_settings', $input ) && ! array_key_exists( 'style_patch', $input ) ) {
			return new WP_Error( 'wpagent_live_editor_elementor_input', __( 'Mindestens eine Elementor-Elementänderung ist erforderlich.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		foreach ( array( 'settings_patch', 'remove_settings', 'style_patch' ) as $field ) {
			if ( array_key_exists( $field, $input ) ) {
				$args[ $field ] = $input[ $field ];
			}
		}
	}
	if ( 'restore-revision' === $operation ) {
		$args['revision_id'] = absint( $input['revision_id'] ?? 0 );
		if ( $args['revision_id'] < 1 ) {
			return new WP_Error( 'wpagent_live_editor_elementor_revision', __( 'revision_id ist erforderlich.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
	}
	$encoded = wp_json_encode( $args );
	if ( ! is_string( $encoded ) || strlen( $encoded ) > WPAGENT_ELEMENTOR_MAX_BYTES ) {
		return new WP_Error( 'wpagent_live_editor_elementor_payload', __( 'Die Elementor-Live-Editor-Anfrage ist zu groß.', 'wp-agent-companion' ), array( 'status' => 413 ) );
	}
	return $args;
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_live_editor_elementor_write( $input ) {
	if ( ! wpagent_perm_live_editor() ) {
		return new WP_Error( 'wpagent_live_editor_forbidden', __( 'Keine Berechtigung.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	$args = wpagent_live_editor_elementor_command_args( is_array( $input ) ? $input : array() );
	if ( is_wp_error( $args ) ) {
		return $args;
	}
	return wpagent_companion_live_editor_queue_command( 'open-document' === $args['operation'] ? 'open-elementor-document' : 'elementor-mutate', $args, true );
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_live_editor_write( $input ) {
	if ( ! wpagent_perm_live_editor() ) {
		return new WP_Error( 'wpagent_live_editor_forbidden', __( 'Keine Berechtigung.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	$input   = is_array( $input ) ? $input : array();
	$action  = is_string( $input['action'] ?? null ) ? $input['action'] : '';
	$allowed = array( 'open-post', 'create-block', 'update-block', 'delete-block', 'move-block', 'replace-inner-blocks', 'undo', 'redo', 'save-post', 'finalize-provider-attributes' );
	if ( ! in_array( $action, $allowed, true ) ) {
		return new WP_Error( 'wpagent_live_editor_action', __( 'Unbekannte schreibende Live-Editor-Aktion.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	if ( wpagent_companion_live_editor_is_provider_finalize_action( $action ) ) {
		$args = wpagent_companion_live_editor_provider_finalize_command_args( $input );
		return is_wp_error( $args ) ? $args : wpagent_companion_live_editor_queue_command( $action, $args, true );
	}
	$reason = is_string( $input['reason'] ?? null ) ? trim( sanitize_text_field( $input['reason'] ) ) : '';
	if ( '' === $reason || strlen( $reason ) > 500 ) {
		return new WP_Error( 'wpagent_live_editor_reason', __( 'reason muss zwischen 1 und 500 Byte lang sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$hash = wpagent_live_editor_state_hash( $input, $action );
	if ( is_wp_error( $hash ) ) return $hash;
	$args = array( 'reason' => $reason );
	if ( '' !== $hash ) $args['expected_state_hash'] = $hash;

	if ( 'open-post' === $action ) {
		$post_id = absint( $input['post_id'] ?? 0 );
		if ( 0 === $post_id || ! current_user_can( 'edit_post', $post_id ) ) {
			return new WP_Error( 'wpagent_live_editor_post', __( 'Der Beitrag fehlt oder darf von diesem Agent-Nutzer nicht bearbeitet werden.', 'wp-agent-companion' ), array( 'status' => 403 ) );
		}
		$args['post_id'] = $post_id;
	} elseif ( in_array( $action, array( 'update-block', 'delete-block', 'move-block', 'replace-inner-blocks' ), true ) ) {
		$id = wpagent_live_editor_clean_identifier( $input['client_id'] ?? null, 'client_id' );
		if ( is_wp_error( $id ) ) return $id;
		$args['client_id'] = $id;
	}
	if ( 'create-block' === $action ) {
		$name = wpagent_live_editor_clean_block_name( $input['block_name'] ?? null );
		if ( is_wp_error( $name ) ) return $name;
		$args['block_name'] = $name;
	}
	if ( in_array( $action, array( 'create-block', 'move-block' ), true ) ) {
		if ( isset( $input['parent_client_id'] ) && '' !== $input['parent_client_id'] ) {
			$parent = wpagent_live_editor_clean_identifier( $input['parent_client_id'], 'parent_client_id' );
			if ( is_wp_error( $parent ) ) return $parent;
			$args['parent_client_id'] = $parent;
		}
		$args['index'] = max( 0, min( 10000, absint( $input['index'] ?? 0 ) ) );
	}
	if ( in_array( $action, array( 'create-block', 'update-block' ), true ) ) {
		$attributes = $input['attributes'] ?? null;
		if ( ! is_array( $attributes ) || ( 'update-block' === $action && empty( $attributes ) ) || strlen( (string) wp_json_encode( $attributes ) ) > 50000 ) {
			return new WP_Error( 'wpagent_live_editor_attributes', __( 'attributes muss ein begrenztes Objekt sein und darf bei update-block nicht leer sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		$args['attributes'] = $attributes;
	}
	if ( 'replace-inner-blocks' === $action ) {
		$blocks = $input['blocks'] ?? null;
		if ( ! is_array( $blocks ) || count( $blocks ) > 200 || strlen( (string) wp_json_encode( $blocks ) ) > 50000 ) {
			return new WP_Error( 'wpagent_live_editor_blocks', __( 'blocks muss ein Array mit höchstens 200 Einträgen und 50.000 Byte sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		$args['blocks'] = $blocks;
	}
	return wpagent_companion_live_editor_queue_command( $action, $args, true );
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_get_live_editor_result( $input ) {
	if ( ! wpagent_perm_live_editor() ) {
		return new WP_Error( 'wpagent_live_editor_forbidden', __( 'Keine Berechtigung.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	$input      = is_array( $input ) ? $input : array();
	$command_id = is_string( $input['command_id'] ?? null ) ? $input['command_id'] : '';
	if ( ! preg_match( '/^[a-f0-9]{24}$/D', $command_id ) ) {
		return new WP_Error( 'wpagent_live_editor_command_missing', __( 'Der Live-Editor-Befehl wurde nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
	}
	$option  = wpagent_companion_live_editor_command_option( $command_id );
	$command = get_option( $option, null );
	if ( ! is_array( $command ) ) {
		return new WP_Error( 'wpagent_live_editor_command_missing', __( 'Der Live-Editor-Befehl wurde nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
	}
	if ( get_current_user_id() !== absint( $command['executor_id'] ?? 0 ) ) {
		return new WP_Error( 'wpagent_live_editor_command_forbidden', __( 'Dieser Live-Editor-Befehl gehört zu einem anderen Agent-Nutzer.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	if ( absint( $command['expires_at'] ?? 0 ) <= time() && ! in_array( (string) ( $command['status'] ?? '' ), array( 'completed', 'failed', 'denied', 'recovery_required' ), true ) ) {
		$session_id = is_string( $command['session_id'] ?? null ) ? $command['session_id'] : '';
		$lock       = wpagent_companion_live_editor_acquire_lock( $session_id );
		if ( is_wp_error( $lock ) ) {
			return $lock;
		}
		try {
			$session = wpagent_companion_live_editor_get_session( $session_id );
			if ( is_wp_error( $session ) ) {
				return $session;
			}
			$session = wpagent_companion_live_editor_prune_commands( $session );
			if ( is_wp_error( $session ) ) {
				return $session;
			}
			if ( ! wpagent_companion_live_editor_store_record( wpagent_companion_live_editor_session_option( $session_id ), $session ) ) {
				return new WP_Error( 'wpagent_live_editor_session_save', __( 'Die bereinigte Live-Editor-Sitzung konnte nicht sicher gespeichert werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
			}
			$command = get_option( $option, null );
			if ( ! is_array( $command ) ) {
				return new WP_Error( 'wpagent_live_editor_command_missing', __( 'Der Live-Editor-Befehl wurde nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
			}
		} finally {
			wpagent_companion_live_editor_release_lock( $session_id, $lock );
		}
	}
	return wpagent_companion_live_editor_public_command( $command );
}
