<?php
/** Conflict-protected WPForms confirmation and notification creation and deletion. */

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

/** @param array<string,mixed> $extra_properties @return array<string,mixed> */
function wpagent_wpforms_delivery_mutation_output_schema( array $extra_properties ): array {
	return array(
		'type'       => 'object',
		'properties' => array_merge(
			wpagent_wpforms_delivery_output_schema()['properties'],
			array( 'verified' => array( 'type' => 'boolean' ) ),
			$extra_properties
		),
	);
}

/** @return array<string,mixed> */
function wpagent_wpforms_confirmation_input_properties(): array {
	$properties = wpagent_wpforms_confirmation_schema()['properties'];
	unset( $properties['id'], $properties['hash'] );
	$properties['name']['maxLength']                = 255;
	$properties['message']['maxLength']             = 100000;
	$properties['page_id']['minimum']               = 0;
	$properties['page_url_parameters']['maxLength'] = 4096;
	$properties['redirect']['maxLength']            = 4096;
	return $properties;
}

/** @return array<string,mixed> */
function wpagent_wpforms_notification_input_properties(): array {
	$properties = wpagent_wpforms_notification_schema()['properties'];
	unset( $properties['id'], $properties['hash'] );
	$properties['name']['maxLength']    = 255;
	$properties['subject']['maxLength'] = 998;
	$properties['message']['maxLength'] = 100000;
	foreach ( array( 'email', 'sender_address', 'reply_to', 'carbon_copy' ) as $field ) {
		$properties[ $field ]['maxLength'] = 2000;
	}
	return $properties;
}

function wpagent_ability_create_wpforms_confirmation(): array {
	return array(
		'label'       => __( 'WPForms-Bestätigung erstellen', 'wp-agent-companion' ),
		'description' => __( 'Erstellt die erste WPForms-Bestätigung oder unter WPForms Pro eine weitere Bestätigung mit nativer numerischer ID. WPForms Lite lehnt eine zweite Regel ab. Der vollständige Formular-Hash, eine Kurzzeitsperre, Provider-Read-back und ein exakter Rollback schützen parallele oder unvollständige Änderungen.', 'wp-agent-companion' ),
		'category'    => 'wp-agent',
		'input_schema' => array(
			'type'                 => 'object',
			'additionalProperties' => false,
			'properties'           => array(
				'form_id'       => array( 'type' => 'integer', 'minimum' => 1 ),
				'expected_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'confirmation'  => array(
					'type'                 => 'object',
					'additionalProperties' => false,
					'properties'           => wpagent_wpforms_confirmation_input_properties(),
					'required'             => array( 'name', 'type' ),
				),
			),
			'required'             => array( 'form_id', 'expected_hash', 'confirmation' ),
		),
		'output_schema'       => wpagent_wpforms_delivery_mutation_output_schema( array( 'created_confirmation_id' => array( 'type' => 'integer' ) ) ),
		'execute_callback'    => 'wpagent_exec_create_wpforms_confirmation',
		'permission_callback' => 'wpagent_perm_wpforms_delivery',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => false ) ),
	);
}

/** @param mixed $input @return array<string,mixed>|WP_Error */
function wpagent_exec_create_wpforms_confirmation( $input ) {
	$input   = is_array( $input ) ? $input : array();
	$payload = is_array( $input['confirmation'] ?? null ) ? $input['confirmation'] : array();
	$new_id  = 0;
	$result  = wpagent_wpforms_delivery_mutate(
		$input,
		static function ( array $before ) use ( $payload, &$new_id ) {
			$allowed = wpagent_wpforms_delivery_can_create( $before['confirmations'] );
			if ( is_wp_error( $allowed ) ) {
				return $allowed;
			}
			$new_id = wpagent_wpforms_delivery_next_id( $before['confirmations'] );
			if ( is_wp_error( $new_id ) ) {
				return $new_id;
			}
			$prepared = wpagent_wpforms_prepare_confirmation(
				array(
					'name'                => '',
					'type'                => 'message',
					'message'             => '',
					'message_scroll'      => '1',
					'page'                => '',
					'page_url_parameters' => '',
					'redirect'            => '',
					'redirect_new_tab'    => '0',
				),
				$payload
			);
			if ( is_wp_error( $prepared ) ) {
				return $prepared;
			}
			if ( '' === trim( (string) ( $prepared['name'] ?? '' ) ) ) {
				return new WP_Error( 'wpagent_wpforms_confirmation_name', __( 'Eine neue WPForms-Bestätigung benötigt name.', 'wp-agent-companion' ), array( 'status' => 400 ) );
			}
			$target = $before['data'];
			$target['settings']['confirmations'][ (string) $new_id ] = $prepared;
			return $target;
		}
	);
	if ( is_wp_error( $result ) ) {
		return $result;
	}
	$result['created_confirmation_id'] = $new_id;
	return $result;
}

