<?php
/** Verified Astra design updates through curated native provider abilities. */

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

/** @return array<string,mixed> */
function wpagent_astra_catalog_settings_schema(): array {
	$schemas = array();
	foreach ( wpagent_astra_operation_catalog() as $definition ) {
		$schemas[] = wpagent_astra_bound_catalog_schema( $definition['input_schema'] );
	}
	return array( 'anyOf' => $schemas );
}

function wpagent_ability_update_astra_design(): array {
	return array(
		'label'               => __( 'Astra-Design aktualisieren', 'wp-agent-companion' ),
		'description'         => __( 'Ändert einen sicheren Astra-Designbereich mit Konfliktschutz, Sperre, frischem Readback und verifiziertem Rollback.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'                 => 'object',
			'properties'           => array(
				'expected_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'operation'     => array( 'type' => 'string', 'enum' => array_keys( wpagent_astra_operation_catalog() ) ),
				'settings'      => wpagent_astra_catalog_settings_schema(),
			),
			'required'             => array( 'expected_hash', 'operation', 'settings' ),
			'maxProperties'        => 3,
			'additionalProperties' => false,
		),
		'output_schema'       => array(
			'type'                 => 'object',
			'properties'           => array(
				'operation'     => array( 'type' => 'string', 'enum' => array_keys( wpagent_astra_operation_catalog() ) ),
				'current'       => wpagent_astra_bounded_object_schema(),
				'previous_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'state_hash'    => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'verified'      => array( 'type' => 'boolean' ),
			),
			'required'             => array( 'operation', 'current', 'previous_hash', 'state_hash', 'verified' ),
			'maxProperties'        => 5,
			'additionalProperties' => false,
		),
		'execute_callback'    => 'wpagent_exec_update_astra_design',
		'permission_callback' => 'wpagent_perm_manage_options',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => false ) ),
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_update_astra_design( $input ) {
	if ( ! wpagent_astra_is_active() ) {
		return new WP_Error( 'wpagent_astra_inactive', __( 'Astra oder ein Astra-Child-Theme ist nicht aktiv.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	if ( ! wpagent_astra_abilities_enabled() ) {
		return new WP_Error( 'wpagent_astra_abilities_disabled', __( 'Aktiviere zuerst die Abilities in den Astra-Einstellungen.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$operation_id = is_array( $input ) ? (string) ( $input['operation'] ?? '' ) : '';
	$available    = wpagent_astra_available_operations();
	if ( ! isset( $available[ $operation_id ] ) ) {
		return new WP_Error( 'wpagent_astra_operation_unavailable', __( 'Die gewählte Astra-Operation ist in dieser Theme-Version nicht verfügbar.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$settings = wpagent_astra_validate_settings( $operation_id, $input['settings'] ?? null );
	if ( is_wp_error( $settings ) ) {
		return $settings;
	}
	$lock = wpagent_astra_acquire_lock();
	if ( is_wp_error( $lock ) ) {
		return $lock;
	}
	try {
		$checkpoint = wpagent_astra_checkpoint( $lock );
		if ( is_wp_error( $checkpoint ) ) {
			return $checkpoint;
		}
		$previous = wpagent_astra_snapshot();
		if ( is_wp_error( $previous ) ) {
			return $previous;
		}
		$previous_hash = wpagent_astra_state_hash( $previous );
		$expected_hash = strtolower( (string) ( $input['expected_hash'] ?? '' ) );
		if ( ! preg_match( '/^[a-f0-9]{64}$/', $expected_hash ) || ! hash_equals( $previous_hash, $expected_hash ) ) {
			return new WP_Error( 'wpagent_astra_conflict', __( 'Die Astra-Einstellungen haben sich seit dem Lesen geändert. Lies sie neu und wiederhole den Vorgang.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $previous_hash ) );
		}

		$before = wpagent_astra_provider_data( $available[ $operation_id ]['read'] );
		if ( is_wp_error( $before ) ) {
			return $before;
		}
		$checkpoint = wpagent_astra_checkpoint( $lock );
		if ( is_wp_error( $checkpoint ) ) {
			return $checkpoint;
		}
		$written = wpagent_astra_provider_data( $available[ $operation_id ]['write'], $settings );
		if ( is_wp_error( $written ) ) {
			return wpagent_astra_recovery_required();
		}
		$checkpoint = wpagent_astra_checkpoint( $lock, true );
		if ( is_wp_error( $checkpoint ) ) {
			return wpagent_astra_recovery_required();
		}

		$fresh_snapshot = wpagent_astra_snapshot();
		$fresh_current  = wpagent_astra_provider_data( $available[ $operation_id ]['read'] );
		if ( is_wp_error( $fresh_snapshot ) || is_wp_error( $fresh_current ) || ! wpagent_astra_readback_matches( $operation_id, $settings, $fresh_current ) ) {
			return wpagent_astra_recovery_required();
		}
		$checkpoint = wpagent_astra_checkpoint( $lock, true );
		if ( is_wp_error( $checkpoint ) ) {
			return wpagent_astra_recovery_required();
		}
		return array(
			'operation'     => $operation_id,
			'current'       => $fresh_current,
			'previous_hash' => $previous_hash,
			'state_hash'    => wpagent_astra_state_hash( $fresh_snapshot ),
			'verified'      => true,
		);
	} finally {
		wpagent_astra_release_lock( $lock );
	}
}
