import { Head, router } from '@inertiajs/react';
import type { ColumnDef } from '@tanstack/react-table';
import { format } from 'date-fns';
import { Trash2, UserPlus } from 'lucide-react';
import { useState } from 'react';
import { DataTable } from '@/components/data-table';
import { DeleteConfirmDialog } from '@/components/delete-confirm-dialog';
import { FormDialog } from '@/components/form-dialog';
import InputError from '@/components/input-error';
import { PageHeader } from '@/components/page-header';
import { RowActions } from '@/components/row-actions';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Checkbox } from '@/components/ui/checkbox';
import { Label } from '@/components/ui/label';
import { index as courseClassIndex } from '@/routes/admin/manage/course-classes';
import {
    destroy,
    store,
} from '@/routes/admin/manage/course-classes/enrollments';
import type {
    ClassEnrollment,
    EnrollmentStudent,
} from '@/types/class-enrollment';
import type { CourseClass } from '@/types/course-class';
import { ClassMethodLabels } from '@/types/course-class';

type Props = {
    courseClass: CourseClass;
    enrollments: ClassEnrollment[];
    availableStudents: EnrollmentStudent[];
};

export default function ClassEnrollmentIndex({
    courseClass,
    enrollments,
    availableStudents,
}: Props) {
    const [createOpen, setCreateOpen] = useState(false);
    const [deleting, setDeleting] = useState<ClassEnrollment | null>(null);

    function handleDelete() {
        if (!deleting) {
            return;
        }

        router.delete(destroy([courseClass.id, deleting.id]), {
            onSuccess: () => setDeleting(null),
        });
    }

    const columns: ColumnDef<ClassEnrollment>[] = [
        {
            accessorKey: 'student.student_number',
            header: () => <span>NIM</span>,
            cell: ({ row }) => row.original.student?.student_number ?? '-',
        },
        {
            accessorKey: 'student.user.profile.full_name',
            header: () => <span>Nama Mahasiswa</span>,
            cell: ({ row }) =>
                row.original.student?.user?.profile?.full_name ?? '-',
        },
        {
            accessorKey: 'student.department.name',
            header: () => <span>Jurusan</span>,
            cell: ({ row }) => row.original.student?.department?.name ?? '-',
        },
        {
            accessorKey: 'enrolled_at',
            header: () => <span>Tanggal Daftar</span>,
            cell: ({ row }) => {
                const enrolledAt = row.getValue('enrolled_at') as string | null;

                return enrolledAt
                    ? format(new Date(enrolledAt), 'd MMM yyyy')
                    : '-';
            },
        },
        {
            id: 'actions',
            header: () => <span className="block text-center">Aksi</span>,
            meta: {
                className: 'w-[80px] text-center',
                headerClassName: 'w-[80px] text-center',
            },
            cell: ({ row }) => (
                <RowActions
                    actions={[
                        {
                            label: 'Keluarkan',
                            icon: (
                                <Trash2 className="h-4 w-4 text-destructive" />
                            ),
                            onClick: () => setDeleting(row.original),
                        },
                    ]}
                />
            ),
        },
    ];

    return (
        <>
            <Head title="Peserta Kelas" />

            <div className="flex h-full flex-1 flex-col gap-6 overflow-x-auto p-4 md:p-6">
                <PageHeader
                    title="Peserta Kelas"
                    actions={
                        <Button variant="outline" asChild>
                            <a href={courseClassIndex.url()}>Kembali</a>
                        </Button>
                    }
                />

                <Card>
                    <CardHeader>
                        <CardTitle>
                            {courseClass.class_name ?? courseClass.course?.name}
                        </CardTitle>
                    </CardHeader>
                    <CardContent className="grid gap-1 text-sm text-muted-foreground">
                        <p>
                            Mata Kuliah: {courseClass.course?.code} -{' '}
                            {courseClass.course?.name}
                        </p>
                        <p>
                            Dosen Pengampu:{' '}
                            {courseClass.lecturer?.user?.profile?.full_name ??
                                '-'}
                        </p>
                        <p>Periode: {courseClass.academic_term?.name}</p>
                        <p>
                            Metode:{' '}
                            {courseClass.method
                                ? ClassMethodLabels[courseClass.method]
                                : '-'}
                        </p>
                        <p>Jumlah Peserta: {enrollments.length}</p>
                    </CardContent>
                </Card>

                <div className="flex items-center justify-between">
                    <h2 className="text-lg font-semibold">Daftar Mahasiswa</h2>
                    <Button onClick={() => setCreateOpen(true)}>
                        <UserPlus className="h-4 w-4" />
                        Tambah Mahasiswa
                    </Button>
                </div>

                <DataTable
                    columns={columns}
                    data={enrollments}
                    emptyText="Belum ada mahasiswa yang terdaftar di kelas ini."
                />

                <EnrollForm
                    open={createOpen}
                    onOpenChange={setCreateOpen}
                    courseClassId={courseClass.id}
                    availableStudents={availableStudents}
                />

                <DeleteConfirmDialog
                    target={deleting}
                    onOpenChange={(open) => {
                        if (!open) {
                            setDeleting(null);
                        }
                    }}
                    title="Keluarkan Mahasiswa"
                    description={(enrollment) =>
                        `Apakah Anda yakin ingin mengeluarkan "${enrollment.student?.user?.profile?.full_name ?? 'mahasiswa ini'}" dari kelas ini?`
                    }
                    onConfirm={handleDelete}
                />
            </div>
        </>
    );
}

