<?php
/** Verified native Spectra administration writes. */

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

function wpagent_ability_set_spectra_block_status(): array {
	return array(
		'label' => __( 'Spectra-Blockstatus setzen', 'wp-agent-companion' ),
		'description' => __( 'Aktiviert oder deaktiviert einen sichtbaren Spectra-Block über Spectras native Einstellung, konfliktgeschützt und mit selektivem Rollback.', 'wp-agent-companion' ),
		'category' => 'wp-agent',
		'input_schema' => array(
			'type' => 'object', 'properties' => array(
				'slug' => array( 'type' => 'string', 'pattern' => '^[a-z0-9][a-z0-9-]{0,127}$' ),
				'enabled' => array( 'type' => 'boolean' ),
				'expected_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
			), 'required' => array( 'slug', 'enabled', 'expected_hash' ), 'additionalProperties' => false,
		),
		'output_schema' => array(
			'type' => 'object', 'properties' => array(
				'block' => wpagent_spectra_block_schema(), 'verified' => array( 'type' => 'boolean' ),
				'previous_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
			), 'required' => array( 'block', 'verified', 'previous_hash', 'hash' ), 'additionalProperties' => false,
		),
		'execute_callback' => 'wpagent_exec_set_spectra_block_status', 'permission_callback' => 'wpagent_perm_manage_options',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => true ) ),
	);
}

function wpagent_ability_update_spectra_popup(): array {
	return array(
		'label' => __( 'Spectra-Popup aktualisieren', 'wp-agent-companion' ),
		'description' => __( 'Ändert sichere Popup-Einstellungen konfliktgeschützt und prüft Titel, Status, Typ, Aktivierung und Wiederholung nach dem Speichern.', 'wp-agent-companion' ),
		'category' => 'wp-agent',
		'input_schema' => array(
			'type' => 'object', 'properties' => array(
				'id' => array( 'type' => 'integer', 'minimum' => 1 ), 'expected_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'title' => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 200 ),
				'status' => array( 'type' => 'string', 'enum' => array( 'draft', 'pending', 'private', 'publish' ) ),
				'type' => array( 'type' => 'string', 'enum' => array( 'unset', 'popup', 'banner' ) ),
				'enabled' => array( 'type' => 'boolean' ), 'repetition' => array( 'type' => 'integer', 'minimum' => 1, 'maximum' => 100 ),
			), 'required' => array( 'id', 'expected_hash' ), 'additionalProperties' => false,
		),
		'output_schema' => array(
			'type' => 'object', 'properties' => array(
				'popup' => wpagent_spectra_popup_schema(), 'verified' => array( 'type' => 'boolean' ),
				'previous_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
			), 'required' => array( 'popup', 'verified', 'previous_hash' ), 'additionalProperties' => false,
		),
		'execute_callback' => 'wpagent_exec_update_spectra_popup', 'permission_callback' => 'wpagent_perm_manage_options',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => true ) ),
	);
}

function wpagent_ability_delete_spectra_popup(): array {
	return array(
		'label' => __( 'Spectra-Popup löschen', 'wp-agent-companion' ),
		'description' => __( 'Verschiebt ein Spectra-Popup nach ausdrücklicher Bestätigung in den Papierkorb oder löscht es endgültig. Ein Zustands-Hash verhindert veraltete Löschungen.', 'wp-agent-companion' ),
		'category' => 'wp-agent',
		'input_schema' => array(
			'type' => 'object', 'properties' => array(
				'id' => array( 'type' => 'integer', 'minimum' => 1 ), 'expected_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'confirm' => array( 'type' => 'boolean' ), 'force' => array( 'type' => 'boolean', 'default' => false ),
			), 'required' => array( 'id', 'expected_hash', 'confirm' ), 'additionalProperties' => false,
		),
		'output_schema' => array(
			'type' => 'object', 'properties' => array(
				'id' => array( 'type' => 'integer' ), 'trashed' => array( 'type' => 'boolean' ), 'deleted' => array( 'type' => 'boolean' ),
			), 'required' => array( 'id', 'trashed', 'deleted' ), 'additionalProperties' => false,
		),
		'execute_callback' => 'wpagent_exec_delete_spectra_popup', 'permission_callback' => 'wpagent_perm_manage_options',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => true, 'idempotent' => true ) ),
	);
}

