<?php
/** Verified Fluent Forms entry status, favorite, and deletion actions. */

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

/** @return array<string,mixed> */
function wpagent_fluent_entry_write_output_schema(): array {
	return array(
		'type'                 => 'object',
		'additionalProperties' => false,
		'properties'           => array(
			'entry' => wpagent_fluent_entry_output_schema(),
			'verified' => array( 'type' => 'boolean' ),
			'changed' => array( 'type' => 'boolean' ),
		),
	);
}

/** @return array<string,mixed> */
function wpagent_fluent_entry_mutation_input_schema( array $extra, array $required ): array {
	return array(
		'type'                 => 'object',
		'additionalProperties' => false,
		'properties'           => array_merge(
			array(
				'entry_id' => array( 'type' => 'integer', 'minimum' => 1 ),
				'expected_version' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
			),
			$extra
		),
		'required'             => array_merge( array( 'entry_id' ), $required ),
	);
}

/** @return \FluentForm\App\Services\Submission\SubmissionService|WP_Error */
function wpagent_fluent_entry_service() {
	if ( ! wpagent_fluent_entries_available() ) {
		return wpagent_fluent_entries_missing_error();
	}
	try {
		return new \FluentForm\App\Services\Submission\SubmissionService();
	} catch ( Throwable $error ) {
		return new WP_Error( 'wpagent_fluent_entries_api_failed', __( 'Die Fluent-Forms-Eintrags-API konnte nicht initialisiert werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
	}
}

/** @param mixed $entry @return array|WP_Error */
function wpagent_fluent_entry_verified_result( $entry, bool $changed ) {
	$payload = wpagent_fluent_entry_payload( $entry, true );
	return is_wp_error( $payload ) ? $payload : array( 'entry' => $payload, 'verified' => true, 'changed' => $changed );
}

/** @param object $service */
function wpagent_fluent_entry_rollback_status( $service, int $form_id, int $entry_id, string $status ): bool {
	try {
		$current = \FluentForm\App\Models\Submission::find( $entry_id );
		if ( $current && $status === sanitize_key( (string) ( wpagent_fluent_entry_model_array( $current )['status'] ?? '' ) ) ) {
			return true;
		}
		$service->handleBulkActions( array( 'form_id' => $form_id, 'entries' => array( $entry_id ), 'action_type' => $status ) );
		$rollback = \FluentForm\App\Models\Submission::find( $entry_id );
		return $rollback && $status === sanitize_key( (string) ( wpagent_fluent_entry_model_array( $rollback )['status'] ?? '' ) );
	} catch ( Throwable $error ) {
		return false;
	}
}

/** @param object $service */
function wpagent_fluent_entry_rollback_favorite( $service, int $form_id, int $entry_id, bool $favorite ): bool {
	$action = $favorite ? 'other.make_favorite' : 'other.unmark_favorite';
	try {
		$current = \FluentForm\App\Models\Submission::find( $entry_id );
		if ( $current && $favorite === ! empty( wpagent_fluent_entry_model_array( $current )['is_favourite'] ) ) {
			return true;
		}
		$service->handleBulkActions( array( 'form_id' => $form_id, 'entries' => array( $entry_id ), 'action_type' => $action ) );
		$rollback = \FluentForm\App\Models\Submission::find( $entry_id );
		return $rollback && $favorite === ! empty( wpagent_fluent_entry_model_array( $rollback )['is_favourite'] );
	} catch ( Throwable $error ) {
		return false;
	}
}

function wpagent_ability_set_fluent_entry_status(): array {
	return array(
		'label'               => __( 'Fluent-Forms-Eintragsstatus setzen', 'wp-agent-companion' ),
		'description'         => __( 'Setzt einen für das Formular verfügbaren Eintragsstatus, prüft Versionskonflikte und rollt eine nicht bestätigte Änderung zurück.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => wpagent_fluent_entry_mutation_input_schema( array( 'status' => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 64 ) ), array( 'status' ) ),
		'output_schema'       => wpagent_fluent_entry_write_output_schema(),
		'execute_callback'    => 'wpagent_exec_set_fluent_entry_status',
		'permission_callback' => 'wpagent_perm_fluent_entries_manage',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => true, 'idempotent' => true ) ),
	);
}

/** @param mixed $input @return array|WP_Error */
function wpagent_exec_set_fluent_entry_status( $input ) {
	$input = is_array( $input ) ? $input : array();
	$entry = wpagent_fluent_get_authorized_entry( $input, 'fluentform_manage_entries' );
	if ( is_wp_error( $entry ) ) {
		return $entry;
	}
	$data     = wpagent_fluent_entry_model_array( $entry );
	$form_id  = absint( $data['form_id'] ?? 0 );
	$status   = sanitize_key( (string) ( $input['status'] ?? '' ) );
	$statuses = wpagent_fluent_entry_statuses( $form_id );
	if ( is_wp_error( $statuses ) ) {
		return $statuses;
	}
	if ( ! isset( $statuses[ $status ] ) ) {
		return new WP_Error( 'wpagent_fluent_entry_bad_status', __( 'Der angeforderte Fluent-Forms-Eintragsstatus ist für dieses Formular nicht verfügbar.', 'wp-agent-companion' ), array( 'status' => 400, 'available_statuses' => array_keys( $statuses ) ) );
	}
	if ( ! wpagent_fluent_entry_expected_version_matches( $input, $entry ) ) {
		return new WP_Error( 'wpagent_fluent_entry_conflict', __( 'Der Fluent-Forms-Eintrag wurde seit dem gelesenen Stand verändert.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$lock = wpagent_companion_acquire_connection_lock();
	if ( is_wp_error( $lock ) ) {
		return $lock;
	}
	$service            = null;
	$old                = '';
	$mutation_attempted = false;
	$entry_id           = absint( $data['id'] ?? 0 );
	try {
		$fresh = \FluentForm\App\Models\Submission::find( $entry_id );
		if ( ! $fresh ) {
			return new WP_Error( 'wpagent_fluent_entry_not_found', __( 'Fluent-Forms-Eintrag nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
		}
		if ( ! wpagent_fluent_entry_expected_version_matches( $input, $fresh ) ) {
			return new WP_Error( 'wpagent_fluent_entry_conflict', __( 'Der Fluent-Forms-Eintrag wurde seit dem gelesenen Stand verändert.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
		$old = sanitize_key( (string) ( wpagent_fluent_entry_model_array( $fresh )['status'] ?? '' ) );
		if ( $old === $status ) {
			return wpagent_fluent_entry_verified_result( $fresh, false );
		}
		if ( ! isset( $statuses[ $old ] ) ) {
			return new WP_Error( 'wpagent_fluent_entry_bad_current_status', __( 'Der vorhandene Eintragsstatus kann bei einem Fehler nicht sicher wiederhergestellt werden.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
		$service = wpagent_fluent_entry_service();
		if ( is_wp_error( $service ) ) {
			return $service;
		}
		$mutation_attempted = true;
		$service->handleBulkActions( array( 'form_id' => $form_id, 'entries' => array( $entry_id ), 'action_type' => $status ) );
		$readback = \FluentForm\App\Models\Submission::find( $entry_id );
		if ( ! $readback || $status !== sanitize_key( (string) ( wpagent_fluent_entry_model_array( $readback )['status'] ?? '' ) ) ) {
			$rolled_back = wpagent_fluent_entry_rollback_status( $service, $form_id, $entry_id, $old );
			return new WP_Error( 'wpagent_fluent_entry_status_unverified', __( 'Die Fluent-Forms-Statusänderung konnte nicht verifiziert werden und wurde zurückgerollt.', 'wp-agent-companion' ), array( 'status' => 500, 'rollback_succeeded' => $rolled_back ) );
		}
		return wpagent_fluent_entry_verified_result( $readback, true );
	} catch ( Throwable $error ) {
		$rolled_back = $mutation_attempted && is_object( $service ) && '' !== $old
			? wpagent_fluent_entry_rollback_status( $service, $form_id, $entry_id, $old )
			: false;
		return new WP_Error( 'wpagent_fluent_entry_status_failed', __( 'Der Fluent-Forms-Eintragsstatus konnte nicht sicher geändert werden.', 'wp-agent-companion' ), array( 'status' => 500, 'rollback_succeeded' => $rolled_back ) );
	} finally {
		wpagent_companion_release_connection_lock( $lock );
	}
}

function wpagent_ability_set_fluent_entry_favorite(): array {
	return array(
		'label'               => __( 'Fluent-Forms-Eintrag markieren', 'wp-agent-companion' ),
		'description'         => __( 'Setzt die Favoritenmarkierung eines Fluent-Forms-Eintrags idempotent und prüft das Ergebnis per Read-back.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => wpagent_fluent_entry_mutation_input_schema( array( 'favorite' => array( 'type' => 'boolean' ) ), array( 'favorite' ) ),
		'output_schema'       => wpagent_fluent_entry_write_output_schema(),
		'execute_callback'    => 'wpagent_exec_set_fluent_entry_favorite',
		'permission_callback' => 'wpagent_perm_fluent_entries_manage',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => true ) ),
	);
}

/** @param mixed $input @return array|WP_Error */
function wpagent_exec_set_fluent_entry_favorite( $input ) {
	$input = is_array( $input ) ? $input : array();
	$entry = wpagent_fluent_get_authorized_entry( $input, 'fluentform_manage_entries' );
	if ( is_wp_error( $entry ) ) {
		return $entry;
	}
	if ( ! wpagent_fluent_entry_expected_version_matches( $input, $entry ) ) {
		return new WP_Error( 'wpagent_fluent_entry_conflict', __( 'Der Fluent-Forms-Eintrag wurde seit dem gelesenen Stand verändert.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$data    = wpagent_fluent_entry_model_array( $entry );
	$desired = true === ( $input['favorite'] ?? false );
	$lock    = wpagent_companion_acquire_connection_lock();
	if ( is_wp_error( $lock ) ) {
		return $lock;
	}
	$service            = null;
	$current            = false;
	$mutation_attempted = false;
	$form_id            = absint( $data['form_id'] ?? 0 );
	$entry_id           = absint( $data['id'] ?? 0 );
	try {
		$fresh = \FluentForm\App\Models\Submission::find( $entry_id );
		if ( ! $fresh ) {
			return new WP_Error( 'wpagent_fluent_entry_not_found', __( 'Fluent-Forms-Eintrag nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
		}
		if ( ! wpagent_fluent_entry_expected_version_matches( $input, $fresh ) ) {
			return new WP_Error( 'wpagent_fluent_entry_conflict', __( 'Der Fluent-Forms-Eintrag wurde seit dem gelesenen Stand verändert.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
		$current = ! empty( wpagent_fluent_entry_model_array( $fresh )['is_favourite'] );
		if ( $current === $desired ) {
			return wpagent_fluent_entry_verified_result( $fresh, false );
		}
		$service = wpagent_fluent_entry_service();
		if ( is_wp_error( $service ) ) {
			return $service;
		}
		$action = $desired ? 'other.make_favorite' : 'other.unmark_favorite';
		$mutation_attempted = true;
		$service->handleBulkActions( array( 'form_id' => $form_id, 'entries' => array( $entry_id ), 'action_type' => $action ) );
		$readback = \FluentForm\App\Models\Submission::find( $entry_id );
		if ( ! $readback || $desired !== ! empty( wpagent_fluent_entry_model_array( $readback )['is_favourite'] ) ) {
			$rolled_back = wpagent_fluent_entry_rollback_favorite( $service, $form_id, $entry_id, $current );
			return new WP_Error( 'wpagent_fluent_entry_favorite_unverified', __( 'Die Fluent-Forms-Markierung konnte nicht verifiziert werden und wurde zurückgerollt.', 'wp-agent-companion' ), array( 'status' => 500, 'rollback_succeeded' => $rolled_back ) );
		}
		return wpagent_fluent_entry_verified_result( $readback, true );
	} catch ( Throwable $error ) {
		$rolled_back = $mutation_attempted && is_object( $service )
			? wpagent_fluent_entry_rollback_favorite( $service, $form_id, $entry_id, $current )
			: false;
		return new WP_Error( 'wpagent_fluent_entry_favorite_failed', __( 'Die Fluent-Forms-Markierung konnte nicht sicher geändert werden.', 'wp-agent-companion' ), array( 'status' => 500, 'rollback_succeeded' => $rolled_back ) );
	} finally {
		wpagent_companion_release_connection_lock( $lock );
	}
}

function wpagent_ability_delete_fluent_entry(): array {
	return array(
		'label'               => __( 'Fluent-Forms-Eintrag dauerhaft löschen', 'wp-agent-companion' ),
		'description'         => __( 'Löscht einen Fluent-Forms-Eintrag und seine nativen Begleitdaten dauerhaft. confirm=true ist zwingend erforderlich.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => wpagent_fluent_entry_mutation_input_schema( array( 'confirm' => array( 'type' => 'boolean' ) ), array( 'confirm' ) ),
		'output_schema'       => array( 'type' => 'object', 'additionalProperties' => false, 'properties' => array( 'entry_id' => array( 'type' => 'integer' ), 'deleted' => array( 'type' => 'boolean' ) ) ),
		'execute_callback'    => 'wpagent_exec_delete_fluent_entry',
		'permission_callback' => 'wpagent_perm_fluent_entries_manage',
		'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_fluent_entry( $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 ) );
	}
	$entry = wpagent_fluent_get_authorized_entry( $input, 'fluentform_manage_entries' );
	if ( is_wp_error( $entry ) ) {
		return $entry;
	}
	if ( ! wpagent_fluent_entry_expected_version_matches( $input, $entry ) ) {
		return new WP_Error( 'wpagent_fluent_entry_conflict', __( 'Der Fluent-Forms-Eintrag wurde seit dem gelesenen Stand verändert.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$data = wpagent_fluent_entry_model_array( $entry );
	$lock = wpagent_companion_acquire_connection_lock();
	if ( is_wp_error( $lock ) ) {
		return $lock;
	}
	try {
		$fresh = \FluentForm\App\Models\Submission::find( absint( $data['id'] ?? 0 ) );
		if ( ! $fresh ) {
			return new WP_Error( 'wpagent_fluent_entry_not_found', __( 'Fluent-Forms-Eintrag nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
		}
		if ( ! wpagent_fluent_entry_expected_version_matches( $input, $fresh ) ) {
			return new WP_Error( 'wpagent_fluent_entry_conflict', __( 'Der Fluent-Forms-Eintrag wurde seit dem gelesenen Stand verändert.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
		$service = wpagent_fluent_entry_service();
		if ( is_wp_error( $service ) ) {
			return $service;
		}
		$entry_id = absint( $data['id'] ?? 0 );
		$service->handleBulkActions( array( 'form_id' => absint( $data['form_id'] ?? 0 ), 'entries' => array( $entry_id ), 'action_type' => 'other.delete_permanently' ) );
		if ( \FluentForm\App\Models\Submission::find( $entry_id ) ) {
			return new WP_Error( 'wpagent_fluent_entry_delete_failed', __( 'Der Fluent-Forms-Eintrag konnte nicht gelöscht werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
		}
		return array( 'entry_id' => $entry_id, 'deleted' => true );
	} catch ( Throwable $error ) {
		return new WP_Error( 'wpagent_fluent_entry_delete_failed', __( 'Der Fluent-Forms-Eintrag konnte nicht sicher gelöscht werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
	} finally {
		wpagent_companion_release_connection_lock( $lock );
	}
}
