"use client"

import { useEffect, useMemo, useState } from "react"
import { MoreHorizontal, Pencil, Plus, Trash2 } from "lucide-react"
import { toast } from "sonner"
import { useRouter } from "next/navigation"

import type { AdminClassListItem, ClassSubjectTeacherAssignment, TeacherOption } from "../types"
import { DEFAULT_CLASS_SUBJECTS } from "../types"
import { createAdminClassAction, deleteAdminClassAction, updateAdminClassAction } from "../actions"
import { Button } from "@/shared/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/shared/components/ui/card"
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/shared/components/ui/dialog"
import { Input } from "@/shared/components/ui/input"
import { Label } from "@/shared/components/ui/label"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/shared/components/ui/table"
import { EmptyState } from "@/shared/components/ui/empty-state"
import { Badge } from "@/shared/components/ui/badge"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/shared/components/ui/dropdown-menu"
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/shared/components/ui/alert-dialog"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/shared/components/ui/select"
import { formatDate } from "@/shared/lib/utils"

export function AdminClassesClient({
  classes,
  teachers,
  schools,
  grades,
}: {
  classes: AdminClassListItem[]
  teachers: TeacherOption[]
  schools: { id: string; name: string }[]
  grades: { id: string; name: string; school: { id: string; name: string } }[]
}) {
  const router = useRouter()
  const [isWorking, setIsWorking] = useState(false)
  const [createOpen, setCreateOpen] = useState(false)
  const [editItem, setEditItem] = useState<AdminClassListItem | null>(null)
  const [deleteItem, setDeleteItem] = useState<AdminClassListItem | null>(null)

  const defaultTeacherId = useMemo(() => teachers[0]?.id ?? "", [teachers])
  const defaultSchoolId = useMemo(() => schools[0]?.id ?? "", [schools])
  const [createTeacherId, setCreateTeacherId] = useState(defaultTeacherId)
  const [createSchoolId, setCreateSchoolId] = useState(defaultSchoolId)
  const [createGradeId, setCreateGradeId] = useState("")
  const [editTeacherId, setEditTeacherId] = useState("")
  const [editSchoolId, setEditSchoolId] = useState("")
  const [editGradeId, setEditGradeId] = useState("")
  const [editSubjectTeachers, setEditSubjectTeachers] = useState<Array<{ subject: string; teacherId: string | null }>>([])

  const createGrades = useMemo(() => grades.filter((g) => g.school.id === createSchoolId), [grades, createSchoolId])
  const editGrades = useMemo(() => grades.filter((g) => g.school.id === editSchoolId), [grades, editSchoolId])
  const selectedCreateSchool = schools.find((s) => s.id === createSchoolId)
  const selectedCreateGrade = grades.find((g) => g.id === createGradeId)
  const selectedEditSchool = schools.find((s) => s.id === editSchoolId)
  const selectedEditGrade = grades.find((g) => g.id === editGradeId)

  useEffect(() => {
    if (!createOpen) return
    setCreateTeacherId(defaultTeacherId)
    setCreateSchoolId(defaultSchoolId)
    setCreateGradeId("")
  }, [createOpen, defaultTeacherId, defaultSchoolId])

  useEffect(() => {
    if (!editItem) return
    setEditTeacherId(editItem.teacher.id)
    setEditSchoolId(editItem.schoolId ?? "")
    setEditGradeId(editItem.gradeId ?? "")
    setEditSubjectTeachers(
      DEFAULT_CLASS_SUBJECTS.map((s) => ({
        subject: s,
        teacherId: editItem.subjectTeachers.find((st) => st.subject === s)?.teacher?.id ?? null,
      }))
    )
  }, [editItem])

  const handleCreate = async (formData: FormData) => {
    setIsWorking(true)
    try {
      const res = await createAdminClassAction(undefined, formData)
      if (res.success) {
        toast.success(res.message)
        setCreateOpen(false)
        router.refresh()
      } else {
        toast.error(res.message || "Failed to create class")
      }
    } catch {
      toast.error("Failed to create class")
    } finally {
      setIsWorking(false)
    }
  }

  const handleUpdate = async (formData: FormData) => {
    if (!editItem) return
    setIsWorking(true)
    try {
      const res = await updateAdminClassAction(editItem.id, undefined, formData)
      if (res.success) {
        toast.success(res.message)
        setEditItem(null)
        router.refresh()
      } else {
        toast.error(res.message || "Failed to update class")
      }
    } catch {
      toast.error("Failed to update class")
    } finally {
      setIsWorking(false)
    }
  }

  const handleDelete = async () => {
    if (!deleteItem) return
    setIsWorking(true)
    try {
      const res = await deleteAdminClassAction(deleteItem.id)
      if (res.success) {
        toast.success(res.message)
        setDeleteItem(null)
        router.refresh()
      } else {
        toast.error(res.message || "Failed to delete class")
      }
    } catch {
      toast.error("Failed to delete class")
    } finally {
      setIsWorking(false)
    }
  }

  const setSubjectTeacher = (subject: string, teacherId: string | null) => {
    setEditSubjectTeachers((prev) => prev.map((p) => (p.subject === subject ? { ...p, teacherId } : p)))
  }

  const formatSubjectTeachers = (list: ClassSubjectTeacherAssignment[]) => {
    const pairs = list
      .filter((x) => x.teacher)
      .map((x) => `${x.subject}:${x.teacher?.name ?? ""}`)
      .filter((x) => x.length > 0)
    return pairs.length > 0 ? pairs.join("，") : "-"
  }

  return (
    <>
      <div className="flex justify-end">
        <Button onClick={() => setCreateOpen(true)} disabled={isWorking}>
          <Plus className="mr-2 h-4 w-4" />
          New class
        </Button>
      </div>

      <Card className="shadow-none">
        <CardHeader className="flex flex-row items-center justify-between space-y-0">
          <CardTitle className="text-base">All classes</CardTitle>
          <Badge variant="secondary" className="tabular-nums">
            {classes.length}
          </Badge>
        </CardHeader>
        <CardContent>
          {classes.length === 0 ? (
            <EmptyState
              title="No classes"
              description="Create classes to manage students and schedules."
              className="h-auto border-none shadow-none"
            />
          ) : (
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>School</TableHead>
                  <TableHead>Name</TableHead>
                  <TableHead>Grade</TableHead>
                  <TableHead>Homeroom</TableHead>
                  <TableHead>Room</TableHead>
                  <TableHead>班主任</TableHead>
                  <TableHead>任课老师</TableHead>
                  <TableHead className="text-right">Students</TableHead>
                  <TableHead>Updated</TableHead>
                  <TableHead className="w-[60px]" />
                </TableRow>
              </TableHeader>
              <TableBody>
                {classes.map((c) => (
                  <TableRow key={c.id}>
                    <TableCell className="text-muted-foreground">{c.schoolName ?? "-"}</TableCell>
                    <TableCell className="font-medium">{c.name}</TableCell>
                    <TableCell className="text-muted-foreground">{c.grade}</TableCell>
                    <TableCell className="text-muted-foreground">{c.homeroom ?? "-"}</TableCell>
                    <TableCell className="text-muted-foreground">{c.room ?? "-"}</TableCell>
                    <TableCell className="text-muted-foreground">{c.teacher.name}</TableCell>
                    <TableCell className="text-muted-foreground">{formatSubjectTeachers(c.subjectTeachers)}</TableCell>
                    <TableCell className="text-muted-foreground tabular-nums text-right">{c.studentCount}</TableCell>
                    <TableCell className="text-muted-foreground">{formatDate(c.updatedAt)}</TableCell>
                    <TableCell className="text-right">
                      <DropdownMenu>
                        <DropdownMenuTrigger asChild>
                          <Button variant="ghost" size="icon" className="h-8 w-8" disabled={isWorking}>
                            <MoreHorizontal className="h-4 w-4" />
                          </Button>
                        </DropdownMenuTrigger>
                        <DropdownMenuContent align="end">
                          <DropdownMenuItem onClick={() => setEditItem(c)}>
                            <Pencil className="mr-2 h-4 w-4" />
                            Edit
                          </DropdownMenuItem>
                          <DropdownMenuSeparator />
                          <DropdownMenuItem
                            className="text-destructive focus:text-destructive"
                            onClick={() => setDeleteItem(c)}
                          >
                            <Trash2 className="mr-2 h-4 w-4" />
                            Delete
                          </DropdownMenuItem>
                        </DropdownMenuContent>
                      </DropdownMenu>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          )}
        </CardContent>
      </Card>

      <Dialog open={createOpen} onOpenChange={setCreateOpen}>
        <DialogContent className="sm:max-w-[560px]">
          <DialogHeader>
            <DialogTitle>New class</DialogTitle>
          </DialogHeader>
          <form action={handleCreate} className="space-y-4">
            <div className="grid grid-cols-4 items-center gap-4">
              <Label className="text-right">School</Label>
              <div className="col-span-3">
                <Select
                  value={createSchoolId}
                  onValueChange={(v) => {
                    setCreateSchoolId(v)
                    setCreateGradeId("")
                  }}
                  disabled={schools.length === 0}
                >
                  <SelectTrigger>
                    <SelectValue placeholder={schools.length === 0 ? "No schools" : "Select a school"} />
                  </SelectTrigger>
                  <SelectContent>
                    {schools.map((s) => (
                      <SelectItem key={s.id} value={s.id}>
                        {s.name}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                <input type="hidden" name="schoolId" value={createSchoolId} />
                <input type="hidden" name="schoolName" value={selectedCreateSchool?.name ?? ""} />
              </div>
            </div>

            <div className="grid grid-cols-4 items-center gap-4">
              <Label htmlFor="create-name" className="text-right">
                Name
              </Label>
              <Input id="create-name" name="name" className="col-span-3" placeholder="e.g. Grade 10 · Class 3" autoFocus />
            </div>

            <div className="grid grid-cols-4 items-center gap-4">
              <Label className="text-right">Grade</Label>
              <div className="col-span-3">
                <Select
                  value={createGradeId}
                  onValueChange={setCreateGradeId}
                  disabled={createGrades.length === 0}
                >
                  <SelectTrigger>
                    <SelectValue placeholder={createGrades.length === 0 ? "No grades" : "Select a grade"} />
                  </SelectTrigger>
                  <SelectContent>
                    {createGrades.map((g) => (
                      <SelectItem key={g.id} value={g.id}>
                        {g.name}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                <input type="hidden" name="gradeId" value={createGradeId} />
                <input type="hidden" name="grade" value={selectedCreateGrade?.name ?? ""} />
              </div>
            </div>

            <div className="grid grid-cols-4 items-center gap-4">
              <Label htmlFor="create-homeroom" className="text-right">
                Homeroom
              </Label>
              <Input id="create-homeroom" name="homeroom" className="col-span-3" placeholder="Optional" />
            </div>

            <div className="grid grid-cols-4 items-center gap-4">
              <Label htmlFor="create-room" className="text-right">
                Room
              </Label>
              <Input id="create-room" name="room" className="col-span-3" placeholder="Optional" />
            </div>

            <div className="grid grid-cols-4 items-center gap-4">
              <Label className="text-right">Teacher</Label>
              <div className="col-span-3">
                <Select value={createTeacherId} onValueChange={setCreateTeacherId} disabled={teachers.length === 0}>
                  <SelectTrigger>
                    <SelectValue placeholder={teachers.length === 0 ? "No teachers" : "Select a teacher"} />
                  </SelectTrigger>
                  <SelectContent>
                    {teachers.map((t) => (
                      <SelectItem key={t.id} value={t.id}>
                        {t.name} ({t.email})
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                <input type="hidden" name="teacherId" value={createTeacherId} />
              </div>
            </div>

            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => setCreateOpen(false)} disabled={isWorking}>
                Cancel
              </Button>
              <Button type="submit" disabled={isWorking || teachers.length === 0 || !createTeacherId || !createGradeId}>
                Create
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      <Dialog
        open={Boolean(editItem)}
        onOpenChange={(open) => {
          if (isWorking) return
          if (!open) setEditItem(null)
        }}
      >
        <DialogContent className="sm:max-w-[560px]">
          <DialogHeader>
            <DialogTitle>Edit class</DialogTitle>
          </DialogHeader>
          {editItem ? (
            <form action={handleUpdate} className="space-y-4">
              <div className="grid grid-cols-4 items-center gap-4">
                <Label className="text-right">School</Label>
                <div className="col-span-3">
                  <Select
                    value={editSchoolId}
                    onValueChange={(v) => {
                      setEditSchoolId(v)
                      setEditGradeId("")
                    }}
                    disabled={schools.length === 0}
                  >
                    <SelectTrigger>
                      <SelectValue placeholder={schools.length === 0 ? "No schools" : "Select a school"} />
                    </SelectTrigger>
                    <SelectContent>
                      {schools.map((s) => (
                        <SelectItem key={s.id} value={s.id}>
                          {s.name}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                  <input type="hidden" name="schoolId" value={editSchoolId} />
                  <input type="hidden" name="schoolName" value={selectedEditSchool?.name ?? ""} />
                </div>
              </div>

              <div className="grid grid-cols-4 items-center gap-4">
                <Label htmlFor="edit-name" className="text-right">
                  Name
                </Label>
                <Input id="edit-name" name="name" className="col-span-3" defaultValue={editItem.name} />
              </div>

              <div className="grid grid-cols-4 items-center gap-4">
                <Label className="text-right">Grade</Label>
                <div className="col-span-3">
                  <Select
                    value={editGradeId}
                    onValueChange={setEditGradeId}
                    disabled={editGrades.length === 0}
                  >
                    <SelectTrigger>
                      <SelectValue placeholder={editGrades.length === 0 ? "No grades" : "Select a grade"} />
                    </SelectTrigger>
                    <SelectContent>
                      {editGrades.map((g) => (
                        <SelectItem key={g.id} value={g.id}>
                          {g.name}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                  <input type="hidden" name="gradeId" value={editGradeId} />
                  <input type="hidden" name="grade" value={selectedEditGrade?.name ?? ""} />
                </div>
              </div>

              <div className="grid grid-cols-4 items-center gap-4">
                <Label htmlFor="edit-homeroom" className="text-right">
                  Homeroom
                </Label>
                <Input id="edit-homeroom" name="homeroom" className="col-span-3" defaultValue={editItem.homeroom ?? ""} />
              </div>

              <div className="grid grid-cols-4 items-center gap-4">
                <Label htmlFor="edit-room" className="text-right">
                  Room
                </Label>
                <Input id="edit-room" name="room" className="col-span-3" defaultValue={editItem.room ?? ""} />
              </div>

              <div className="grid grid-cols-4 items-center gap-4">
                <Label className="text-right">班主任</Label>
                <div className="col-span-3">
                  <Select value={editTeacherId} onValueChange={setEditTeacherId} disabled={teachers.length === 0}>
                    <SelectTrigger>
                      <SelectValue placeholder={teachers.length === 0 ? "No teachers" : "Select a teacher"} />
                    </SelectTrigger>
                    <SelectContent>
                      {teachers.map((t) => (
                        <SelectItem key={t.id} value={t.id}>
                          {t.name} ({t.email})
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                  <input type="hidden" name="teacherId" value={editTeacherId} />
                </div>
              </div>

              <div className="space-y-3 rounded-md border p-4">
                <div className="text-sm font-medium">任课老师</div>
                <div className="grid gap-3">
                  {DEFAULT_CLASS_SUBJECTS.map((subject) => {
                    const selected = editSubjectTeachers.find((x) => x.subject === subject)?.teacherId ?? null
                    return (
                      <div key={subject} className="grid grid-cols-4 items-center gap-4">
                        <Label className="text-right">{subject}</Label>
                        <div className="col-span-3">
                          <Select
                            value={selected ?? ""}
                            onValueChange={(v) => setSubjectTeacher(subject, v ? v : null)}
                            disabled={teachers.length === 0}
                          >
                            <SelectTrigger>
                              <SelectValue placeholder={teachers.length === 0 ? "No teachers" : "Select a teacher"} />
                            </SelectTrigger>
                            <SelectContent>
                              {teachers.map((t) => (
                                <SelectItem key={t.id} value={t.id}>
                                  {t.name} ({t.email})
                                </SelectItem>
                              ))}
                            </SelectContent>
                          </Select>
                        </div>
                      </div>
                    )
                  })}
                </div>
                <input type="hidden" name="subjectTeachers" value={JSON.stringify(editSubjectTeachers)} />
              </div>

              <DialogFooter>
                <Button type="button" variant="outline" onClick={() => setEditItem(null)} disabled={isWorking}>
                  Cancel
                </Button>
                <Button type="submit" disabled={isWorking || !editTeacherId}>
                  Save
                </Button>
              </DialogFooter>
            </form>
          ) : null}
        </DialogContent>
      </Dialog>

      <AlertDialog
        open={Boolean(deleteItem)}
        onOpenChange={(open) => {
          if (!open) setDeleteItem(null)
        }}
      >
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Delete class</AlertDialogTitle>
            <AlertDialogDescription>This will permanently delete {deleteItem?.name || "this class"}.</AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel disabled={isWorking}>Cancel</AlertDialogCancel>
            <AlertDialogAction onClick={handleDelete} disabled={isWorking}>
              Delete
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </>
  )
}
