"use client"

import Link from "next/link"
import { useMemo, useState } from "react"
import { useRouter } from "next/navigation"
import { Calendar, Copy, MoreHorizontal, Pencil, Plus, RefreshCw, Trash2, Users } from "lucide-react"
import { toast } from "sonner"
import { parseAsString, useQueryState } from "nuqs"

import { Card, CardContent, CardHeader, CardTitle } from "@/shared/components/ui/card"
import { Button } from "@/shared/components/ui/button"
import { Badge } from "@/shared/components/ui/badge"
import { EmptyState } from "@/shared/components/ui/empty-state"
import { cn } from "@/shared/lib/utils"
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 {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/shared/components/ui/dialog"
import { Input } from "@/shared/components/ui/input"
import { Label } from "@/shared/components/ui/label"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/shared/components/ui/select"
import type { TeacherClass } from "../types"
import {
  createTeacherClassAction,
  deleteTeacherClassAction,
  ensureClassInvitationCodeAction,
  regenerateClassInvitationCodeAction,
  updateTeacherClassAction,
} from "../actions"

export function MyClassesGrid({ classes }: { classes: TeacherClass[] }) {
  const router = useRouter()
  const [isWorking, setIsWorking] = useState(false)
  const [createOpen, setCreateOpen] = useState(false)

  const [q, setQ] = useQueryState("q", parseAsString.withDefault(""))
  const [grade, setGrade] = useQueryState("grade", parseAsString.withDefault("all"))

  const gradeOptions = useMemo(() => {
    const set = new Set<string>()
    for (const c of classes) set.add(c.grade)
    return Array.from(set).sort((a, b) => a.localeCompare(b))
  }, [classes])

  const filteredClasses = useMemo(() => {
    const needle = q.trim().toLowerCase()
    return classes.filter((c) => {
      const gradeOk = grade === "all" ? true : c.grade === grade
      const qOk = needle.length === 0 ? true : c.name.toLowerCase().includes(needle)
      return gradeOk && qOk
    })
  }, [classes, grade, q])

  const defaultGrade = useMemo(() => (grade !== "all" ? grade : classes[0]?.grade ?? ""), [classes, grade])

  const handleCreate = async (formData: FormData) => {
    setIsWorking(true)
    try {
      const res = await createTeacherClassAction(null, 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)
    }
  }

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between gap-3">
        <div className="flex flex-1 items-center gap-2">
          <div className="relative flex-1 md:max-w-sm">
            <Input
              placeholder="Search classes..."
              value={q}
              onChange={(e) => setQ(e.target.value || null)}
            />
          </div>
          <Select value={grade} onValueChange={(v) => setGrade(v === "all" ? null : v)}>
            <SelectTrigger className="w-[200px]">
              <SelectValue placeholder="Grade" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All grades</SelectItem>
              {gradeOptions.map((g) => (
                <SelectItem key={g} value={g}>
                  {g}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          {(q || grade !== "all") && (
            <Button
              variant="ghost"
              className="h-9"
              onClick={() => {
                setQ(null)
                setGrade(null)
              }}
            >
              Reset
            </Button>
          )}
        </div>
        <Dialog
          open={createOpen}
          onOpenChange={(open) => {
            if (isWorking) return
            setCreateOpen(open)
          }}
        >
          <DialogTrigger asChild>
            <Button className="gap-2" disabled={isWorking}>
              <Plus className="size-4" />
              New class
            </Button>
          </DialogTrigger>
          <DialogContent className="sm:max-w-[480px]">
            <DialogHeader>
              <DialogTitle>Create class</DialogTitle>
              <DialogDescription>Add a new class to start managing students.</DialogDescription>
            </DialogHeader>
            <form action={handleCreate}>
              <div className="grid gap-4 py-4">
                <div className="grid grid-cols-4 items-center gap-4">
                  <Label htmlFor="create-school-name" className="text-right">
                    School
                  </Label>
                  <Input
                    id="create-school-name"
                    name="schoolName"
                    className="col-span-3"
                    placeholder="Optional"
                  />
                </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. Class 1A" required />
                </div>
                <div className="grid grid-cols-4 items-center gap-4">
                  <Label htmlFor="create-grade" className="text-right">
                    Grade
                  </Label>
                  <Input
                    id="create-grade"
                    name="grade"
                    className="col-span-3"
                    placeholder="e.g. Grade 7"
                    defaultValue={defaultGrade}
                    required
                  />
                </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>
              <DialogFooter>
                <Button type="submit" disabled={isWorking}>
                  {isWorking ? "Creating..." : "Create"}
                </Button>
              </DialogFooter>
            </form>
          </DialogContent>
        </Dialog>
      </div>

      <div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
        {classes.length === 0 ? (
          <EmptyState
            title="No classes yet"
            description="Create your first class to start managing students and schedules."
            icon={Users}
            action={{ label: "Create class", onClick: () => setCreateOpen(true) }}
            className="h-[360px] bg-card sm:col-span-2 lg:col-span-3"
          />
        ) : filteredClasses.length === 0 ? (
          <EmptyState
            title="No classes match your filters"
            description="Try clearing filters or adjusting keywords."
            icon={Users}
            action={{ label: "Clear filters", onClick: () => {
              setQ(null)
              setGrade(null)
            }}}
            className="h-[360px] bg-card sm:col-span-2 lg:col-span-3"
          />
        ) : (
          filteredClasses.map((c) => (
            <ClassCard
              key={c.id}
              c={c}
              onWorkingChange={setIsWorking}
              isWorking={isWorking}
            />
          ))
        )}
      </div>
    </div>
  )
}

function ClassCard({
  c,
  isWorking,
  onWorkingChange,
}: {
  c: TeacherClass
  isWorking: boolean
  onWorkingChange: (v: boolean) => void
}) {
  const router = useRouter()
  const [showEdit, setShowEdit] = useState(false)
  const [showDelete, setShowDelete] = useState(false)

  const handleEnsureCode = async () => {
    onWorkingChange(true)
    try {
      const res = await ensureClassInvitationCodeAction(c.id)
      if (res.success) {
        toast.success(res.message || "Invitation code ready")
        router.refresh()
      } else {
        toast.error(res.message || "Failed to generate invitation code")
      }
    } catch {
      toast.error("Failed to generate invitation code")
    } finally {
      onWorkingChange(false)
    }
  }

  const handleRegenerateCode = async () => {
    onWorkingChange(true)
    try {
      const res = await regenerateClassInvitationCodeAction(c.id)
      if (res.success) {
        toast.success(res.message || "Invitation code updated")
        router.refresh()
      } else {
        toast.error(res.message || "Failed to regenerate invitation code")
      }
    } catch {
      toast.error("Failed to regenerate invitation code")
    } finally {
      onWorkingChange(false)
    }
  }

  const handleCopyCode = async () => {
    const code = c.invitationCode ?? ""
    if (!code) return
    try {
      await navigator.clipboard.writeText(code)
      toast.success("Copied invitation code")
    } catch {
      toast.error("Failed to copy")
    }
  }

  const handleEdit = async (formData: FormData) => {
    onWorkingChange(true)
    try {
      const res = await updateTeacherClassAction(c.id, null, formData)
      if (res.success) {
        toast.success(res.message)
        setShowEdit(false)
        router.refresh()
      } else {
        toast.error(res.message || "Failed to update class")
      }
    } catch {
      toast.error("Failed to update class")
    } finally {
      onWorkingChange(false)
    }
  }

  const handleDelete = async () => {
    onWorkingChange(true)
    try {
      const res = await deleteTeacherClassAction(c.id)
      if (res.success) {
        toast.success(res.message)
        setShowDelete(false)
        router.refresh()
      } else {
        toast.error(res.message || "Failed to delete class")
      }
    } catch {
      toast.error("Failed to delete class")
    } finally {
      onWorkingChange(false)
    }
  }

  return (
    <Card className="shadow-none">
      <CardHeader className="space-y-2">
        <div className="flex items-start justify-between gap-3">
          <div className="min-w-0">
            <CardTitle className="text-base truncate">
              <Link href={`/teacher/classes/my/${encodeURIComponent(c.id)}`} className="hover:underline">
                {c.name}
              </Link>
            </CardTitle>
            <div className="text-muted-foreground text-sm mt-1">
              {c.room ? `Room: ${c.room}` : "Room: Not set"}
            </div>
          </div>

          <div className="flex items-center gap-2">
            <Badge variant="secondary">{c.grade}</Badge>
            <DropdownMenu>
              <DropdownMenuTrigger asChild>
                <Button variant="ghost" size="icon" className="h-8 w-8" disabled={isWorking}>
                  <MoreHorizontal className="size-4" />
                </Button>
              </DropdownMenuTrigger>
              <DropdownMenuContent align="end">
                <DropdownMenuItem onClick={() => setShowEdit(true)}>
                  <Pencil className="mr-2 size-4" />
                  Edit
                </DropdownMenuItem>
                <DropdownMenuSeparator />
                <DropdownMenuItem
                  className="text-destructive focus:text-destructive"
                  onClick={() => setShowDelete(true)}
                >
                  <Trash2 className="mr-2 size-4" />
                  Delete
                </DropdownMenuItem>
              </DropdownMenuContent>
            </DropdownMenu>
          </div>
        </div>
      </CardHeader>

      <CardContent className="space-y-4">
        <div className="flex items-center justify-between">
          <div className="text-sm font-medium tabular-nums">{c.studentCount} students</div>
          {c.homeroom ? <Badge variant="outline">{c.homeroom}</Badge> : null}
        </div>
        <div className="flex items-center justify-between gap-3">
          <div className="min-w-0">
            <div className="text-xs uppercase text-muted-foreground">Invitation code</div>
            <div className="font-mono tabular-nums text-sm">{c.invitationCode ?? "-"}</div>
          </div>
          <div className="flex items-center gap-2">
            {c.invitationCode ? (
              <>
                <Button variant="outline" size="sm" className="gap-2" onClick={handleCopyCode} disabled={isWorking}>
                  <Copy className="size-4" />
                  Copy
                </Button>
                <Button variant="outline" size="sm" className="gap-2" onClick={handleRegenerateCode} disabled={isWorking}>
                  <RefreshCw className="size-4" />
                  Regenerate
                </Button>
              </>
            ) : (
              <Button variant="outline" size="sm" onClick={handleEnsureCode} disabled={isWorking}>
                Generate
              </Button>
            )}
          </div>
        </div>
        <div className={cn("grid gap-2", "grid-cols-2")}>
          <Button asChild variant="outline" className="w-full justify-start gap-2">
            <Link href={`/teacher/classes/students?classId=${encodeURIComponent(c.id)}`}>
              <Users className="size-4" />
              Students
            </Link>
          </Button>
          <Button asChild variant="outline" className="w-full justify-start gap-2">
            <Link href={`/teacher/classes/schedule?classId=${encodeURIComponent(c.id)}`}>
              <Calendar className="size-4" />
              Schedule
            </Link>
          </Button>
        </div>
      </CardContent>

      <Dialog
        open={showEdit}
        onOpenChange={(open) => {
          if (isWorking) return
          setShowEdit(open)
        }}
      >
        <DialogContent className="sm:max-w-[480px]">
          <DialogHeader>
            <DialogTitle>Edit class</DialogTitle>
            <DialogDescription>Update basic class information.</DialogDescription>
          </DialogHeader>
          <form action={handleEdit}>
            <div className="grid gap-4 py-4">
              <div className="grid grid-cols-4 items-center gap-4">
                <Label htmlFor={`edit-school-name-${c.id}`} className="text-right">
                  School
                </Label>
                <Input
                  id={`edit-school-name-${c.id}`}
                  name="schoolName"
                  className="col-span-3"
                  defaultValue={c.schoolName ?? ""}
                  placeholder="Optional"
                />
              </div>
              <div className="grid grid-cols-4 items-center gap-4">
                <Label htmlFor={`edit-name-${c.id}`} className="text-right">
                  Name
                </Label>
                <Input
                  id={`edit-name-${c.id}`}
                  name="name"
                  className="col-span-3"
                  defaultValue={c.name}
                  required
                />
              </div>
              <div className="grid grid-cols-4 items-center gap-4">
                <Label htmlFor={`edit-grade-${c.id}`} className="text-right">
                  Grade
                </Label>
                <Input
                  id={`edit-grade-${c.id}`}
                  name="grade"
                  className="col-span-3"
                  defaultValue={c.grade}
                  required
                />
              </div>
              <div className="grid grid-cols-4 items-center gap-4">
                <Label htmlFor={`edit-homeroom-${c.id}`} className="text-right">
                  Homeroom
                </Label>
                <Input
                  id={`edit-homeroom-${c.id}`}
                  name="homeroom"
                  className="col-span-3"
                  defaultValue={c.homeroom ?? ""}
                />
              </div>
              <div className="grid grid-cols-4 items-center gap-4">
                <Label htmlFor={`edit-room-${c.id}`} className="text-right">
                  Room
                </Label>
                <Input
                  id={`edit-room-${c.id}`}
                  name="room"
                  className="col-span-3"
                  defaultValue={c.room ?? ""}
                />
              </div>
            </div>
            <DialogFooter>
              <Button type="submit" disabled={isWorking}>
                {isWorking ? "Saving..." : "Save"}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      <AlertDialog
        open={showDelete}
        onOpenChange={(open) => {
          if (isWorking) return
          setShowDelete(open)
        }}
      >
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Delete class?</AlertDialogTitle>
            <AlertDialogDescription>
              This will permanently delete <span className="font-medium text-foreground">{c.name}</span> and remove all
              enrollments.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel disabled={isWorking}>Cancel</AlertDialogCancel>
            <AlertDialogAction
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
              onClick={handleDelete}
              disabled={isWorking}
            >
              {isWorking ? "Deleting..." : "Delete"}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </Card>
  )
}
