"use client"

import { useState, useTransition } from "react"
import { useRouter } from "next/navigation"
import { toast } from "sonner"
import { useTranslations } from "next-intl"
import { BookOpen, CheckCircle2, XCircle } from "lucide-react"

import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@/shared/components/ui/alert-dialog"
import { Badge } from "@/shared/components/ui/badge"
import { Button } from "@/shared/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/shared/components/ui/card"
import { EmptyState } from "@/shared/components/ui/empty-state"
import { Label } from "@/shared/components/ui/label"
import { Textarea } from "@/shared/components/ui/textarea"

import {
  COURSE_SELECTION_STATUS_BADGE_VARIANTS,
  COURSE_SELECTION_STATUS_LABEL_KEYS,
  ELECTIVE_STATUS_BADGE_VARIANTS,
  ELECTIVE_STATUS_LABEL_KEYS,
  SELECTION_MODE_LABEL_KEYS,
} from "../constants"
import type {
  CourseSelectionWithDetails,
  ElectiveCourseWithDetails,
} from "../types"
import { selectCourseAction, dropCourseAction } from "../actions"

/**
 * 已选课程区块（我的选课）
 * - 独立 Suspense 边界内的客户端组件
 * - 仅负责"退课"操作与展示
 */
export function StudentMySelectionsSection({
  mySelections,
}: {
  mySelections: CourseSelectionWithDetails[]
}) {
  const router = useRouter()
  const t = useTranslations("elective")
  const [pendingId, setPendingId] = useState<string | null>(null)
  const [isPending, startTransition] = useTransition()
  // P2-4：退课理由输入（按课程 ID 隔离，便于多卡片独立填写）
  const [dropReasonMap, setDropReasonMap] = useState<Record<string, string>>({})

  const activeSelections = mySelections.filter((s) =>
    ["selected", "enrolled", "waitlist"].includes(s.status)
  )

  const handleDrop = (courseId: string) => {
    setPendingId(courseId)
    startTransition(async () => {
      const formData = new FormData()
      formData.set("courseId", courseId)
      // P2-4：透传退课理由
      const reason = dropReasonMap[courseId]
      if (reason && reason.trim().length > 0) {
        formData.set("dropReason", reason.trim())
      }
      const res = await dropCourseAction(null, formData)
      if (res.success) {
        toast.success(res.message || t("student.dropSuccess"))
        router.refresh()
        // 清空该课程的退课理由
        setDropReasonMap((prev) => {
          const next = { ...prev }
          delete next[courseId]
          return next
        })
      } else {
        toast.error(res.message ?? t("errors.unexpected"))
      }
      setPendingId(null)
    })
  }

  return (
    <section className="space-y-4" aria-labelledby="student-my-selections-heading">
      <div className="flex items-center justify-between">
        <h3
          id="student-my-selections-heading"
          className="text-lg font-semibold"
        >
          {t("student.mySelections")}
        </h3>
        <span className="text-sm text-muted-foreground" aria-live="polite">
          {activeSelections.length}
        </span>
      </div>
      {activeSelections.length === 0 ? (
        <EmptyState
          title={t("list.empty")}
          description={t("description.student")}
          icon={BookOpen}
          className="h-auto border-none shadow-none"
        />
      ) : (
        <div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
          {activeSelections.map((sel) => (
            <Card key={sel.id}>
              <CardHeader className="flex flex-row items-start justify-between gap-2 space-y-0">
                <CardTitle className="text-base">
                  {sel.courseName ?? t("errors.notFound")}
                </CardTitle>
                <Badge variant={COURSE_SELECTION_STATUS_BADGE_VARIANTS[sel.status]}>
                  {t(COURSE_SELECTION_STATUS_LABEL_KEYS[sel.status])}
                </Badge>
              </CardHeader>
              <CardContent className="space-y-3">
                {sel.courseCapacity !== null && sel.courseEnrolledCount !== null ? (
                  <p className="text-xs text-muted-foreground">
                    {t("fields.enrolled")}: {sel.courseEnrolledCount}/{sel.courseCapacity}
                  </p>
                ) : null}
                {sel.lotteryRank ? (
                  <p className="text-xs text-muted-foreground">
                    #{sel.lotteryRank}
                  </p>
                ) : null}
                <AlertDialog>
                  <AlertDialogTrigger asChild>
                    <Button
                      variant="outline"
                      size="sm"
                      className="text-destructive hover:text-destructive"
                      disabled={isPending && pendingId === sel.courseId}
                    >
                      <XCircle className="mr-1 h-3 w-3" />
                      {t("actions.drop")}
                    </Button>
                  </AlertDialogTrigger>
                  <AlertDialogContent>
                    <AlertDialogHeader>
                      <AlertDialogTitle>{t("student.confirmDrop")}</AlertDialogTitle>
                      <AlertDialogDescription>
                        {t("student.confirmDrop")}
                      </AlertDialogDescription>
                    </AlertDialogHeader>
                    {/* P2-4：可选退课理由输入 */}
                    <div className="grid gap-2 py-2">
                      <Label htmlFor={`dropReason-${sel.courseId}`}>
                        {t("fields.dropReason")}
                      </Label>
                      <Textarea
                        id={`dropReason-${sel.courseId}`}
                        value={dropReasonMap[sel.courseId] ?? ""}
                        onChange={(e) =>
                          setDropReasonMap((prev) => ({
                            ...prev,
                            [sel.courseId]: e.target.value,
                          }))
                        }
                        placeholder={t("student.dropReasonPlaceholder")}
                        className="min-h-[60px]"
                        maxLength={255}
                      />
                    </div>
                    <AlertDialogFooter>
                      <AlertDialogCancel>{t("actions.cancel")}</AlertDialogCancel>
                      <AlertDialogAction
                        onClick={() => handleDrop(sel.courseId)}
                      >
                        {t("actions.drop")}
                      </AlertDialogAction>
                    </AlertDialogFooter>
                  </AlertDialogContent>
                </AlertDialog>
              </CardContent>
            </Card>
          ))}
        </div>
      )}
    </section>
  )
}

