<?php
/** Verified native CRUD for Elementor v4 Global Classes. */

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

/** @return array<string,mixed> */
function wpagent_elementor_global_class_variant_input_schema(): array {
	return array(
		'type'                 => 'object',
		'properties'           => array(
			'meta'  => array(
				'type'                 => 'object',
				'properties'           => array(
					'breakpoint' => array( 'type' => 'string' ),
					'state'      => array( 'type' => array( 'string', 'null' ) ),
				),
				'required'             => array( 'breakpoint', 'state' ),
				'additionalProperties' => false,
			),
			'props' => wpagent_elementor_json_document_schema(),
		),
		'required'             => array( 'meta', 'props' ),
		'additionalProperties' => false,
	);
}

/** @return array<string,mixed> */
function wpagent_elementor_global_class_write_output_schema(): array {
	$schema = wpagent_elementor_global_classes_output_schema();
	$schema['properties']['class'] = wpagent_elementor_global_class_schema();
	$schema['properties']['previous_hash'] = array( 'type' => 'string' );
	$schema['properties']['changed'] = array( 'type' => 'boolean' );
	$schema['properties']['verified'] = array( 'type' => 'boolean' );
	$schema['properties']['rolled_back'] = array( 'type' => 'boolean' );
	return $schema;
}

function wpagent_ability_create_elementor_global_class(): array {
	return array(
		'label'               => __( 'Elementor v4 Global Class erstellen', 'wp-agent-companion' ),
		'description'         => __( 'Erstellt eine native Elementor-v4-Global-Class mit validierten Breakpoints und Style-Props. Konfliktschutz, Sperre und Rückleseprüfung sind verpflichtend. Unklare Providerzustände bleiben zur manuellen Prüfung erhalten.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'                 => 'object',
			'properties'           => array(
				'expected_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'label'         => array( 'type' => 'string', 'minLength' => 2, 'maxLength' => 50 ),
				'variants'      => array( 'type' => 'array', 'minItems' => 1, 'maxItems' => WPAGENT_ELEMENTOR_GLOBAL_CLASSES_MAX_VARIANTS, 'items' => wpagent_elementor_global_class_variant_input_schema() ),
			),
			'required'             => array( 'expected_hash', 'label', 'variants' ),
			'additionalProperties' => false,
		),
		'output_schema'       => wpagent_elementor_global_class_write_output_schema(),
		'execute_callback'    => 'wpagent_exec_create_elementor_global_class',
		'permission_callback' => 'wpagent_perm_manage_options',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => false ) ),
	);
}

function wpagent_ability_update_elementor_global_class(): array {
	return array(
		'label'               => __( 'Elementor v4 Global Class aktualisieren', 'wp-agent-companion' ),
		'description'         => __( 'Aktualisiert Name oder native Style-Varianten einer Elementor-v4-Global-Class mit Konfliktschutz, Sperre und Rückleseprüfung. Unklare Providerzustände bleiben zur manuellen Prüfung erhalten.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'                 => 'object',
			'properties'           => array(
				'expected_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'class_id'      => array( 'type' => 'string', 'pattern' => '^[a-z][a-z0-9_-]{0,63}$' ),
				'label'         => array( 'type' => 'string', 'minLength' => 2, 'maxLength' => 50 ),
				'variants'      => array( 'type' => 'array', 'minItems' => 1, 'maxItems' => WPAGENT_ELEMENTOR_GLOBAL_CLASSES_MAX_VARIANTS, 'items' => wpagent_elementor_global_class_variant_input_schema() ),
			),
			'required'             => array( 'expected_hash', 'class_id' ),
			'additionalProperties' => false,
		),
		'output_schema'       => wpagent_elementor_global_class_write_output_schema(),
		'execute_callback'    => 'wpagent_exec_update_elementor_global_class',
		'permission_callback' => 'wpagent_perm_manage_options',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => false ) ),
	);
}

