<?php
/** Formidable Forms create, update, duplicate and delete abilities. */

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

/** @return array<string,mixed> */
function wpagent_formidable_write_properties_schema(): array {
	return array(
		'form_key' => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 100, 'pattern' => '^[A-Za-z0-9_-]+$' ),
		'name' => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 255 ),
		'description' => array( 'type' => 'string', 'maxLength' => 10000 ),
		'status' => array( 'type' => 'string', 'enum' => array( 'published', 'draft' ) ),
	);
}

/** @return array<string,mixed> */
function wpagent_formidable_write_output_schema(): array {
	return array(
		'type'       => 'object',
		'properties' => array(
			'form' => wpagent_formidable_form_output_schema(),
			'verified' => array( 'type' => 'boolean' ),
		),
	);
}

/** @param array<string,mixed> $input @return array<string,mixed> */
function wpagent_formidable_prepare_form_values( array $input, bool $creating ): array {
	$values = array();
	foreach ( array( 'name', 'description', 'status' ) as $key ) {
		if ( array_key_exists( $key, $input ) ) {
			$values[ $key ] = $input[ $key ];
		}
	}
	if ( isset( $values['name'] ) ) {
		$values['name'] = sanitize_text_field( (string) $values['name'] );
	}
	if ( isset( $values['description'] ) ) {
		$values['description'] = sanitize_textarea_field( (string) $values['description'] );
	}
	if ( isset( $values['status'] ) ) {
		$values['status'] = sanitize_key( (string) $values['status'] );
	}
	if ( $creating ) {
		$values['description'] = (string) ( $values['description'] ?? '' );
		$values['form_key']    = sanitize_title( (string) ( $input['form_key'] ?? $input['name'] ?? '' ) );
		if ( '' === $values['form_key'] ) {
			$values['form_key'] = 'wpagently-form';
		}
		$values['options']  = array();
	}
	return $values;
}

/** @param array<string,mixed> $field @return array<string,mixed> */
function wpagent_formidable_comparable_field( array $field ): array {
	unset( $field['id'], $field['field_key'] );
	return $field;
}

/** @param array<string,mixed> $field @return array<string,mixed> */
function wpagent_formidable_duplicate_comparable_field( array $field ): array {
	unset( $field['id'], $field['field_key'], $field['description'], $field['default_value'] );
	return $field;
}

/** @param mixed $field @return array<string,mixed> */
function wpagent_formidable_raw_field_values( $field ): array {
	$data   = is_object( $field ) ? get_object_vars( $field ) : ( is_array( $field ) ? $field : array() );
	$values = array();
	foreach ( array( 'field_key', 'name', 'description', 'type', 'default_value', 'options', 'field_order', 'required', 'field_options' ) as $key ) {
		if ( array_key_exists( $key, $data ) ) {
			$values[ $key ] = wpagent_formidable_json_value( $data[ $key ] );
		}
	}
	return $values;
}

/**
 * Captures public verification data and complete provider-owned field options for rollback.
 * The raw part never leaves the server.
 *
 * @param mixed $form
 * @param int[] $raw_field_ids
 * @return array{public:array<string,mixed>,form_values:array<string,mixed>,fields:array<int,array<string,mixed>>}
 */
function wpagent_formidable_capture_snapshot( $form, array $raw_field_ids = array() ): array {
	$data       = is_object( $form ) ? get_object_vars( $form ) : ( is_array( $form ) ? $form : array() );
	$form_id    = absint( $data['id'] ?? 0 );
	$public     = wpagent_formidable_form_payload( $form, false );
	$raw_fields = array();
	$raw_lookup = array_fill_keys( array_filter( array_map( 'absint', $raw_field_ids ) ), true );
	foreach ( wpagent_formidable_bounded_fields( $form_id ) as $field ) {
		$field_id = absint( is_object( $field ) ? ( $field->id ?? 0 ) : ( $field['id'] ?? 0 ) );
		if ( $field_id <= 0 ) {
			continue;
		}
		$public['fields'][] = wpagent_formidable_field_payload( $field );
		if ( isset( $raw_lookup[ $field_id ] ) ) {
			$raw_fields[ $field_id ] = wpagent_formidable_raw_field_values( $field );
		}
	}
	$form_values = array();
	foreach ( array( 'name', 'description', 'status' ) as $key ) {
		if ( array_key_exists( $key, $data ) ) {
			$form_values[ $key ] = $data[ $key ];
		}
	}
	return array( 'public' => $public, 'form_values' => $form_values, 'fields' => $raw_fields );
}

