import {
    AlertDialog,
    AlertDialogCancel,
    AlertDialogContent,
    AlertDialogDescription,
    AlertDialogFooter,
    AlertDialogHeader,
    AlertDialogTitle,
} from "@/shadcn/components/ui/alert-dialog";
import { ScrollArea } from "@/shadcn/components/ui/scroll-area";
import { Button } from "@/shadcn/components/ui/button";
import { TextInput } from "@mantine/core";
import { Label } from "@/shadcn/components/ui/label";
import { useForm } from "@mantine/form";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { getRouteApi } from "@tanstack/react-router";
import { createAspect, updateAspect, getAspectByIdQueryOptions } from "../queries/aspectQueries";
import { useEffect, useState } from "react";
import { notifications } from "@mantine/notifications";
import FormResponseError from "@/errors/FormResponseError";
import { createId } from "@paralleldrive/cuid2";

// Initialize route API
const routeApi = getRouteApi("/_dashboardLayout/aspect/");

export default function AspectFormModal() {
    const queryClient = useQueryClient();
    const navigate = routeApi.useNavigate();
    const searchParams = routeApi.useSearch();
    const dataId = searchParams.detail || searchParams.edit;
    const isDialogOpen = Boolean(dataId || searchParams.create);
    const formType = searchParams.detail ? "detail" : searchParams.edit ? "ubah" : "tambah";

    // Fetch aspect data if ubahing or viewing details
    const aspectQuery = useQuery(getAspectByIdQueryOptions(dataId));

    const modalTitle = `${formType.charAt(0).toUpperCase() + formType.slice(1)} Aspek`;

    const form = useForm({
        initialValues: {
            id: "",
            name: "",
            subAspects: [{ id: "", name: "", questionCount: 0 }] as { id: string; name: string; questionCount: number }[],
        },
    });

    useEffect(() => {
        const data = aspectQuery.data;

        if (!data) {
            form.reset();
            return;
        }

        form.setValues({
            id: data.id,
            name: data.name,
            subAspects: data.subAspects?.map(subAspect => ({
                id: subAspect.id || "",
                name: subAspect.name,
                questionCount: subAspect.questionCount || 0,
            })) || [],
        });

        form.setErrors({});
    }, [aspectQuery.data]);

    const mutation = useMutation({
        mutationKey: ["aspectMutation"],
        mutationFn: async (
            options:
                | { action: "ubah"; data: Parameters<typeof updateAspect>[0] }
                | { action: "tambah"; data: Parameters<typeof createAspect>[0] }
        ) => {
            return options.action === "ubah"
                ? await updateAspect(options.data)
                : await createAspect(options.data);
        },
        onError: (error: unknown) => {
            if (error instanceof FormResponseError) {
                form.setErrors(error.formErrors);
                return;
            }

            if (error instanceof Error) {
                notifications.show({
                    message: error.message,
                    color: "red",
                });
            }
        },
    });

    type CreateAspectPayload = {
        name: string;
        subAspects?: string;
    };

    type EditAspectPayload = {
        id: string;
        name: string;
        subAspects?: string;
    };

    const [isSubmitting, setIsSubmitting] = useState(false);

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

        const values = form.values;

        try {
            // Start submit process
            setIsSubmitting(true);

            // Name field validation
            if (values.name.trim() === "") {
                form.setErrors({ name: "Nama aspek harus diisi" });
                setIsSubmitting(false);
                return;
            }

            let payload: CreateAspectPayload | EditAspectPayload;

            if (formType === "tambah") {
                payload = {
                    name: values.name,
                    subAspects: values.subAspects.length > 0
                        ? JSON.stringify(
                            values.subAspects
                                .filter(subAspect => subAspect.name.trim() !== "")
                                .map(subAspect => subAspect.name)
                        )
                        : "",
                };
                await createAspect(payload);
            } else if (formType === "ubah") {
                payload = {
                    id: values.id,
                    name: values.name,
                    subAspects: values.subAspects.length > 0
                        ? JSON.stringify(
                            values.subAspects
                                .filter(subAspect => subAspect.name.trim() !== "")
                                .map(subAspect => ({
                                    id: subAspect.id || "",
                                    name: subAspect.name,
                                    questionCount: subAspect.questionCount || 0,
                                }))
                        )
                        : "",
                };
                await updateAspect(payload);
            }

            queryClient.invalidateQueries({ queryKey: ["management-aspect"] });

            notifications.show({
                message: `Aspek ${formType === "tambah" ? "berhasil dibuat" : "berhasil diubah"}`,
            });

            navigate({ search: {} });
        } catch (error) {
            console.error("Error during submit:", error);

            if (error instanceof Error && error.message === "Aspect name already exists") {
                notifications.show({
                    message: "Nama aspek sudah ada. Silakan gunakan nama lain.",
                    color: "red",
                });
            } else {
                notifications.show({
                    message: "Nama Sub Aspek sudah ada. Silakan gunakan nama lain.",
                    color: "red",
                });
            }
        } finally {
            setIsSubmitting(false);
        }
    };

    return (
        <AlertDialog open={isDialogOpen} onOpenChange={isOpen => !isOpen && navigate({ search: {} })}>
            <AlertDialogContent className="max-h-[80vh] overflow-hidden">
                <AlertDialogHeader>
                    <AlertDialogTitle>{modalTitle}</AlertDialogTitle>
                    <AlertDialogDescription>
                        {formType === "detail" ? "Detail dari aspek." : "Silakan isi data aspek di bawah ini."}
                    </AlertDialogDescription>
                </AlertDialogHeader>

                <form onSubmit={handleSubmit}>
                    <ScrollArea className="h-[300px] p-4">
                        <div className="grid gap-4">
                            <div className="mb-4">
                                <Label htmlFor="name" className="block text-left mb-1">Nama Aspek</Label>
                                <TextInput
                                    id="name"
                                    type="text"
                                    {...form.getInputProps("name")}
                                    disabled={formType === "detail" || isSubmitting}
                                    error={form.errors.name}
                                />
                            </div>

                            {form.values.subAspects.map((subAspect, index) => (
                                <div className="flex justify-between items-center mb-4" key={subAspect.id}>
                                    <div className="flex-grow">
                                        <Label htmlFor={`subAspect-${index}`} className="block text-left mb-1">
                                            Sub Aspek {index + 1}
                                        </Label>
                                        <TextInput
                                            id={`subAspect-${index}`}
                                            value={subAspect.name}
                                            onChange={(event) => {
                                                if (formType !== "detail" && !mutation.isPending) {
                                                    const newSubAspects = [...form.values.subAspects];
                                                    newSubAspects[index] = { ...newSubAspects[index], name: event.target.value };
                                                    form.setValues({ subAspects: newSubAspects });
                                                }
                                            }}
                                            disabled={formType === "detail" || isSubmitting}
                                        />
                                    </div>
                                    {formType === "detail" && (
                                        <div className="ml-4 flex-shrink-0">
                                            <Label className="block text-left mb-1">Jumlah Soal</Label>
                                            <TextInput
                                                value={subAspect.questionCount}
                                                readOnly
                                                className="w-full"
                                                disabled
                                            />
                                        </div>
                                    )}
                                    {formType !== "detail" && (
                                        <Button
                                            className="ml-4 mt-4"
                                            variant="outline"
                                            onClick={(e) => {
                                                e.preventDefault();
                                                const newSubAspects = form.values.subAspects.filter((_, i) => i !== index);
                                                form.setValues({ subAspects: newSubAspects });
                                            }}
                                            disabled={isSubmitting}
                                        >
                                            Hapus
                                        </Button>
                                    )}
                                </div>
                            ))}

                            {formType !== "detail" && (
                                <Button className="mb-4"
                                    variant="outline"
                                    onClick={(e) => {
                                        e.preventDefault();
                                        const newSubAspects = [
                                            ...form.values.subAspects,
                                            { id: createId(), name: "", questionCount: 0 }
                                        ];
                                        form.setValues({ subAspects: newSubAspects });
                                    }}
                                >
                                    Tambah Sub Aspek
                                </Button>
                            )}
                        </div>
                    </ScrollArea>
                    
                    <AlertDialogFooter>
                        <AlertDialogCancel disabled={isSubmitting}>Tutup</AlertDialogCancel>
                        {formType !== "detail" && (
                            <Button type="submit" disabled={isSubmitting}>
                                {isSubmitting ? "Menyimpan..." : modalTitle}
                            </Button>
                        )}
                    </AlertDialogFooter>
                </form>
            </AlertDialogContent>
        </AlertDialog>
    );
}