function wpagent_ability_delete_elementor_global_class(): array {
	return array(
		'label'               => __( 'Elementor v4 Global Class löschen', 'wp-agent-companion' ),
		'description'         => __( 'Prüft eine native Elementor-v4-Global-Class und alle betroffenen Dokumente per Hash. Remote-Löschungen sind deaktiviert, weil Elementor keine atomare Compare-and-Delete-Operation gegen parallele Editor-Änderungen bietet.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'                 => 'object',
			'properties'           => array(
				'expected_hash'    => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'class_id'         => array( 'type' => 'string', 'pattern' => '^[a-z][a-z0-9_-]{0,63}$' ),
				'confirm'          => array( 'type' => 'boolean' ),
				'affected_post_ids' => array( 'type' => 'array', 'maxItems' => WPAGENT_ELEMENTOR_GLOBAL_CLASSES_MAX_USAGE_POSTS, 'items' => array( 'type' => 'integer' ) ),
			),
			'required'             => array( 'expected_hash', 'class_id', 'confirm', 'affected_post_ids' ),
			'additionalProperties' => false,
		),
		'output_schema'       => array(
			'type'                 => 'object',
			'properties'           => array(),
			'additionalProperties' => false,
		),
		'execute_callback'    => 'wpagent_exec_delete_elementor_global_class',
		'permission_callback' => 'wpagent_perm_manage_options',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => true, 'idempotent' => false, 'manual_only' => true ) ),
	);
}

/** @return string[] */
function wpagent_elementor_global_class_order_without( array $order, string $class_id ): array {
	return array_values(
		array_filter(
			$order,
			static fn( $id ): bool => is_string( $id ) && $id !== $class_id
		)
	);
}

/** @return string[] */
function wpagent_elementor_global_class_restore_order( array $current_order, array $before_order, string $class_id ): array {
	$order = wpagent_elementor_global_class_order_without( $current_order, $class_id );
	$position = array_search( $class_id, $before_order, true );
	if ( false === $position ) {
		return $order;
	}
	for ( $index = $position + 1, $length = count( $before_order ); $index < $length; ++$index ) {
		$next = $before_order[ $index ];
		$next_position = array_search( $next, $order, true );
		if ( false !== $next_position ) {
			array_splice( $order, $next_position, 0, array( $class_id ) );
			return $order;
		}
	}
	for ( $index = $position - 1; $index >= 0; --$index ) {
		$previous = $before_order[ $index ];
		$previous_position = array_search( $previous, $order, true );
		if ( false !== $previous_position ) {
			array_splice( $order, $previous_position + 1, 0, array( $class_id ) );
			return $order;
		}
	}
	$order[] = $class_id;
	return $order;
}

/** @param array{items:array<string,array<string,mixed>>,order:string[]} $before @param array{items:array<string,array<string,mixed>>,order:string[]} $after */
function wpagent_elementor_global_class_preserves_others( array $before, array $after, string $class_id ): bool {
	foreach ( $before['items'] as $id => $item ) {
		if ( $id === $class_id ) {
			continue;
		}
		if ( ! isset( $after['items'][ $id ] ) || wpagent_elementor_canonicalize( $item ) !== wpagent_elementor_canonicalize( $after['items'][ $id ] ) ) {
			return false;
		}
	}
	foreach ( $after['items'] as $id => $item ) {
		if ( $id !== $class_id && ! isset( $before['items'][ $id ] ) ) {
			return false;
		}
	}
	return wpagent_elementor_global_class_order_without( $before['order'], $class_id ) === wpagent_elementor_global_class_order_without( $after['order'], $class_id );
}

/**
 * Restore one known Global Class without writing a stale complete repository snapshot.
 *
 * @param array{items:array<string,array<string,mixed>>,order:string[]} $before
 * @param array<string,mixed>|null $expected_item The exact item that this operation wrote, or null for delete.
 */
function wpagent_elementor_global_class_restore_target( array $before, string $class_id, string $mode, ?array $expected_item ): bool {
	// Public operations deliberately preserve ambiguous provider state. This
	// legacy signature has no token/capability context, so it must never write.
	unset( $before, $class_id, $mode, $expected_item );
	return false;
}

