"use client";

import { useEffect, useMemo, useState, useTransition } from "react";
import { toast } from "sonner";
import {
	createCategoryAction,
	updateCategoryAction,
} from "@/features/categories/actions";
import { Button } from "@/shared/components/ui/button";
import {
	Dialog,
	DialogContent,
	DialogDescription,
	DialogFooter,
	DialogHeader,
	DialogTitle,
	DialogTrigger,
} from "@/shared/components/ui/dialog";
import { useControlledState } from "@/shared/hooks/use-controlled-state";
import { useFormState } from "@/shared/hooks/use-form-state";
import { CATEGORY_TYPES } from "@/shared/lib/categories/constants";
import { getDefaultIconForType } from "@/shared/lib/categories/icons";

import { CategoryFormFields } from "./category-form-fields";
import type { Category, CategoryFormValues } from "./types";

interface CategoryDialogProps {
	mode: "create" | "update";
	trigger?: React.ReactNode;
	category?: Category;
	defaultType?: CategoryFormValues["type"];
	open?: boolean;
	onOpenChange?: (open: boolean) => void;
}

const buildInitialValues = ({
	category,
	defaultType,
}: {
	category?: Category;
	defaultType?: CategoryFormValues["type"];
}): CategoryFormValues => {
	const initialType = category?.type ?? defaultType ?? CATEGORY_TYPES[0];
	const fallbackIcon = getDefaultIconForType();
	const existingIcon = category?.icon ?? "";
	const icon = existingIcon || fallbackIcon;

	return {
		name: category?.name ?? "",
		type: initialType,
		icon,
	};
};

export function CategoryDialog({
	mode,
	trigger,
	category,
	defaultType,
	open,
	onOpenChange,
}: CategoryDialogProps) {
	const [errorMessage, setErrorMessage] = useState<string | null>(null);
	const [isPending, startTransition] = useTransition();

	// Use controlled state hook for dialog open state
	const [dialogOpen, setDialogOpen] = useControlledState(
		open,
		false,
		onOpenChange,
	);

	const initialState = useMemo(
		() =>
			buildInitialValues({
				category,
				defaultType,
			}),
		[category, defaultType],
	);

	// Use form state hook for form management
	const { formState, resetForm, updateField } =
		useFormState<CategoryFormValues>(initialState);

	// Reset form when dialog opens
	useEffect(() => {
		if (dialogOpen) {
			resetForm(initialState);
			setErrorMessage(null);
		}
	}, [dialogOpen, initialState, resetForm]);

	// Clear error when dialog closes
	useEffect(() => {
		if (!dialogOpen) {
			setErrorMessage(null);
		}
	}, [dialogOpen]);

	const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
		event.preventDefault();
		setErrorMessage(null);

		if (mode === "update" && !category?.id) {
			const message = "Category inválida.";
			setErrorMessage(message);
			toast.error(message);
			return;
		}

		const payload = {
			name: formState.name.trim(),
			type: formState.type,
			icon: formState.icon.trim(),
		};

		startTransition(async () => {
			const result =
				mode === "create"
					? await createCategoryAction(payload)
					: await updateCategoryAction({
							id: category?.id ?? "",
							...payload,
						});

			if (result.success) {
				toast.success(result.message);
				setDialogOpen(false);
				resetForm(initialState);
				return;
			}

			setErrorMessage(result.error);
			toast.error(result.error);
		});
	};

	const title = mode === "create" ? "Nova categoria" : "Atualizar categoria";
	const description =
		mode === "create"
			? "Crie uma categoria para organizar seus lançamentos."
			: "Atualize os detalhes da categoria selecionada.";
	const submitLabel = mode === "create" ? "Salvar" : "Atualizar";

	return (
		<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
			{trigger ? <DialogTrigger asChild>{trigger}</DialogTrigger> : null}
			<DialogContent>
				<DialogHeader>
					<DialogTitle>{title}</DialogTitle>
					<DialogDescription>{description}</DialogDescription>
				</DialogHeader>

				<form className="flex flex-col gap-5" onSubmit={handleSubmit}>
					<CategoryFormFields values={formState} onChange={updateField} />

					{errorMessage && (
						<p className="text-sm text-destructive">{errorMessage}</p>
					)}

					<DialogFooter>
						<Button
							type="button"
							variant="outline"
							onClick={() => setDialogOpen(false)}
							disabled={isPending}
						>
							Cancelar
						</Button>
						<Button type="submit" disabled={isPending}>
							{isPending ? "Salvando..." : submitLabel}
						</Button>
					</DialogFooter>
				</form>
			</DialogContent>
		</Dialog>
	);
}