function wpagent_ability_delete_wpforms_confirmation(): array {
	return array(
		'label'       => __( 'WPForms-Bestätigung löschen', 'wp-agent-companion' ),
		'description' => __( 'Löscht eine zusätzliche WPForms-Bestätigung erst nach Wiederholung ihrer exakten ID. Mindestens eine Bestätigung bleibt erhalten. Der Schreibpfad ist vollständig konfliktgeschützt und wird per Provider-Read-back verifiziert.', 'wp-agent-companion' ),
		'category'    => 'wp-agent',
		'input_schema' => array(
			'type'                 => 'object',
			'additionalProperties' => false,
			'properties'           => array(
				'form_id'                 => array( 'type' => 'integer', 'minimum' => 1 ),
				'confirmation_id'         => array( 'type' => 'integer', 'minimum' => 1 ),
				'confirm_confirmation_id' => array( 'type' => 'integer', 'minimum' => 1 ),
				'expected_hash'           => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
			),
			'required'             => array( 'form_id', 'confirmation_id', 'confirm_confirmation_id', 'expected_hash' ),
		),
		'output_schema'       => wpagent_wpforms_delivery_mutation_output_schema( array( 'deleted_confirmation_id' => array( 'type' => 'integer' ) ) ),
		'execute_callback'    => 'wpagent_exec_delete_wpforms_confirmation',
		'permission_callback' => 'wpagent_perm_wpforms_delivery',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => true, 'idempotent' => false ) ),
	);
}