/** @return WP_Error */
function wpagent_elementor_global_classes_recovery_required( int $kit_id, string $previous_hash, string $reason ): WP_Error {
	return new WP_Error(
		'wpagent_elementor_global_classes_recovery_required',
		__( 'Der Elementor-Global-Class-Providerzustand konnte nach einer unsicheren Änderung nicht automatisch wiederhergestellt werden. Prüfe die Global Classes im Elementor-Editor.', 'wp-agent-companion' ),
		array( 'status' => 500, 'kit_id' => $kit_id, 'previous_hash' => $previous_hash, 'recovery_required' => true, 'reason' => $reason )
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_elementor_global_class_mutate( array $input, string $mode ) {
	$capability = wpagent_elementor_global_classes_require_capability( 'elementor_global_classes_update_class' );
	if ( is_wp_error( $capability ) ) {
		return $capability;
	}
	$expected_hash = wpagent_elementor_global_class_hash_input( $input );
	if ( is_wp_error( $expected_hash ) ) {
		return $expected_hash;
	}
	$initial = wpagent_elementor_global_classes_snapshot();
	if ( is_wp_error( $initial ) ) {
		return $initial;
	}
	$class_id = 'update' === $mode && is_string( $input['class_id'] ?? null ) ? $input['class_id'] : '';
	if ( 'update' === $mode && ! preg_match( '/^[a-z][a-z0-9_-]{0,63}$/', $class_id ) ) {
		return new WP_Error( 'wpagent_elementor_global_class_bad_id', __( 'class_id ist ungültig.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	if ( 'update' === $mode && ! isset( $initial['items'][ $class_id ] ) ) {
		return new WP_Error( 'wpagent_elementor_global_class_not_found', __( 'Global Class nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
	}
	if ( 'update' === $mode && wpagent_elementor_global_class_has_custom_css( $initial['items'][ $class_id ] ) ) {
		return new WP_Error( 'wpagent_elementor_global_class_manual_update_required', __( 'Diese Elementor Global Class enthält nicht unterstütztes benutzerdefiniertes CSS und wird zur Vermeidung eines Datenverlusts nur im Elementor-Editor aktualisiert.', 'wp-agent-companion' ), array( 'status' => 409, 'manual_action_required' => true ) );
	}
	if ( 'update' === $mode && ! array_key_exists( 'label', $input ) && ! array_key_exists( 'variants', $input ) ) {
		return new WP_Error( 'wpagent_elementor_global_class_no_changes', __( 'label oder variants ist erforderlich.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$label_value = 'create' === $mode || array_key_exists( 'label', $input ) ? ( $input['label'] ?? null ) : $initial['items'][ $class_id ]['label'];
	$label = wpagent_elementor_global_class_label( $label_value );
	if ( is_wp_error( $label ) ) {
		return $label;
	}
	foreach ( $initial['items'] as $other_id => $other ) {
		if ( $other_id !== $class_id && $label === ( $other['label'] ?? null ) ) {
			return new WP_Error( 'wpagent_elementor_global_class_duplicate_label', __( 'Eine Global Class mit diesem Namen existiert bereits.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
	}
	if ( 'create' === $mode ) {
		if ( count( $initial['items'] ) >= WPAGENT_ELEMENTOR_GLOBAL_CLASSES_MAX_ITEMS ) {
			return new WP_Error( 'wpagent_elementor_global_classes_limit', __( 'Elementors Limit von 1.000 Global Classes ist erreicht.', 'wp-agent-companion' ), array( 'status' => 413 ) );
		}
		do {
			$class_id = 'g-' . strtolower( str_replace( '-', '', wp_generate_uuid4() ) );
		} while ( isset( $initial['items'][ $class_id ] ) );
	}
	$variants_value = array_key_exists( 'variants', $input ) ? $input['variants'] : $initial['items'][ $class_id ]['variants'];
	$variants = wpagent_elementor_global_class_variants( $variants_value, $class_id, $label );
	if ( is_wp_error( $variants ) ) {
		return $variants;
	}
	$item = array( 'id' => $class_id, 'type' => 'class', 'label' => $label, 'variants' => $variants );
	if ( isset( $initial['items'][ $class_id ]['sync_to_v3'] ) ) {
		$item['sync_to_v3'] = (bool) $initial['items'][ $class_id ]['sync_to_v3'];
	}
	$initial_hash = wpagent_elementor_global_classes_hash( $initial );
	if ( ! hash_equals( $initial_hash, $expected_hash ) ) {
		return new WP_Error( 'wpagent_elementor_global_classes_conflict', __( 'Die Global Classes wurden seit dem letzten Lesen geändert.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $initial_hash ) );
	}
	if ( 'update' === $mode && wpagent_elementor_canonicalize( $item ) === wpagent_elementor_canonicalize( $initial['items'][ $class_id ] ) ) {
		$state = wpagent_elementor_global_classes_state( $initial );
		$class = wpagent_elementor_global_class_public_item( $initial['items'][ $class_id ] );
		if ( is_wp_error( $state ) || is_wp_error( $class ) ) {
			return is_wp_error( $state ) ? $state : $class;
		}
		$state['class'] = $class;
		$state['previous_hash'] = $initial_hash;
		$state['changed'] = false;
		$state['verified'] = true;
		$state['rolled_back'] = false;
		return $state;
	}
	$kit_id = $initial['kit_id'];
	$lock = wpagent_elementor_acquire_lock( $kit_id );
	if ( is_wp_error( $lock ) ) {
		return $lock;
	}
	try {
		if ( ! wpagent_elementor_lock_checkpoint( $kit_id, $lock ) ) {
			return wpagent_elementor_global_classes_recovery_required( $kit_id, $expected_hash, 'lock_lost_before_initial_read' );
		}
		$capability = wpagent_elementor_global_classes_require_capability( 'elementor_global_classes_update_class' );
		if ( is_wp_error( $capability ) ) {
			return wpagent_elementor_global_classes_recovery_required( $kit_id, $expected_hash, 'capability_lost_before_initial_read' );
		}
		$before = wpagent_elementor_global_classes_snapshot();
		if ( is_wp_error( $before ) ) {
			return $before;
		}
		$before_hash = wpagent_elementor_global_classes_hash( $before );
		if ( ! hash_equals( $before_hash, $expected_hash ) ) {
			return new WP_Error( 'wpagent_elementor_global_classes_conflict', __( 'Die Global Classes wurden während der Vorbereitung geändert.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $before_hash ) );
		}
		$repository = wpagent_elementor_global_classes_repository();
		if ( is_wp_error( $repository ) ) {
			return $repository;
		}
		$order = $before['order'];
		$changes = array( 'added' => array(), 'deleted' => array(), 'modified' => array(), 'order' => false );
		if ( 'create' === $mode ) {
			$order[] = $class_id;
			$changes['added'][] = $class_id;
			$changes['order'] = true;
		} else {
			$changes['modified'][] = $class_id;
		}
		if ( ! wpagent_elementor_lock_checkpoint( $kit_id, $lock ) ) {
			return wpagent_elementor_global_classes_recovery_required( $kit_id, $before_hash, 'lock_lost_before_provider_write' );
		}
		$capability = wpagent_elementor_global_classes_require_capability( 'elementor_global_classes_update_class' );
		if ( is_wp_error( $capability ) ) {
			return wpagent_elementor_global_classes_recovery_required( $kit_id, $before_hash, 'capability_lost_before_provider_write' );
		}
		$prewrite = wpagent_elementor_global_classes_snapshot();
		if ( is_wp_error( $prewrite ) ) {
			return wpagent_elementor_global_classes_recovery_required( $kit_id, $before_hash, 'provider_state_unavailable_before_write' );
		}
		$prewrite_hash = wpagent_elementor_global_classes_hash( $prewrite );
		if ( ! hash_equals( $before_hash, $prewrite_hash ) ) {
			return new WP_Error( 'wpagent_elementor_global_classes_conflict', __( 'Die Global Classes wurden vor dem Speichern verändert.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $prewrite_hash ) );
		}
		try {
			$repository->apply_changes( array( $class_id => $item ), $changes, $order );
		} catch ( Throwable ) {
			return wpagent_elementor_global_classes_recovery_required( $kit_id, $before_hash, 'provider_write_exception' );
		}
		if ( ! wpagent_elementor_lock_checkpoint( $kit_id, $lock ) ) {
			return wpagent_elementor_global_classes_recovery_required( $kit_id, $before_hash, 'lock_lost_after_provider_write' );
		}
		$capability = wpagent_elementor_global_classes_require_capability( 'elementor_global_classes_update_class' );
		if ( is_wp_error( $capability ) ) {
			return wpagent_elementor_global_classes_recovery_required( $kit_id, $before_hash, 'capability_lost_before_readback' );
		}
		$after = wpagent_elementor_global_classes_snapshot();
		$verified = is_array( $after )
			&& isset( $after['items'][ $class_id ] )
			&& wpagent_elementor_canonicalize( $after['items'][ $class_id ] ) === wpagent_elementor_canonicalize( $item )
			&& $order === $after['order']
			&& wpagent_elementor_global_class_preserves_others( $before, $after, $class_id );
		if ( ! $verified ) {
			return wpagent_elementor_global_classes_recovery_required( $kit_id, $before_hash, 'provider_readback_verification_failed' );
		}
		if ( ! wpagent_elementor_lock_checkpoint( $kit_id, $lock ) ) {
			return wpagent_elementor_global_classes_recovery_required( $kit_id, $before_hash, 'lock_lost_after_readback' );
		}
		$state = wpagent_elementor_global_classes_state( $after );
		$class = wpagent_elementor_global_class_public_item( $after['items'][ $class_id ] );
		if ( is_wp_error( $state ) || is_wp_error( $class ) ) {
			return is_wp_error( $state ) ? $state : $class;
		}
		$state['class'] = $class;
		$state['previous_hash'] = $before_hash;
		$state['changed'] = true;
		$state['verified'] = true;
		$state['rolled_back'] = false;
		return $state;
	} finally {
		wpagent_elementor_release_lock( $kit_id, $lock );
	}
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_create_elementor_global_class( $input ) {
	return wpagent_elementor_global_class_mutate( is_array( $input ) ? $input : array(), 'create' );
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_update_elementor_global_class( $input ) {
	return wpagent_elementor_global_class_mutate( is_array( $input ) ? $input : array(), 'update' );
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_delete_elementor_global_class( $input ) {
	$input = is_array( $input ) ? $input : array();
	$capability = wpagent_elementor_global_classes_require_capability( 'elementor_global_classes_remove_class' );
	if ( is_wp_error( $capability ) ) {
		return $capability;
	}
	$expected_hash = wpagent_elementor_global_class_hash_input( $input );
	$class_id = is_string( $input['class_id'] ?? null ) ? $input['class_id'] : '';
	if ( is_wp_error( $expected_hash ) ) {
		return $expected_hash;
	}
	if ( ! preg_match( '/^[a-z][a-z0-9_-]{0,63}$/', $class_id ) ) {
		return new WP_Error( 'wpagent_elementor_global_class_bad_id', __( 'class_id ist ungültig.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	if ( true !== ( $input['confirm'] ?? false ) ) {
		return new WP_Error( 'wpagent_confirmation_required', __( 'confirm=true ist zum Löschen erforderlich.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$confirmed = $input['affected_post_ids'] ?? null;
	if ( ! is_array( $confirmed ) || ! array_is_list( $confirmed ) || count( $confirmed ) > WPAGENT_ELEMENTOR_GLOBAL_CLASSES_MAX_USAGE_POSTS ) {
		return new WP_Error( 'wpagent_elementor_global_class_usage_conflict', __( 'affected_post_ids muss alle betroffenen Dokumente exakt bestätigen.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$confirmed = array_map( 'absint', $confirmed );
	if ( count( array_unique( $confirmed ) ) !== count( $confirmed ) || in_array( 0, $confirmed, true ) ) {
		return new WP_Error( 'wpagent_elementor_global_class_usage_conflict', __( 'affected_post_ids enthält ungültige oder doppelte IDs.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	sort( $confirmed, SORT_NUMERIC );
	$initial = wpagent_elementor_global_classes_snapshot();
	if ( is_wp_error( $initial ) ) {
		return $initial;
	}
	$initial_hash = wpagent_elementor_global_classes_hash( $initial );
	if ( ! hash_equals( $initial_hash, $expected_hash ) ) {
		return new WP_Error( 'wpagent_elementor_global_classes_conflict', __( 'Die Global Classes wurden seit dem letzten Lesen geändert.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $initial_hash ) );
	}
	if ( ! isset( $initial['items'][ $class_id ] ) ) {
		return new WP_Error( 'wpagent_elementor_global_class_not_found', __( 'Global Class nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
	}
	$usage = wpagent_elementor_global_class_usage( $class_id );
	if ( is_wp_error( $usage ) ) {
		return $usage;
	}
	if ( $usage !== $confirmed ) {
		return new WP_Error( 'wpagent_elementor_global_class_usage_conflict', __( 'Die bestätigten Dokumente stimmen nicht mit der aktuellen Verwendung überein.', 'wp-agent-companion' ), array( 'status' => 409, 'affected_post_ids' => $usage ) );
	}
	return new WP_Error(
		'wpagent_elementor_manual_delete_required',
		__( 'Die Elementor v4 Global Class wird nicht remote gelöscht, weil Elementor keine atomare Compare-and-Delete-Operation gegen parallele Editor-Änderungen bietet. Prüfe den aktuellen Zustand erneut und lösche die Global Class anschließend manuell im Elementor-Editor.', 'wp-agent-companion' ),
		array( 'status' => 409, 'current_hash' => $initial_hash, 'class_id' => $class_id, 'affected_post_ids' => $usage, 'manual_action_required' => true )
	);
}

/** @return array<int,array<string,mixed>>|false */
function wpagent_elementor_global_class_removed_elements( array $elements, string $class_id ) {
	$result = array();
	foreach ( $elements as $element ) {
		if ( ! is_array( $element ) ) {
			return false;
		}
		try {
			$type = \Elementor\Modules\GlobalClasses\Utils\Atomic_Elements_Utils::get_element_type( $element );
			$instance = \Elementor\Modules\GlobalClasses\Utils\Atomic_Elements_Utils::get_element_instance( $type );
			if ( \Elementor\Modules\GlobalClasses\Utils\Atomic_Elements_Utils::is_atomic_element( $instance ) && method_exists( $instance, 'get_props_schema' ) ) {
				foreach ( $instance->get_props_schema() as $settings_key => $prop ) {
					$current = $element['settings'][ $settings_key ] ?? null;
					if ( ! \Elementor\Modules\GlobalClasses\Utils\Atomic_Elements_Utils::is_classes_prop( $prop ) || ! is_array( $current ) || ! is_array( $current['value'] ?? null ) ) {
						continue;
					}
					$element['settings'][ $settings_key ]['value'] = array_values( array_filter( $current['value'], static fn( $value ): bool => $value !== $class_id ) );
				}
			}
		} catch ( Throwable ) {
			return false;
		}
		if ( isset( $element['elements'] ) ) {
			if ( ! is_array( $element['elements'] ) ) {
				return false;
			}
			$children = wpagent_elementor_global_class_removed_elements( $element['elements'], $class_id );
			if ( false === $children ) {
				return false;
			}
			$element['elements'] = $children;
		}
		$result[] = $element;
	}
	return $result;
}

/**
 * @param array<int,array<string,mixed>> $before_states
 * @return array{hashes:array<int,string>,verified:bool}|false
 */
function wpagent_elementor_global_class_delete_expectations( array $before_states, string $class_id ) {
	$hashes = array();
	$verified = true;
	foreach ( $before_states as $post_id => $before_state ) {
		if ( ! is_array( $before_state ) || ! is_array( $before_state['elements'] ?? null ) || ! is_array( $before_state['settings'] ?? null ) ) {
			return false;
		}
		$expected_elements = wpagent_elementor_global_class_removed_elements( $before_state['elements'], $class_id );
		if ( false === $expected_elements ) {
			return false;
		}
		$expected_state = $before_state;
		$expected_state['elements'] = $expected_elements;
		$hashes[ (int) $post_id ] = wpagent_elementor_state_hash( $expected_state );
		$document = \Elementor\Plugin::$instance->documents->get( (int) $post_id, false );
		if ( ! is_object( $document ) || ! hash_equals( $hashes[ (int) $post_id ], wpagent_elementor_document_state( (int) $post_id, $document )['hash'] ) ) {
			$verified = false;
		}
	}
	return array( 'hashes' => $hashes, 'verified' => $verified );
}

/** @param array<string,int> $revision_ids @param array<int,string> $document_hashes @param array<int,string> $deleted_document_hashes */
function wpagent_elementor_global_class_delete_rollback( array $before, string $class_id, array $revision_ids, array $document_hashes, array $deleted_document_hashes ): bool {
	// Public Global-Class deletes are manual-only. Do not retain a callable,
	// stale-snapshot rollback path for any legacy internal caller.
	unset( $before, $class_id, $revision_ids, $document_hashes, $deleted_document_hashes );
	return false;
}