/** @param array<int,array<string,mixed>> $expected @param array<int,array<string,mixed>> $actual */
function wpagent_formidable_comparable_fields_match( array $expected, array $actual ): bool {
	if ( count( $expected ) !== count( $actual ) ) {
		return false;
	}
	$normalize = static function ( array $fields ): array {
		$values = array_map(
			static fn( array $field ): string => (string) wp_json_encode( wpagent_formidable_duplicate_comparable_field( $field ) ),
			$fields
		);
		sort( $values, SORT_STRING );
		return $values;
	};
	return $normalize( $expected ) === $normalize( $actual );
}

/** @param array<string,mixed> $expected @param array<string,mixed> $actual */
function wpagent_formidable_form_request_matches( array $expected, array $actual ): bool {
	foreach ( array( 'form_key', 'name', 'description', 'status' ) as $key ) {
		if ( array_key_exists( $key, $expected ) && (string) $expected[ $key ] !== (string) ( $actual[ $key ] ?? '' ) ) {
			return false;
		}
	}
	return true;
}

/** @param array<string,mixed> $requested @param array<string,mixed> $actual */
function wpagent_formidable_field_request_matches( array $requested, array $actual ): bool {
	$prepared = wpagent_formidable_prepare_field_values( $requested, 0, false );
	foreach ( $prepared as $key => $value ) {
		$matches = 'options' === $key
			? wpagent_formidable_exact_matches( $value, $actual[ $key ] ?? null )
			: wpagent_formidable_subset_matches( $value, $actual[ $key ] ?? null );
		if ( 'form_id' === $key || ! array_key_exists( $key, $actual ) || ! $matches ) {
			return false;
		}
	}
	return true;
}

/**
 * @param array{public:array<string,mixed>,form_values:array<string,mixed>,fields:array<int,array<string,mixed>>} $snapshot
 * @param int[] $created_field_ids
 * @param int[] $modified_field_ids
 * @param string[] $modified_form_keys
 */
function wpagent_formidable_restore_snapshot( array $snapshot, array $created_field_ids, array $modified_field_ids, array $modified_form_keys ): bool {
	$form_id = absint( $snapshot['public']['id'] ?? 0 );
	if ( $form_id <= 0 ) {
		return false;
	}
	$restored           = true;
	$modified_field_ids = array_unique( array_filter( array_map( 'absint', $modified_field_ids ) ) );
	$created_field_ids  = array_unique( array_filter( array_map( 'absint', $created_field_ids ) ) );
	$form_values        = array_intersect_key( $snapshot['form_values'], array_fill_keys( $modified_form_keys, true ) );
	try {
		if ( $form_values ) {
			FrmForm::update( $form_id, $form_values );
		}
	} catch ( Throwable $error ) {
		$restored = false;
	}
	foreach ( $modified_field_ids as $field_id ) {
		try {
			if ( ! isset( $snapshot['fields'][ $field_id ] ) || ! is_object( FrmField::getOne( $field_id ) ) ) {
				$restored = false;
				continue;
			}
			FrmField::update( $field_id, $snapshot['fields'][ $field_id ] );
		} catch ( Throwable $error ) {
			$restored = false;
		}
	}
	foreach ( $created_field_ids as $field_id ) {
		try {
			if ( is_object( FrmField::getOne( $field_id ) ) ) {
				FrmField::destroy( $field_id );
			}
		} catch ( Throwable $error ) {
			$restored = false;
		}
	}
	try {
		$fresh        = FrmForm::getOne( $form_id );
		$fresh_fields = array();
		foreach ( $modified_field_ids as $field_id ) {
			$fresh_fields[ $field_id ] = FrmField::getOne( $field_id );
		}
	} catch ( Throwable $error ) {
		return false;
	}
	if ( ! $restored || ! is_object( $fresh ) ) {
		return false;
	}
	try {
		$actual = wpagent_formidable_form_payload( $fresh );
	} catch ( Throwable $error ) {
		return false;
	}
	$public = $snapshot['public'];
	if ( ! wpagent_formidable_form_request_matches( $public, $actual ) || count( $actual['fields'] ) !== count( $public['fields'] ?? array() ) ) {
		return false;
	}
	$actual_by_id = array_column( $actual['fields'], null, 'id' );
	foreach ( $public['fields'] ?? array() as $field ) {
		$field_id = absint( $field['id'] ?? 0 );
		if ( ! isset( $actual_by_id[ $field_id ] ) || ! wpagent_formidable_exact_matches( wpagent_formidable_comparable_field( $field ), wpagent_formidable_comparable_field( $actual_by_id[ $field_id ] ) ) ) {
			return false;
		}
	}
	$fresh_form_data = get_object_vars( $fresh );
	foreach ( $modified_form_keys as $key ) {
		if ( ! array_key_exists( $key, $snapshot['form_values'] ) || ! array_key_exists( $key, $fresh_form_data ) || ! wpagent_formidable_exact_matches( $snapshot['form_values'][ $key ], $fresh_form_data[ $key ] ) ) {
			return false;
		}
	}
	foreach ( $modified_field_ids as $field_id ) {
		if ( ! is_object( $fresh_fields[ $field_id ] ?? null ) || ! wpagent_formidable_exact_matches( $snapshot['fields'][ $field_id ], wpagent_formidable_raw_field_values( $fresh_fields[ $field_id ] ) ) ) {
			return false;
		}
	}
	return true;
}