/** @param mixed $input @return array<string,mixed>|WP_Error */
function wpagent_exec_delete_wpforms_confirmation( $input ) {
	$input      = is_array( $input ) ? $input : array();
	$id         = absint( $input['confirmation_id'] ?? 0 );
	$confirmed  = $input['confirm_confirmation_id'] ?? null;
	if ( ! is_int( $confirmed ) || $id <= 0 || $confirmed !== $id ) {
		return new WP_Error( 'wpagent_wpforms_confirmation_confirmation', __( 'confirm_confirmation_id muss die zu löschende confirmation_id exakt wiederholen.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$result = wpagent_wpforms_delivery_mutate(
		$input,
		static function ( array $before ) use ( $id ) {
			if ( ! isset( $before['confirmations'][ $id ] ) ) {
				return new WP_Error( 'wpagent_wpforms_confirmation_not_found', __( 'Die WPForms-Bestätigung wurde nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
			}
			if ( count( $before['confirmations'] ) <= 1 ) {
				return new WP_Error( 'wpagent_wpforms_confirmation_required', __( 'Die letzte WPForms-Bestätigung kann nicht gelöscht werden.', 'wp-agent-companion' ), array( 'status' => 409 ) );
			}
			$target = $before['data'];
			unset( $target['settings']['confirmations'][ (string) $id ], $target['settings']['confirmations'][ $id ] );
			return $target;
		}
	);
	if ( is_wp_error( $result ) ) {
		return $result;
	}
	$result['deleted_confirmation_id'] = $id;
	return $result;
}

function wpagent_ability_create_wpforms_notification(): array {
	return array(
		'label'       => __( 'WPForms-Benachrichtigung erstellen', 'wp-agent-companion' ),
		'description' => __( 'Erstellt die erste native WPForms-E-Mail-Benachrichtigung oder unter WPForms Pro eine weitere und kann den globalen Versandschalter ausdrücklich setzen. WPForms Lite lehnt eine zweite Regel ab, weil seine Laufzeit nur die erste sendet. Empfänger, Kopfzeilen und Nachricht werden begrenzt und nach dem Speichern vollständig verifiziert.', 'wp-agent-companion' ),
		'category'    => 'wp-agent',
		'input_schema' => array(
			'type'                 => 'object',
			'additionalProperties' => false,
			'properties'           => array(
				'form_id'               => array( 'type' => 'integer', 'minimum' => 1 ),
				'expected_hash'         => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'notifications_enabled' => array( 'type' => 'boolean' ),
				'notification'          => array(
					'type'                 => 'object',
					'additionalProperties' => false,
					'properties'           => wpagent_wpforms_notification_input_properties(),
					'required'             => array( 'name', 'email', 'subject', 'sender_name', 'sender_address', 'message' ),
				),
			),
			'required'             => array( 'form_id', 'expected_hash', 'notification' ),
		),
		'output_schema'       => wpagent_wpforms_delivery_mutation_output_schema( array( 'created_notification_id' => array( 'type' => 'integer' ) ) ),
		'execute_callback'    => 'wpagent_exec_create_wpforms_notification',
		'permission_callback' => 'wpagent_perm_wpforms_delivery',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => false ) ),
	);
}

/** @param mixed $input @return array<string,mixed>|WP_Error */
function wpagent_exec_create_wpforms_notification( $input ) {
	$input       = is_array( $input ) ? $input : array();
	$payload     = is_array( $input['notification'] ?? null ) ? $input['notification'] : array();
	$has_enabled = array_key_exists( 'notifications_enabled', $input );
	$new_id      = 0;
	$result      = wpagent_wpforms_delivery_mutate(
		$input,
		static function ( array $before ) use ( $payload, $has_enabled, $input, &$new_id ) {
			$allowed = wpagent_wpforms_delivery_can_create( $before['notifications'] );
			if ( is_wp_error( $allowed ) ) {
				return $allowed;
			}
			$new_id = wpagent_wpforms_delivery_next_id( $before['notifications'] );
			if ( is_wp_error( $new_id ) ) {
				return $new_id;
			}
			$prepared = wpagent_wpforms_prepare_notification(
				array(
					'notification_name' => '',
					'email'             => '',
					'subject'           => '',
					'sender_name'       => '',
					'sender_address'    => '',
					'replyto'           => '',
					'carboncopy'        => '',
					'message'           => '',
				),
				$payload,
				$before['data']
			);
			if ( is_wp_error( $prepared ) ) {
				return $prepared;
			}
			foreach ( array( 'notification_name', 'email', 'subject', 'sender_name', 'sender_address', 'message' ) as $required ) {
				if ( '' === trim( (string) ( $prepared[ $required ] ?? '' ) ) ) {
					return new WP_Error( 'wpagent_wpforms_notification_required', __( 'Eine neue WPForms-Benachrichtigung benötigt Name, Empfänger, Betreff, Absendername, Absenderadresse und Nachricht.', 'wp-agent-companion' ), array( 'status' => 400 ) );
				}
			}
			$target = $before['data'];
			$target['settings']['notifications'][ (string) $new_id ] = $prepared;
			if ( $has_enabled ) {
				$target['settings']['notification_enable'] = rest_sanitize_boolean( $input['notifications_enabled'] ) ? '1' : '0';
			}
			return $target;
		}
	);
	if ( is_wp_error( $result ) ) {
		return $result;
	}
	$result['created_notification_id'] = $new_id;
	return $result;
}

function wpagent_ability_delete_wpforms_notification(): array {
	return array(
		'label'       => __( 'WPForms-Benachrichtigung löschen', 'wp-agent-companion' ),
		'description' => __( 'Löscht eine WPForms-E-Mail-Benachrichtigung erst nach Wiederholung ihrer exakten ID. Beim Entfernen der letzten Benachrichtigung wird der globale Versand deaktiviert. Konfliktschutz, Read-back und Rollback sichern den vollständigen Formularzustand.', 'wp-agent-companion' ),
		'category'    => 'wp-agent',
		'input_schema' => array(
			'type'                 => 'object',
			'additionalProperties' => false,
			'properties'           => array(
				'form_id'                 => array( 'type' => 'integer', 'minimum' => 1 ),
				'notification_id'         => array( 'type' => 'integer', 'minimum' => 1 ),
				'confirm_notification_id' => array( 'type' => 'integer', 'minimum' => 1 ),
				'expected_hash'           => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
			),
			'required'             => array( 'form_id', 'notification_id', 'confirm_notification_id', 'expected_hash' ),
		),
		'output_schema'       => wpagent_wpforms_delivery_mutation_output_schema( array( 'deleted_notification_id' => array( 'type' => 'integer' ) ) ),
		'execute_callback'    => 'wpagent_exec_delete_wpforms_notification',
		'permission_callback' => 'wpagent_perm_wpforms_delivery',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => true, 'idempotent' => false ) ),
	);
}

/** @param mixed $input @return array<string,mixed>|WP_Error */
function wpagent_exec_delete_wpforms_notification( $input ) {
	$input     = is_array( $input ) ? $input : array();
	$id        = absint( $input['notification_id'] ?? 0 );
	$confirmed = $input['confirm_notification_id'] ?? null;
	if ( ! is_int( $confirmed ) || $id <= 0 || $confirmed !== $id ) {
		return new WP_Error( 'wpagent_wpforms_notification_confirmation', __( 'confirm_notification_id muss die zu löschende notification_id exakt wiederholen.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$result = wpagent_wpforms_delivery_mutate(
		$input,
		static function ( array $before ) use ( $id ) {
			if ( ! isset( $before['notifications'][ $id ] ) ) {
				return new WP_Error( 'wpagent_wpforms_notification_not_found', __( 'Die WPForms-Benachrichtigung wurde nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
			}
			$target = $before['data'];
			unset( $target['settings']['notifications'][ (string) $id ], $target['settings']['notifications'][ $id ] );
			if ( count( $before['notifications'] ) <= 1 ) {
				$target['settings']['notification_enable'] = '0';
			}
			return $target;
		}
	);
	if ( is_wp_error( $result ) ) {
		return $result;
	}
	$result['deleted_notification_id'] = $id;
	return $result;
}