/** @return string|WP_Error */
function wpagent_spectra_expected_hash( $value ) {
	if ( ! is_string( $value ) || ! preg_match( '/^[a-f0-9]{64}$/', $value ) ) {
		return new WP_Error( 'wpagent_spectra_hash', __( 'expected_hash muss ein SHA-256-Hash sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	return $value;
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_set_spectra_block_status( $input ) {
	$input = is_array( $input ) ? $input : array();
	$registry = wpagent_spectra_block_registry();
	if ( is_wp_error( $registry ) ) return $registry;
	$slug = is_string( $input['slug'] ?? null ) ? $input['slug'] : '';
	if ( ! preg_match( '/^[a-z0-9][a-z0-9-]{0,127}$/', $slug ) || ! isset( $registry[ $slug ] ) ) {
		return new WP_Error( 'wpagent_spectra_block', __( 'Der Spectra-Block ist unbekannt oder nicht einzeln schaltbar.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	if ( ! is_bool( $input['enabled'] ?? null ) ) {
		return new WP_Error( 'wpagent_spectra_enabled', __( 'enabled muss ein boolescher Wert sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$expected_hash = wpagent_spectra_expected_hash( $input['expected_hash'] ?? null );
	if ( is_wp_error( $expected_hash ) ) return $expected_hash;
	$lock = wpagent_site_editor_acquire_lock( 'spectra', 'blocks' );
	if ( is_wp_error( $lock ) ) return $lock;
	try {
		$before = wpagent_spectra_block_option_snapshot();
		if ( is_wp_error( $before ) ) return $before;
		if ( ! hash_equals( $before['hash'], $expected_hash ) ) {
			return new WP_Error( 'wpagent_spectra_conflict', __( 'Spectras Blockstatus wurde seit dem Lesen verändert.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $before['hash'] ) );
		}
		$candidate          = $before['value'];
		$candidate[ $slug ] = $input['enabled'] ? $slug : 'disabled';
		try {
			UAGB_Admin_Helper::update_admin_settings_option( '_uagb_blocks', $candidate );
		} catch ( Throwable $error ) {
			return new WP_Error( 'wpagent_spectra_save_failed', $error->getMessage(), array( 'status' => 500 ) );
		}
		$after = wpagent_spectra_block_option_snapshot();
		if ( is_wp_error( $after ) || $after['value'] !== $candidate ) {
			$rolled_back = false;
			if ( is_wp_error( $after ) ) {
				if ( $before['exists'] ) UAGB_Admin_Helper::update_admin_settings_option( '_uagb_blocks', $before['value'] );
				else delete_option( '_uagb_blocks' );
				$verified_rollback = wpagent_spectra_block_option_snapshot();
				$rolled_back = ! is_wp_error( $verified_rollback ) && hash_equals( $before['hash'], $verified_rollback['hash'] );
			} else {
				$current = $after;
				$rollback = $current['value'];
				if ( array_key_exists( $slug, $before['value'] ) ) $rollback[ $slug ] = $before['value'][ $slug ];
				else unset( $rollback[ $slug ] );
				if ( array() === $rollback && ! $before['exists'] ) delete_option( '_uagb_blocks' );
				else UAGB_Admin_Helper::update_admin_settings_option( '_uagb_blocks', $rollback );
				$verified_rollback = wpagent_spectra_block_option_snapshot();
				$rolled_back = ! is_wp_error( $verified_rollback )
					&& ( array_key_exists( $slug, $before['value'] )
						? array_key_exists( $slug, $verified_rollback['value'] ) && $verified_rollback['value'][ $slug ] === $before['value'][ $slug ]
						: ! array_key_exists( $slug, $verified_rollback['value'] ) );
			}
			return new WP_Error( 'wpagent_spectra_verify_failed', __( 'Der Spectra-Blockstatus bestand die Rückleseprüfung nicht.', 'wp-agent-companion' ), array( 'status' => 500, 'rolled_back' => $rolled_back ) );
		}
		return array(
			'block' => wpagent_spectra_block_state( $registry[ $slug ], $after['value'] ), 'verified' => true,
			'previous_hash' => $before['hash'], 'hash' => $after['hash'],
		);
	} finally {
		wpagent_site_editor_release_lock( 'spectra', 'blocks', $lock );
	}
}

/** @return array<string,mixed>|WP_Error */
function wpagent_spectra_validate_popup_update( array $input, array $before ) {
	$fields = array( 'title', 'status', 'type', 'enabled', 'repetition' );
	if ( ! array_intersect( $fields, array_keys( $input ) ) ) {
		return new WP_Error( 'wpagent_spectra_no_fields', __( 'Mindestens ein Popup-Feld muss geändert werden.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$title = $before['title'];
	if ( array_key_exists( 'title', $input ) ) {
		$title = is_string( $input['title'] ) ? trim( $input['title'] ) : '';
		$length = function_exists( 'mb_strlen' ) ? mb_strlen( $title, 'UTF-8' ) : strlen( $title );
		if ( '' === $title || $length > 200 || sanitize_text_field( $title ) !== $title ) {
			return new WP_Error( 'wpagent_spectra_title', __( 'title muss reiner Text mit 1-200 Zeichen sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
	}
	$status = $input['status'] ?? $before['status'];
	if ( ! in_array( $status, array( 'draft', 'pending', 'private', 'publish' ), true ) ) {
		return new WP_Error( 'wpagent_spectra_status', __( 'Ungültiger Popup-Status.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$type = $input['type'] ?? $before['type'];
	if ( ! in_array( $type, array( 'unset', 'popup', 'banner' ), true ) ) {
		return new WP_Error( 'wpagent_spectra_type', __( 'Ungültiger Popup-Typ.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$enabled = $input['enabled'] ?? $before['enabled'];
	if ( ! is_bool( $enabled ) ) {
		return new WP_Error( 'wpagent_spectra_enabled', __( 'enabled muss ein boolescher Wert sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$repetition = $input['repetition'] ?? $before['repetition'];
	if ( ! is_int( $repetition ) || $repetition < 1 || $repetition > 100 ) {
		return new WP_Error( 'wpagent_spectra_repetition', __( 'repetition muss eine ganze Zahl zwischen 1 und 100 sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	if ( $enabled && ( 'publish' !== $status || 'unset' === $type || empty( $before['has_popup_wrapper'] ) ) ) {
		return new WP_Error( 'wpagent_spectra_popup_incomplete', __( 'Nur ein veröffentlichtes Popup oder Banner mit Spectras Popup-Builder-Block darf aktiviert werden.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	return compact( 'title', 'status', 'type', 'enabled', 'repetition' );
}

/** @return bool */
function wpagent_spectra_rollback_popup( int $post_id, array $before, array $meta_before ): bool {
	wp_update_post( wp_slash( array(
		'ID' => $post_id, 'post_title' => $before['title'], 'post_name' => $before['slug'],
		'post_status' => $before['status'], 'post_type' => 'spectra-popup', 'post_content' => $before['content'],
	) ) );
	foreach ( $meta_before as $key => $snapshot ) wpagent_spectra_restore_popup_meta( $post_id, $key, $snapshot );
	$fresh = get_post( $post_id );
	if ( ! $fresh instanceof WP_Post || 'spectra-popup' !== $fresh->post_type || $fresh->post_title !== $before['title']
		|| $fresh->post_name !== $before['slug'] || $fresh->post_status !== $before['status'] || $fresh->post_content !== $before['content'] ) {
		return false;
	}
	foreach ( $meta_before as $key => $snapshot ) {
		if ( metadata_exists( 'post', $post_id, $key ) !== $snapshot['exists'] ) return false;
		if ( $snapshot['exists'] && get_post_meta( $post_id, $key, true ) !== $snapshot['value'] ) return false;
	}
	return true;
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_update_spectra_popup( $input ) {
	$available = wpagent_spectra_require_available();
	if ( is_wp_error( $available ) ) return $available;
	$input = is_array( $input ) ? $input : array();
	$post_id = absint( $input['id'] ?? 0 );
	$expected_hash = wpagent_spectra_expected_hash( $input['expected_hash'] ?? null );
	if ( is_wp_error( $expected_hash ) ) return $expected_hash;
	$lock = wpagent_site_editor_acquire_lock( 'spectra-popup', (string) $post_id );
	if ( is_wp_error( $lock ) ) return $lock;
	try {
		$post = wpagent_spectra_get_popup( $post_id );
		if ( is_wp_error( $post ) ) return $post;
		if ( 'trash' === $post->post_status ) return new WP_Error( 'wpagent_spectra_popup_trashed', __( 'Ein Popup im Papierkorb kann nicht aktualisiert werden.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		$before = wpagent_spectra_popup_state( $post, true );
		if ( is_wp_error( $before ) ) return $before;
		if ( ! hash_equals( $before['hash'], $expected_hash ) ) return new WP_Error( 'wpagent_spectra_conflict', __( 'Das Spectra-Popup wurde seit dem Lesen verändert.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $before['hash'] ) );
		$desired = wpagent_spectra_validate_popup_update( $input, $before );
		if ( is_wp_error( $desired ) ) return $desired;
		$desired_content = $before['content'];
		if ( array_key_exists( 'type', $input ) && 'unset' !== $desired['type'] && $desired['type'] !== $before['type'] ) {
			$desired_content = wpagent_spectra_retarget_popup_content( $before['content'], $desired['type'] );
			if ( is_wp_error( $desired_content ) ) return $desired_content;
		}
		$meta_before = array(
			'spectra-popup-type' => wpagent_spectra_popup_meta_snapshot( $post_id, 'spectra-popup-type' ),
			'spectra-popup-enabled' => wpagent_spectra_popup_meta_snapshot( $post_id, 'spectra-popup-enabled' ),
			'spectra-popup-repetition' => wpagent_spectra_popup_meta_snapshot( $post_id, 'spectra-popup-repetition' ),
		);
		try {
			if ( array_key_exists( 'enabled', $input ) && ! $desired['enabled'] ) update_post_meta( $post_id, 'spectra-popup-enabled', false );
			if ( $desired['title'] !== $before['title'] || $desired['status'] !== $before['status'] || $desired_content !== $before['content'] ) {
				$saved = wp_update_post( wp_slash( array(
					'ID' => $post_id, 'post_type' => 'spectra-popup', 'post_title' => $desired['title'],
					'post_status' => $desired['status'], 'post_content' => $desired_content,
				) ), true );
				if ( is_wp_error( $saved ) ) throw new RuntimeException( $saved->get_error_message() );
			}
			if ( array_key_exists( 'type', $input ) ) update_post_meta( $post_id, 'spectra-popup-type', $desired['type'] );
			if ( array_key_exists( 'repetition', $input ) ) update_post_meta( $post_id, 'spectra-popup-repetition', $desired['repetition'] );
			if ( array_key_exists( 'enabled', $input ) && $desired['enabled'] ) update_post_meta( $post_id, 'spectra-popup-enabled', true );
		} catch ( Throwable $error ) {
			$rolled_back = wpagent_spectra_rollback_popup( $post_id, $before, $meta_before );
			return new WP_Error( 'wpagent_spectra_save_failed', $error->getMessage(), array( 'status' => 500, 'rolled_back' => $rolled_back ) );
		}
		$fresh = wpagent_spectra_get_popup( $post_id );
		$after = is_wp_error( $fresh ) ? $fresh : wpagent_spectra_popup_state( $fresh, true );
		$wrapper = is_array( $after ) && 'unset' !== $desired['type'] ? wpagent_spectra_popup_native_contract( $after['content'] ) : null;
		$verified = is_array( $after ) && $after['title'] === $desired['title'] && $after['status'] === $desired['status']
			&& $after['type'] === $desired['type'] && $after['enabled'] === $desired['enabled'] && $after['repetition'] === $desired['repetition']
			&& $after['content'] === $desired_content && $after['has_popup_wrapper'] === $before['has_popup_wrapper']
			&& ( 'unset' === $desired['type'] || ( is_array( $wrapper ) && $wrapper['type'] === $desired['type'] ) );
		if ( ! $verified ) {
			$rolled_back = wpagent_spectra_rollback_popup( $post_id, $before, $meta_before );
			return new WP_Error( 'wpagent_spectra_verify_failed', __( 'Die Popup-Änderung bestand die Rückleseprüfung nicht.', 'wp-agent-companion' ), array( 'status' => 500, 'rolled_back' => $rolled_back ) );
		}
		return array( 'popup' => $after, 'verified' => true, 'previous_hash' => $before['hash'] );
	} finally {
		wpagent_site_editor_release_lock( 'spectra-popup', (string) $post_id, $lock );
	}
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_delete_spectra_popup( $input ) {
	$available = wpagent_spectra_require_available();
	if ( is_wp_error( $available ) ) return $available;
	$input = is_array( $input ) ? $input : array();
	$confirm = wpagent_spectra_boolean( $input['confirm'] ?? null, 'confirm' );
	if ( is_wp_error( $confirm ) ) return $confirm;
	if ( ! $confirm ) return new WP_Error( 'wpagent_spectra_confirmation', __( 'confirm=true ist zum Löschen erforderlich.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	$force = array_key_exists( 'force', $input ) ? wpagent_spectra_boolean( $input['force'], 'force' ) : false;
	if ( is_wp_error( $force ) ) return $force;
	$post_id = absint( $input['id'] ?? 0 );
	$expected_hash = wpagent_spectra_expected_hash( $input['expected_hash'] ?? null );
	if ( is_wp_error( $expected_hash ) ) return $expected_hash;
	$lock = wpagent_site_editor_acquire_lock( 'spectra-popup', (string) $post_id );
	if ( is_wp_error( $lock ) ) return $lock;
	try {
		$post = wpagent_spectra_get_popup( $post_id );
		if ( is_wp_error( $post ) ) return $post;
		$before = wpagent_spectra_popup_state( $post, false );
		if ( is_wp_error( $before ) ) return $before;
		if ( ! hash_equals( $before['hash'], $expected_hash ) ) return new WP_Error( 'wpagent_spectra_conflict', __( 'Das Spectra-Popup wurde seit dem Lesen verändert.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $before['hash'] ) );
		if ( $force ) {
			$deleted = wp_delete_post( $post_id, true );
			if ( ! $deleted || get_post( $post_id ) ) return new WP_Error( 'wpagent_spectra_delete_failed', __( 'Das Spectra-Popup konnte nicht endgültig gelöscht werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
			return array( 'id' => $post_id, 'trashed' => false, 'deleted' => true );
		}
		if ( defined( 'EMPTY_TRASH_DAYS' ) && 0 === (int) EMPTY_TRASH_DAYS ) {
			return new WP_Error( 'wpagent_spectra_trash_disabled', __( 'Der WordPress-Papierkorb ist deaktiviert. Verwende force=true nur für eine bewusst endgültige Löschung.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
		if ( 'trash' !== $post->post_status && ! wp_trash_post( $post_id ) ) return new WP_Error( 'wpagent_spectra_trash_failed', __( 'Das Spectra-Popup konnte nicht in den Papierkorb verschoben werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
		$fresh = get_post( $post_id );
		if ( ! $fresh instanceof WP_Post || 'trash' !== $fresh->post_status ) return new WP_Error( 'wpagent_spectra_trash_verify_failed', __( 'Der Papierkorbstatus des Spectra-Popups konnte nicht bestätigt werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
		return array( 'id' => $post_id, 'trashed' => true, 'deleted' => false );
	} finally {
		wpagent_site_editor_release_lock( 'spectra-popup', (string) $post_id, $lock );
	}
}