/**
 * 可选课程区块
 * - 独立 Suspense 边界内的客户端组件
 * - 仅负责"选课"操作与展示
 * - 通过 selectedCourseIds prop 接收已选课程 ID 集合，避免与已选区块直接耦合
 */
export function StudentAvailableCoursesSection({
  availableCourses,
  selectedCourseIds,
}: {
  availableCourses: ElectiveCourseWithDetails[]
  selectedCourseIds: Set<string>
}) {
  const router = useRouter()
  const t = useTranslations("elective")
  const [pendingId, setPendingId] = useState<string | null>(null)
  const [isPending, startTransition] = useTransition()

  const handleSelect = (courseId: string) => {
    setPendingId(courseId)
    startTransition(async () => {
      const formData = new FormData()
      formData.set("courseId", courseId)
      const res = await selectCourseAction(null, formData)
      if (res.success) {
        toast.success(res.message || t("student.selectSuccess"))
        router.refresh()
      } else {
        toast.error(res.message ?? t("errors.unexpected"))
      }
      setPendingId(null)
    })
  }

  return (
    <section className="space-y-4" aria-labelledby="student-available-courses-heading">
      <div className="flex items-center justify-between">
        <h3
          id="student-available-courses-heading"
          className="text-lg font-semibold"
        >
          {t("student.availableCourses")}
        </h3>
        <span className="text-sm text-muted-foreground" aria-live="polite">
          {availableCourses.length}
        </span>
      </div>
      {availableCourses.length === 0 ? (
        <EmptyState
          title={t("list.emptyStudent")}
          description={t("description.student")}
          icon={BookOpen}
          className="h-auto border-none shadow-none"
        />
      ) : (
        <div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
          {availableCourses.map((course) => {
            const isFull = course.enrolledCount >= course.capacity
            const alreadySelected = selectedCourseIds.has(course.id)
            const isPendingThis = isPending && pendingId === course.id
            return (
              <Card key={course.id} className="flex h-full flex-col" role="article" aria-label={course.name}>
                <CardHeader className="flex flex-row items-start justify-between gap-2 space-y-0">
                  <CardTitle className="line-clamp-2 text-base">{course.name}</CardTitle>
                  <Badge variant={ELECTIVE_STATUS_BADGE_VARIANTS[course.status]}>
                    {t(ELECTIVE_STATUS_LABEL_KEYS[course.status])}
                  </Badge>
                </CardHeader>
                <CardContent className="flex flex-1 flex-col gap-3">
                  <div className="flex flex-wrap items-center gap-2 text-xs text-muted-foreground">
                    {course.subjectName ? (
                      <Badge variant="outline">{course.subjectName}</Badge>
                    ) : null}
                    <span>{t("fields.credit")}: {course.credit}</span>
                    <span>· {t(SELECTION_MODE_LABEL_KEYS[course.selectionMode])}</span>
                  </div>
                  {course.description ? (
                    <p className="line-clamp-2 text-sm text-muted-foreground">
                      {course.description}
                    </p>
                  ) : null}
                  <div className="grid grid-cols-2 gap-2 text-xs">
                    <div>
                      <span className="text-muted-foreground">{t("fields.teacher")}:</span>{" "}
                      <span className="font-medium">{course.teacherName ?? "—"}</span>
                    </div>
                    <div>
                      <span className="text-muted-foreground">{t("fields.capacity")}:</span>{" "}
                      <span className="font-medium">
                        {course.enrolledCount}/{course.capacity}
                        {isFull ? ` (${t("student.capacityFull")})` : ""}
                      </span>
                    </div>
                  </div>
                  {course.schedule ? (
                    <p className="text-xs text-muted-foreground">
                      <span className="font-medium">{t("fields.schedule")}:</span> {course.schedule}
                    </p>
                  ) : null}
                  <div className="mt-auto pt-2">
                    {alreadySelected ? (
                      <Button variant="secondary" size="sm" disabled>
                        <CheckCircle2 className="mr-1 h-3 w-3" />
                        {t("student.selected")}
                      </Button>
                    ) : (
                      <Button
                        size="sm"
                        disabled={isPendingThis}
                        onClick={() => handleSelect(course.id)}
                      >
                        {isPendingThis ? t("actions.select") + "..." : t("actions.select")}
                      </Button>
                    )}
                  </div>
                </CardContent>
              </Card>
            )
          })}
        </div>
      )}
    </section>
  )
}
