import {
AlertDialog,
AlertDialogContent,
AlertDialogDescription,
AlertDialogHeader,
AlertDialogTitle,
} from "@/Components/ui/alert-dialog";
import { Button } from "@/Components/ui/button";
import { Input } from "@/Components/ui/input";
import { Label } from "@/Components/ui/label";
import { useForm, usePage } from "@inertiajs/react";
import { FormEventHandler, useEffect, useId } from "react";
import { useEstudianteStore } from "@/Store/useEstudianteStore";
import { toast } from "sonner";
import { Page } from "@inertiajs/core";

import { validateInputNumber, validateInputText } from "@/Utils/validations";
import { Curso } from "@/types/curso";
import { useCursosStore } from "@/Store/useCursoStore";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/Components/ui/table";
import { Estudiante } from "@/types/estudiante";
import { PageProps } from "@/types/param";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/Components/ui/select";
import { Grado } from "@/types/grado";

type Field =
| "nombres"
| "id"
| "apellido_paterno"
| "apellido_materno"
| "dni"
| "celular"
| "celular_apoderado"
| "password"
| "cursos";

export function ModalCreateOrEdit() {
const idNombres = useId();
const idApellidoPaterno = useId();
const idApellidoMaterno = useId();
const idCelular = useId();
const idCelularApoderado = useId();
const idDNI = useId();
const idPassword = useId();

const {
estudiante,
openModalCreateOrEditEstudiante,
setOpenModalCreateOrEditEstudiante,
} = useEstudianteStore();

const {
cursos,
addCurso,
removeCurso,
addMultipleCursos,
removeAllCursos,
} = useCursosStore();

const {grados, cursos: PageCursos } = usePage<PageProps<Estudiante>>().props;

    useEffect(() => {
    if (estudiante?.cursos) {
    addMultipleCursos(estudiante.cursos);
    }

    }, [estudiante?.cursos]);

    const { data, setData, post, put, reset, clearErrors, processing, errors } =
    useForm<{ id: number | null; dni: string; nombres: string; apellido_paterno: string; apellido_materno: string;
        celular: string; celular_apoderado: string; password: string; cursos: Curso[]; grado: Grado[] | undefined; }>({
        id: estudiante?.id ?? null,
        dni: estudiante?.dni || "",
        nombres: estudiante?.nombres || "",
        apellido_paterno: estudiante?.apellido_paterno || "",
        apellido_materno: estudiante?.apellido_materno || "",
        celular: estudiante?.celular || "",
        celular_apoderado: estudiante?.celular_apoderado || "",
        password: estudiante?.password || "",
        cursos: cursos,
        grado: estudiante?.grado ? [estudiante?.grado[0]] : undefined,
        });

        const submit: FormEventHandler = (e) => {
        e.preventDefault();

        data.cursos = cursos;

        interface Options {
        preserveScroll: boolean;
        onSuccess: (
        response: Page<{ status?: { success?: string } }>
            ) => void;
            onError: (errors: Record<string, string> | undefined) => void;
                }

                const options: Options = {
                preserveScroll: true,
                onSuccess: (response: Page<{ status?: { success?: string } }>) => {
                    reset();
                    const successMessage =
                    response.props.status?.success ||
                    "Operación realizada con éxito.";
                    toast.success(successMessage);
                    setOpenModalCreateOrEditEstudiante(false);
                    },

                    onError: (errors: Record<string, string> | undefined) => {

                        if (errors) {
                        console.error("errors ", errors);
                        Object.entries(errors).forEach(([field, message]) => {
                        toast.error(`${field}: ${message}`);
                        });
                        } else {
                        toast.error("Error en el formulario.");
                        }
                        },
                        };

                        if (data.id) {
                        put(route("estudiantes.update", { estudiante: data.id }), options);
                        } else {
                        post(route("estudiantes.store"), options);
                        }

                        clearErrors();
                        };

                        const handleChange = (
                        e: React.ChangeEvent<HTMLInputElement>,
                            field: Field
                            ) => {
                            const value = e.target.value;

                            if (
                            field === "nombres" ||
                            field === "apellido_paterno" ||
                            field === "apellido_materno"
                            ) {
                            if (validateInputText(value)) {
                            setData((prevData) => ({
                            ...prevData,
                            [field]: value,
                            }));
                            }
                            } else if (
                            field === "dni" ||
                            field === "celular" ||
                            field === "celular_apoderado"
                            ) {
                            if (validateInputNumber(value)) {
                            setData((prevData) => ({
                            ...prevData,
                            [field]: value,
                            }));
                            }
                            } else {
                            setData((prevData) => ({
                            ...prevData,
                            [field]: value,
                            }));
                            }
                            };

                            return (
                            <AlertDialog open={openModalCreateOrEditEstudiante} onOpenChange={()=>
                                setOpenModalCreateOrEditEstudiante(false)}
                                >
                                <AlertDialogContent>
                                    <AlertDialogHeader>
                                        <AlertDialogTitle>
                                            {estudiante?.id ? "Editar" : "Crear"} Estudiante
                                        </AlertDialogTitle>
                                        <AlertDialogDescription>
                                            {estudiante?.id
                                            ? "Modifica los datos del estudiante y guarda los cambios."
                                            : "Ingresa los datos para registrar un nuevo "}
                                        </AlertDialogDescription>
                                    </AlertDialogHeader>
                                    <form onSubmit={submit} className="overflow-y-auto max-h-[80vh]">
                                        <Label htmlFor={idDNI}>DNI</Label>
                                        <Input id={idDNI} type="text" value={data.dni} className="mt-1 block w-full"
                                            placeholder="00000000" onChange={(e)=> handleChange(e, "dni")}
                                        required
                                        />
                                        {errors.dni && (
                                        <p>
                                            <Label className="text-destructive" htmlFor={idDNI}>
                                                {errors.dni}
                                            </Label>
                                        </p>
                                        )}

                                        <Label htmlFor={idNombres}>Nombres</Label>
                                        <Input id={idNombres} type="text" value={data.nombres}
                                            className="mt-1 block w-full" placeholder="Nombre del estudiante"
                                            onChange={(e)=> handleChange(e, "nombres")}
                                        required
                                        />
                                        {errors.nombres && (
                                        <p>
                                            <Label className="text-destructive" htmlFor={idNombres}>
                                                {errors.nombres}
                                            </Label>
                                        </p>
                                        )}
                                        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                                            <div className="col-span-1">
                                                <Label htmlFor={idApellidoPaterno}>
                                                    Apellido Paterno
                                                </Label>
                                                <Input id={idApellidoPaterno} type="text"
                                                    value={data.apellido_paterno} className="mt-1 block w-full"
                                                    placeholder="Apellido Paterno..." onChange={(e)=>
                                                handleChange(e, "apellido_paterno")
                                                }
                                                required
                                                />{" "}
                                                {errors.apellido_paterno && (
                                                <p>
                                                    <Label className="text-destructive" htmlFor={idApellidoPaterno}>
                                                        {errors.apellido_paterno}
                                                    </Label>
                                                </p>
                                                )}
                                            </div>
                                            <div>
                                                <Label htmlFor={idApellidoMaterno}>
                                                    Apellido Materno
                                                </Label>
                                                <Input id={idApellidoMaterno} type="text"
                                                    value={data.apellido_materno} className="mt-1 block w-full"
                                                    placeholder="Apellido Materno..." onChange={(e)=>
                                                handleChange(e, "apellido_materno")
                                                }
                                                required
                                                />
                                                {errors.apellido_materno && (
                                                <p>
                                                    <Label className="text-destructive" htmlFor={idApellidoMaterno}>
                                                        {errors.apellido_materno}
                                                    </Label>
                                                </p>
                                                )}
                                            </div>
                                        </div>

                                        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                                            <div className="col-span-1">
                                                <Label htmlFor={idCelular}>
                                                    Celular Estudiante
                                                </Label>
                                                <Input id={idCelular} type="text" value={data.celular}
                                                    className="mt-1 block w-full" placeholder="987654321"
                                                    onChange={(e)=> handleChange(e, "celular")}
                                                />
                                                {errors.celular && (
                                                <p>
                                                    <Label className="text-destructive" htmlFor={idCelular}>
                                                        {errors.celular}
                                                    </Label>
                                                </p>
                                                )}
                                            </div>
                                            <div>
                                                <Label htmlFor={idCelularApoderado}>
                                                    Celular Apoderado
                                                </Label>
                                                <Input id={idCelularApoderado} type="text"
                                                    value={data.celular_apoderado} className="mt-1 block w-full"
                                                    placeholder="987654321" onChange={(e)=>
                                                handleChange(e, "celular_apoderado")
                                                }
                                                />

                                                {errors.celular_apoderado && (
                                                <p>
                                                    <Label className="text-destructive" htmlFor={idCelularApoderado}>
                                                        {errors.celular_apoderado}
                                                    </Label>
                                                </p>
                                                )}
                                            </div>
                                        </div>
                                        <div>
                                            <Label>
                                                Grado Escolar
                                            </Label>
                                            <Select value={data.grado?.[0]?.id?.toString() ?? "" }
                                                onValueChange={(value)=> {
                                                const gradoSeleccionado = grados.find((g: Grado) => g.id.toString() ===
                                                value);
                                                if (gradoSeleccionado) {
                                                setData("grado", [gradoSeleccionado]);
                                                }
                                                }}
                                                >
                                                <SelectTrigger>
                                                    <SelectValue placeholder="Selecciona un grado" />
                                                </SelectTrigger>
                                                <SelectContent>
                                                    {grados.length > 0 ? (
                                                    grados.map((grado: Grado) => (
                                                    <SelectItem key={grado.id} value={grado.id.toString()}>
                                                        {grado.nombre}
                                                    </SelectItem>
                                                    ))
                                                    ) : (
                                                    <SelectItem disabled value="0">
                                                        No hay grados disponibles
                                                    </SelectItem>
                                                    )}
                                                </SelectContent>
                                            </Select>

                                            {errors.grado && (
                                            <p>
                                                <Label className="text-destructive">
                                                    {errors.grado}
                                                </Label>
                                            </p>
                                            )}
                                        </div>

                                        {estudiante?.id && (
                                        <>
                                            <Label htmlFor={idPassword}>Contraseña</Label>
                                            <Input id={idPassword} type="text" value={data.password}
                                                className="mt-1 block w-full" placeholder="Password ..." onChange={(e)=>
                                            handleChange(e, "password")}
                                            />
                                            {errors.password && (
                                            <p>
                                                <Label className="text-destructive" htmlFor={idPassword}>
                                                    {errors.password}
                                                </Label>
                                            </p>
                                            )}
                                        </>
                                        )}

                                        <Table className="mt-4">
                                            <TableHeader>
                                                <TableRow>
                                                    <TableHead className="w-20">
                                                        Seleccionar
                                                    </TableHead>
                                                    <TableHead>Nombre</TableHead>
                                                </TableRow>
                                            </TableHeader>
                                            <TableBody>
                                                {PageCursos.length > 0 ? (
                                                PageCursos.map((curso: Curso) => (
                                                <TableRow key={curso.id}>
                                                    <TableCell className="flex justify-center">
                                                        <Input id={`check${curso.id}`} className="w-8" type="checkbox"
                                                            onChange={()=> {
                                                        if (
                                                        cursos.some(
                                                        (
                                                        cursoFilter: Curso
                                                        ) =>
                                                        curso.id ===
                                                        cursoFilter.id
                                                        )
                                                        ) {
                                                        removeCurso(curso.id);
                                                        } else {
                                                        addCurso(curso);
                                                        }
                                                        }}
                                                        checked={
                                                        cursos.some(
                                                        (cursoFilter: Curso) =>
                                                        curso.id ===
                                                        cursoFilter.id
                                                        ) || false
                                                        }
                                                        />
                                                    </TableCell>
                                                    <TableCell>
                                                        <Label htmlFor={`check${curso.id}`}>
                                                            {curso.nombre}
                                                        </Label>
                                                    </TableCell>
                                                </TableRow>
                                                ))
                                                ) : (
                                                <TableRow>
                                                    <TableCell colSpan={2} className="text-center">
                                                        No se encontraron cursos.
                                                    </TableCell>
                                                </TableRow>
                                                )}
                                            </TableBody>
                                        </Table>

                                        <footer className="flex justify-around gap-4 mt-4">
                                            <Button type="button" onClick={()=> {
                                                removeAllCursos();
                                                setOpenModalCreateOrEditEstudiante(false);
                                                }}
                                                variant="secondary"
                                                >
                                                Cancelar
                                            </Button>
                                            <Button type="submit" disabled={processing}>
                                                Guardar
                                            </Button>
                                        </footer>
                                    </form>
                                </AlertDialogContent>
                            </AlertDialog>
                            );
                            }