function wpagent_formidable_delete_and_verify( int $form_id ): bool {
	try {
		$field_ids = array();
		foreach ( (array) FrmField::get_all_for_form( $form_id ) as $field ) {
			$field_id = absint( is_object( $field ) ? ( $field->id ?? 0 ) : ( $field['id'] ?? 0 ) );
			if ( $field_id > 0 ) {
				$field_ids[] = $field_id;
			}
		}
		$entry_ids = class_exists( 'FrmDb' ) && class_exists( 'FrmEntry' )
			? array_values( array_filter( array_map( 'absint', FrmDb::get_col( 'frm_items', array( 'form_id' => $form_id ), 'id' ) ) ) )
			: array();
		FrmForm::destroy( $form_id );
		if ( is_object( FrmForm::getOne( $form_id ) ) ) {
			return false;
		}
		// Formidable uses a MySQL-specific DELETE JOIN for fields. If the provider
		// leaves rows behind, remove them through its public field model instead.
		foreach ( $field_ids as $field_id ) {
			if ( is_object( FrmField::getOne( $field_id ) ) ) {
				FrmField::destroy( $field_id );
			}
		}
		foreach ( $field_ids as $field_id ) {
			if ( is_object( FrmField::getOne( $field_id ) ) ) {
				return false;
			}
		}
		foreach ( $entry_ids as $entry_id ) {
			if ( is_object( FrmEntry::getOne( $entry_id ) ) ) {
				FrmEntry::destroy( $entry_id );
			}
		}
		foreach ( $entry_ids as $entry_id ) {
			if ( is_object( FrmEntry::getOne( $entry_id ) ) ) {
				return false;
			}
		}
		return true;
	} catch ( Throwable $error ) {
		return false;
	}
}

function wpagent_ability_create_formidable_form(): array {
	$properties           = wpagent_formidable_write_properties_schema();
	$properties['fields'] = array( 'type' => 'array', 'maxItems' => 500, 'items' => wpagent_formidable_field_schema( false ) );
	return array(
		'label'               => __( 'Formidable-Forms-Formular erstellen', 'wp-agent-companion' ),
		'description'         => __( 'Erstellt ein Formidable-Forms-Formular mit bis zu 500 strikt validierten Feldern über die native Modell-API. Fehler werden vollständig zurückgerollt.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array( 'type' => 'object', 'additionalProperties' => false, 'properties' => $properties, 'required' => array( 'name' ) ),
		'output_schema'       => wpagent_formidable_write_output_schema(),
		'execute_callback'    => 'wpagent_exec_create_formidable_form',
		'permission_callback' => 'wpagent_perm_formidable_edit',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => false ) ),
	);
}