function EnrollForm({
    open,
    onOpenChange,
    courseClassId,
    availableStudents,
}: {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    courseClassId: number;
    availableStudents: EnrollmentStudent[];
}) {
    const [selectedIds, setSelectedIds] = useState<number[]>([]);

    const allSelected =
        availableStudents.length > 0 &&
        selectedIds.length === availableStudents.length;

    function toggleAll() {
        setSelectedIds(
            allSelected ? [] : availableStudents.map((student) => student.id),
        );
    }

    function toggleOne(id: number) {
        setSelectedIds((prev) =>
            prev.includes(id)
                ? prev.filter((selectedId) => selectedId !== id)
                : [...prev, id],
        );
    }

    return (
        <FormDialog
            open={open}
            onOpenChange={onOpenChange}
            title="Tambah Mahasiswa"
            action={store(courseClassId)}
            resetOnSuccess
            submitDisabled={selectedIds.length === 0}
            submitLabel={
                selectedIds.length > 0
                    ? `Tambahkan (${selectedIds.length})`
                    : 'Tambahkan'
            }
            onSuccess={() => {
                onOpenChange(false);
                setSelectedIds([]);
            }}
        >
            {({ errors }) => (
                <div className="grid gap-4">
                    <div className="grid gap-2">
                        <div className="flex items-center justify-between">
                            <Label>
                                Mahasiswa{' '}
                                <span className="text-destructive">*</span>
                            </Label>
                            {availableStudents.length > 0 && (
                                <div className="flex items-center gap-2">
                                    <Checkbox
                                        id="select-all-students"
                                        checked={allSelected}
                                        onCheckedChange={toggleAll}
                                    />
                                    <Label
                                        htmlFor="select-all-students"
                                        className="text-sm font-normal"
                                    >
                                        Pilih Semua
                                    </Label>
                                </div>
                            )}
                        </div>
                        {selectedIds.map((id) => (
                            <input
                                key={id}
                                type="hidden"
                                name="student_ids[]"
                                value={id}
                            />
                        ))}
                        <div className="max-h-64 overflow-y-auto rounded-md border">
                            {availableStudents.length === 0 ? (
                                <p className="p-4 text-sm text-muted-foreground">
                                    Tidak ada mahasiswa dari jurusan yang sama
                                    untuk didaftarkan.
                                </p>
                            ) : (
                                availableStudents.map((student) => (
                                    <label
                                        key={student.id}
                                        htmlFor={`student-${student.id}`}
                                        className="flex items-center gap-2 border-b px-3 py-2 last:border-b-0 hover:bg-muted/50"
                                    >
                                        <Checkbox
                                            id={`student-${student.id}`}
                                            checked={selectedIds.includes(
                                                student.id,
                                            )}
                                            onCheckedChange={() =>
                                                toggleOne(student.id)
                                            }
                                        />
                                        <span className="text-sm">
                                            {student.user?.profile?.full_name ??
                                                'N/A'}{' '}
                                            - {student.student_number}
                                        </span>
                                    </label>
                                ))
                            )}
                        </div>
                        <InputError message={errors.student_ids} />
                    </div>
                </div>
            )}
        </FormDialog>
    );
}
