import { useState } from "react";
import { useMutation, useQueryClient, type QueryClient, type UseMutationOptions } from "@tanstack/react-query";

/** Which form is open: none, the create form, or the edit form for one row. */
export type CrudFormState<Entity> = { mode: "create" } | { mode: "edit"; entity: Entity };

type MutationFactory<Variables> = (queryClient: QueryClient) => UseMutationOptions<unknown, Error, Variables>;

export interface CrudFormSpec<Entity extends { id: number }, Input> {
	create: MutationFactory<Input>;
	update: MutationFactory<{ id: number; input: Input }>;
	remove: MutationFactory<number>;
	/** The `window.confirm` text shown before a delete. */
	confirmDelete: (entity: Entity) => string;
}

/**
 * The create/edit/delete plumbing shared by the local DNS tabs (ruling 10):
 * three mutations, the open-form state, and the three handlers. The field JSX
 * and the table stay in the caller.
 */
export function useCrudForm<Entity extends { id: number }, Input>(spec: CrudFormSpec<Entity, Input>) {
	const queryClient = useQueryClient();
	const create = useMutation(spec.create(queryClient));
	const update = useMutation(spec.update(queryClient));
	const remove = useMutation(spec.remove(queryClient));
	const [form, setForm] = useState<CrudFormState<Entity> | null>(null);

	function openForm(next: CrudFormState<Entity>) {
		create.reset();
		update.reset();
		setForm(next);
	}

	function closeForm() {
		setForm(null);
	}

	function onSubmit(input: Input) {
		if (form === null) return;
		if (form.mode === "create") {
			create.mutate(input, { onSuccess: () => setForm(null) });
		} else {
			update.mutate({ id: form.entity.id, input }, { onSuccess: () => setForm(null) });
		}
	}

	function onDelete(entity: Entity) {
		if (!window.confirm(spec.confirmDelete(entity))) return;
		remove.mutate(entity.id);
	}

	return { create, update, remove, form, openForm, closeForm, onSubmit, onDelete };
}