/** @param mixed $input @return array|WP_Error */
function wpagent_exec_create_formidable_form( $input ) {
	if ( ! wpagent_formidable_available() ) {
		return wpagent_formidable_missing_error();
	}
	$input = is_array( $input ) ? $input : array();
	$lock  = wpagent_formidable_acquire_mutation_lock();
	if ( is_wp_error( $lock ) ) {
		return $lock;
	}
	$form_id = 0;
	try {
		try {
			$form_id = absint( FrmForm::create( wpagent_formidable_prepare_form_values( $input, true ) ) );
			if ( $form_id <= 0 ) {
				throw new RuntimeException( 'Form creation failed.' );
			}
			foreach ( is_array( $input['fields'] ?? null ) ? $input['fields'] : array() as $field ) {
				$field_id = absint( FrmField::create( wpagent_formidable_prepare_field_values( $field, $form_id, true ) ) );
				if ( $field_id <= 0 ) {
					throw new RuntimeException( 'Field creation failed.' );
				}
			}
			$fresh  = FrmForm::getOne( $form_id );
			$actual = is_object( $fresh ) ? wpagent_formidable_form_payload( $fresh ) : array();
		} catch ( Throwable $error ) {
			if ( $form_id > 0 && ! wpagent_formidable_delete_and_verify( $form_id ) ) {
				return new WP_Error( 'wpagent_formidable_rollback_failed', __( 'Das unvollständige Formidable-Forms-Formular konnte nicht zurückgerollt werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
			}
			return new WP_Error( 'wpagent_formidable_create_failed', __( 'Das Formidable-Forms-Formular konnte nicht vollständig erstellt werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
		}
		$requested = wpagent_formidable_prepare_form_values( $input, true );
		unset( $requested['options'] );
		if ( ! array_key_exists( 'form_key', $input ) ) {
			unset( $requested['form_key'] );
		}
		$verified  = wpagent_formidable_form_request_matches( $requested, $actual )
			&& count( $actual['fields'] ?? array() ) === count( $input['fields'] ?? array() );
		foreach ( $input['fields'] ?? array() as $index => $field ) {
			$verified = $verified && isset( $actual['fields'][ $index ] ) && wpagent_formidable_field_request_matches( $field, $actual['fields'][ $index ] );
		}
		if ( ! $verified ) {
			if ( ! wpagent_formidable_delete_and_verify( $form_id ) ) {
				return new WP_Error( 'wpagent_formidable_rollback_failed', __( 'Das unverifizierte Formidable-Forms-Formular konnte nicht zurückgerollt werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
			}
			return new WP_Error( 'wpagent_formidable_create_unverified', __( 'Das Formidable-Forms-Formular wich nach dem Speichern von der Anforderung ab und wurde entfernt.', 'wp-agent-companion' ), array( 'status' => 500 ) );
		}
		return array( 'form' => $actual, 'verified' => true );
	} finally {
		wpagent_formidable_release_mutation_lock( $lock );
	}
}

function wpagent_ability_update_formidable_form(): array {
	$properties              = array( 'form_id' => array( 'type' => 'integer', 'minimum' => 1 ) ) + wpagent_formidable_write_properties_schema();
	unset( $properties['form_key'] );
	$properties['fields']    = array( 'type' => 'array', 'maxItems' => 500, 'items' => wpagent_formidable_field_schema( true ) );
	return array(
		'label'               => __( 'Formidable-Forms-Formular aktualisieren', 'wp-agent-companion' ),
		'description'         => __( 'Aktualisiert Formulardaten und Felder additiv. Nicht genannte Felder bleiben erhalten. Jede Änderung wird rückgelesen und bei Abweichungen zurückgerollt.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array( 'type' => 'object', 'additionalProperties' => false, 'properties' => $properties, 'required' => array( 'form_id' ), 'minProperties' => 2 ),
		'output_schema'       => wpagent_formidable_write_output_schema(),
		'execute_callback'    => 'wpagent_exec_update_formidable_form',
		'permission_callback' => 'wpagent_perm_formidable_edit',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => true ) ),
	);
}

/** @param mixed $input @return array|WP_Error */
function wpagent_exec_update_formidable_form( $input ) {
	$input = is_array( $input ) ? $input : array();
	$form  = wpagent_formidable_get_authorized_form( $input, 'frm_edit_forms' );
	if ( is_wp_error( $form ) ) {
		return $form;
	}
	$lock = wpagent_formidable_acquire_mutation_lock();
	if ( is_wp_error( $lock ) ) {
		return $lock;
	}
	$form_id           = absint( $input['form_id'] ?? 0 );
	$created_field_ids = array();
	$modified_field_ids = array();
	$modified_form_keys = array();
	try {
		try {
			$fresh_form = FrmForm::getOne( $form_id );
			if ( ! is_object( $fresh_form ) ) {
				return new WP_Error( 'wpagent_formidable_form_not_found', __( 'Formidable-Forms-Formular nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
			}
			$requested_field_ids = array();
			foreach ( is_array( $input['fields'] ?? null ) ? $input['fields'] : array() as $requested_field ) {
				if ( absint( $requested_field['id'] ?? 0 ) > 0 ) {
					$requested_field_ids[] = absint( $requested_field['id'] );
				}
			}
			$snapshot = wpagent_formidable_capture_snapshot( $fresh_form, $requested_field_ids );
		} catch ( OverflowException $error ) {
			return wpagent_formidable_payload_limit_error();
		} catch ( Throwable $error ) {
			return wpagent_formidable_provider_error();
		}
		$snapshot_by_id = array_column( $snapshot['public']['fields'], null, 'id' );
		foreach ( is_array( $input['fields'] ?? null ) ? $input['fields'] : array() as $field ) {
			$field_id = absint( $field['id'] ?? 0 );
			if ( $field_id <= 0 ) {
				continue;
			}
			if ( ! isset( $snapshot_by_id[ $field_id ] ) ) {
				return new WP_Error( 'wpagent_formidable_foreign_field', __( 'Mindestens ein Feld gehört nicht zu diesem Formidable-Forms-Formular.', 'wp-agent-companion' ), array( 'status' => 400 ) );
			}
			$target_type = sanitize_key( (string) ( $field['type'] ?? $snapshot_by_id[ $field_id ]['type'] ?? '' ) );
			if ( wpagent_formidable_sensitive_field_type( $target_type ) && array_key_exists( 'default_value', $field ) ) {
				return new WP_Error( 'wpagent_formidable_sensitive_default', __( 'Standardwerte von Passwort- und versteckten Feldern können aus Sicherheitsgründen nicht über die Agent-Schnittstelle geändert werden.', 'wp-agent-companion' ), array( 'status' => 400 ) );
			}
		}
		try {
			$form_values = wpagent_formidable_prepare_form_values( $input, false );
			if ( $form_values ) {
				$modified_form_keys = array_keys( $form_values );
				FrmForm::update( $form_id, $form_values );
			}
			foreach ( is_array( $input['fields'] ?? null ) ? $input['fields'] : array() as $field ) {
				$field_id = absint( $field['id'] ?? 0 );
				if ( $field_id > 0 ) {
					$values = wpagent_formidable_prepare_field_values( $field, $form_id, false );
					if ( $values ) {
						if ( isset( $values['field_options'] ) ) {
							$existing_options        = is_array( $snapshot['fields'][ $field_id ]['field_options'] ?? null ) ? $snapshot['fields'][ $field_id ]['field_options'] : array();
							$values['field_options'] = array_replace( $existing_options, $values['field_options'] );
						}
						$modified_field_ids[] = $field_id;
						FrmField::update( $field_id, $values );
					}
				} else {
					$field_id = absint( FrmField::create( wpagent_formidable_prepare_field_values( $field, $form_id, true ) ) );
					if ( $field_id <= 0 ) {
						throw new RuntimeException( 'Field creation failed.' );
					}
					$created_field_ids[] = $field_id;
				}
			}
			$fresh  = FrmForm::getOne( $form_id );
			$actual = is_object( $fresh ) ? wpagent_formidable_form_payload( $fresh ) : array();
		} catch ( Throwable $error ) {
			if ( ! wpagent_formidable_restore_snapshot( $snapshot, $created_field_ids, $modified_field_ids, $modified_form_keys ) ) {
				return new WP_Error( 'wpagent_formidable_rollback_failed', __( 'Die fehlgeschlagene Formidable-Forms-Änderung konnte nicht vollständig zurückgerollt werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
			}
			return new WP_Error( 'wpagent_formidable_update_failed', __( 'Das Formidable-Forms-Formular konnte nicht vollständig aktualisiert werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
		}
		$verified = wpagent_formidable_form_request_matches( wpagent_formidable_prepare_form_values( $input, false ), $actual )
			&& count( $actual['fields'] ?? array() ) === count( $snapshot['public']['fields'] ) + count( $created_field_ids );
		$actual_by_id = array_column( $actual['fields'] ?? array(), null, 'id' );
		$new_index     = 0;
		foreach ( $input['fields'] ?? array() as $field ) {
			$field_id = absint( $field['id'] ?? 0 );
			if ( $field_id <= 0 ) {
				$field_id = $created_field_ids[ $new_index ] ?? 0;
				++$new_index;
			}
			$verified = $verified && isset( $actual_by_id[ $field_id ] ) && wpagent_formidable_field_request_matches( $field, $actual_by_id[ $field_id ] );
		}
		if ( ! $verified ) {
			if ( ! wpagent_formidable_restore_snapshot( $snapshot, $created_field_ids, $modified_field_ids, $modified_form_keys ) ) {
				return new WP_Error( 'wpagent_formidable_rollback_failed', __( 'Die unverifizierte Formidable-Forms-Änderung konnte nicht vollständig zurückgerollt werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
			}
			return new WP_Error( 'wpagent_formidable_update_unverified', __( 'Das Formidable-Forms-Formular wich nach dem Speichern von der Anforderung ab. Die Änderung wurde zurückgerollt.', 'wp-agent-companion' ), array( 'status' => 500 ) );
		}
		return array( 'form' => $actual, 'verified' => true );
	} finally {
		wpagent_formidable_release_mutation_lock( $lock );
	}
}

function wpagent_ability_duplicate_formidable_form(): array {
	return array(
		'label'               => __( 'Formidable-Forms-Formular duplizieren', 'wp-agent-companion' ),
		'description'         => __( 'Dupliziert ein Formidable-Forms-Formular nativ, prüft die vollständige Feldstruktur und entfernt abweichende Kopien.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array( 'type' => 'object', 'additionalProperties' => false, 'properties' => array( 'form_id' => array( 'type' => 'integer', 'minimum' => 1 ), 'name' => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 255 ) ), 'required' => array( 'form_id' ) ),
		'output_schema'       => wpagent_formidable_write_output_schema(),
		'execute_callback'    => 'wpagent_exec_duplicate_formidable_form',
		'permission_callback' => 'wpagent_perm_formidable_edit',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => false ) ),
	);
}

/** @param mixed $input @return array|WP_Error */
function wpagent_exec_duplicate_formidable_form( $input ) {
	$input  = is_array( $input ) ? $input : array();
	$source = wpagent_formidable_get_authorized_form( $input, 'frm_edit_forms' );
	if ( is_wp_error( $source ) ) {
		return $source;
	}
	$lock = wpagent_formidable_acquire_mutation_lock();
	if ( is_wp_error( $lock ) ) {
		return $lock;
	}
	$copy_id = 0;
	try {
		try {
			$source = FrmForm::getOne( absint( $input['form_id'] ?? 0 ) );
			if ( ! is_object( $source ) ) {
				return new WP_Error( 'wpagent_formidable_form_not_found', __( 'Formidable-Forms-Formular nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
			}
			$source_payload = wpagent_formidable_form_payload( $source );
		} catch ( OverflowException $error ) {
			return wpagent_formidable_payload_limit_error();
		} catch ( Throwable $error ) {
			return wpagent_formidable_provider_error();
		}
		try {
			$copy_id = absint( FrmForm::duplicate( $source_payload['id'], false, false, false ) );
			if ( $copy_id <= 0 ) {
				throw new RuntimeException( 'Duplication failed.' );
			}
			if ( isset( $input['name'] ) ) {
				FrmForm::update( $copy_id, array( 'name' => sanitize_text_field( (string) $input['name'] ) ) );
			}
			$copy   = FrmForm::getOne( $copy_id );
			$actual = is_object( $copy ) ? wpagent_formidable_form_payload( $copy ) : array();
		} catch ( Throwable $error ) {
			if ( $copy_id > 0 && ! wpagent_formidable_delete_and_verify( $copy_id ) ) {
				return new WP_Error( 'wpagent_formidable_rollback_failed', __( 'Die unvollständige Formularkopie konnte nicht zurückgerollt werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
			}
			return new WP_Error( 'wpagent_formidable_duplicate_failed', __( 'Das Formidable-Forms-Formular konnte nicht dupliziert werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
		}
		$verified = $actual
			&& $actual['id'] !== $source_payload['id']
			&& $actual['status'] === $source_payload['status']
			&& $actual['description'] === $source_payload['description']
			&& $actual['name'] === ( isset( $input['name'] ) ? sanitize_text_field( (string) $input['name'] ) : $source_payload['name'] )
			&& wpagent_formidable_comparable_fields_match( $source_payload['fields'], $actual['fields'] );
		if ( ! $verified ) {
			if ( ! wpagent_formidable_delete_and_verify( $copy_id ) ) {
				return new WP_Error( 'wpagent_formidable_rollback_failed', __( 'Die abweichende Formularkopie konnte nicht zurückgerollt werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
			}
			return new WP_Error( 'wpagent_formidable_duplicate_unverified', __( 'Die Formularkopie wich vom Quellformular ab und wurde entfernt.', 'wp-agent-companion' ), array( 'status' => 500 ) );
		}
		return array( 'form' => $actual, 'verified' => true );
	} finally {
		wpagent_formidable_release_mutation_lock( $lock );
	}
}

function wpagent_ability_delete_formidable_form(): array {
	return array(
		'label'               => __( 'Formidable-Forms-Formular dauerhaft löschen', 'wp-agent-companion' ),
		'description'         => __( 'Löscht ein Formular einschließlich seiner Felder und Einträge dauerhaft. confirm=true ist zwingend erforderlich.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type' => 'object', 'additionalProperties' => false,
			'properties' => array(
				'form_id' => array( 'type' => 'integer', 'minimum' => 1 ),
				'confirm' => array( 'type' => 'boolean' ),
				'expected_form_key' => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 100, 'pattern' => '^[A-Za-z0-9_-]+$' ),
			),
			'required' => array( 'form_id', 'confirm' ),
		),
		'output_schema'       => array( 'type' => 'object', 'properties' => array( 'form_id' => array( 'type' => 'integer' ), 'deleted' => array( 'type' => 'boolean' ) ) ),
		'execute_callback'    => 'wpagent_exec_delete_formidable_form',
		'permission_callback' => 'wpagent_perm_formidable_delete',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => true, 'idempotent' => false ) ),
	);
}

/** @param mixed $input @return array|WP_Error */
function wpagent_exec_delete_formidable_form( $input ) {
	$input = is_array( $input ) ? $input : array();
	if ( true !== ( $input['confirm'] ?? false ) ) {
		return new WP_Error( 'wpagent_confirmation_required', __( 'Dauerhaftes Löschen erfordert confirm=true.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$form = wpagent_formidable_get_authorized_form( $input, 'frm_delete_forms' );
	if ( is_wp_error( $form ) ) {
		return $form;
	}
	$lock = wpagent_formidable_acquire_mutation_lock();
	if ( is_wp_error( $lock ) ) {
		return $lock;
	}
	try {
		$form_id = absint( $input['form_id'] ?? 0 );
		try {
			$fresh = FrmForm::getOne( $form_id );
		} catch ( Throwable $error ) {
			return wpagent_formidable_provider_error();
		}
		if ( ! is_object( $fresh ) ) {
			return new WP_Error( 'wpagent_formidable_form_not_found', __( 'Formidable-Forms-Formular nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
		}
		$form_key = sanitize_key( (string) ( $fresh->form_key ?? '' ) );
		if ( isset( $input['expected_form_key'] ) && sanitize_key( (string) $input['expected_form_key'] ) !== $form_key ) {
			return new WP_Error( 'wpagent_formidable_stale_form', __( 'expected_form_key stimmt nicht mehr mit dem Formular überein. Das Formular wurde nicht gelöscht.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
		if ( ! wpagent_formidable_delete_and_verify( $form_id ) ) {
			return new WP_Error( 'wpagent_formidable_delete_failed', __( 'Das Formidable-Forms-Formular konnte nicht vollständig gelöscht werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
		}
		return array( 'form_id' => $form_id, 'deleted' => true );
	} finally {
		wpagent_formidable_release_mutation_lock( $lock );
	}
}
