"use client"

import type { JSX } from "react"
import { useMemo, useState } from "react"
import { useTranslations } from "next-intl"
import { ChevronLeft, ChevronRight, CalendarDays } from "lucide-react"

import { Button } from "@/shared/components/ui/button"
import { Badge } from "@/shared/components/ui/badge"
import { cn } from "@/shared/lib/utils"

import type { CoursePlanWithItems } from "../types"
import {
  planToCalendarEvents,
  buildMonthGrid,
  eventsOnDay,
  startOfMonth,
  endOfMonth,
  isSameDay,
  addMonths,
  type CalendarEvent,
} from "../lib/calendar-utils"

interface CoursePlanCalendarProps {
  plan: CoursePlanWithItems
}

/**
 * 课程计划月历视图（P2-7）。
 *
 * - 通过纯函数 `planToCalendarEvents` 将周计划映射到日期范围
 * - 月历网格采用 6×7 布局，周一为每周起始
 * - 支持上一月/下一月/今天导航
 * - 单元格内显示当日事件，按完成状态着色
 * - 无 `plan.startDate` 时显示空状态提示
 *
 * 可访问性：
 * - 导航按钮带 `aria-label`
 * - 日期单元格带 `role="gridcell"` 与 `aria-label`
 * - 今日单元格带 `aria-current="date"`
 */
export function CoursePlanCalendar({ plan }: CoursePlanCalendarProps): JSX.Element {
  const t = useTranslations("coursePlans")
  const [cursor, setCursor] = useState<Date>(() => new Date())

  const events: CalendarEvent[] = useMemo(
    () => planToCalendarEvents(plan),
    [plan],
  )

  const grid: Date[] = useMemo(() => buildMonthGrid(cursor), [cursor])
  const monthStart = useMemo(() => startOfMonth(cursor), [cursor])
  const monthEnd = useMemo(() => endOfMonth(cursor), [cursor])
  const visibleEvents = useMemo(
    () => events.filter((e) => {
      const start = new Date(e.startDate)
      const end = new Date(e.endDate)
      return start <= monthEnd && end >= monthStart
    }),
    [events, monthStart, monthEnd],
  )

  const today = new Date()
  const weekLabels = t.raw("calendar.weekShort") as unknown as string[]

  const handlePrev = (): void => setCursor((prev) => addMonths(prev, -1))
  const handleNext = (): void => setCursor((prev) => addMonths(prev, 1))
  const handleToday = (): void => setCursor(new Date())

  if (!plan.startDate) {
    return (
      <div
        className="flex flex-col items-center justify-center gap-2 rounded-lg border border-dashed p-8 text-center"
        role="status"
      >
        <CalendarDays className="h-8 w-8 text-muted-foreground" aria-hidden="true" />
        <p className="text-sm text-muted-foreground">
          {t("calendar.noStartDate")}
        </p>
      </div>
    )
  }

  return (
    <div className="space-y-4">
      {/* 导航条 */}
      <div className="flex items-center justify-between gap-2">
        <h3 className="text-lg font-semibold">
          {t("calendar.monthTitle", {
            year: cursor.getFullYear(),
            month: cursor.getMonth() + 1,
          })}
        </h3>
        <div className="flex items-center gap-1">
          <Button
            variant="outline"
            size="icon"
            onClick={handlePrev}
            aria-label={t("calendar.prevMonth")}
          >
            <ChevronLeft className="h-4 w-4" aria-hidden="true" />
          </Button>
          <Button variant="outline" size="sm" onClick={handleToday}>
            {t("calendar.today")}
          </Button>
          <Button
            variant="outline"
            size="icon"
            onClick={handleNext}
            aria-label={t("calendar.nextMonth")}
          >
            <ChevronRight className="h-4 w-4" aria-hidden="true" />
          </Button>
        </div>
      </div>

      {/* 周首行 */}
      <div
        className="grid grid-cols-7 gap-1 text-center text-xs font-medium text-muted-foreground"
        role="row"
      >
        {weekLabels.map((label) => (
          <div key={label} className="py-1" role="columnheader">
            {label}
          </div>
        ))}
      </div>

      {/* 日期网格 */}
      <div
        className="grid grid-cols-7 gap-1"
        role="grid"
        aria-label={t("calendar.title")}
      >
        {grid.map((day, index) => {
          const dayEvents = eventsOnDay(visibleEvents, day)
          const inMonth = day.getMonth() === cursor.getMonth()
          const isToday = isSameDay(day, today)
          return (
            <div
              key={index}
              role="gridcell"
              aria-label={day.toDateString()}
              aria-current={isToday ? "date" : undefined}
              className={cn(
                "min-h-[80px] rounded-md border p-1 text-left",
                inMonth ? "bg-card" : "bg-muted/30",
                isToday && "ring-2 ring-primary",
              )}
            >
              <div
                className={cn(
                  "mb-1 text-xs font-medium",
                  inMonth ? "text-foreground" : "text-muted-foreground/60",
                )}
              >
                {day.getDate()}
              </div>
              <div className="space-y-1">
                {dayEvents.slice(0, 2).map((event) => (
                  <div
                    key={event.id}
                    className={cn(
                      "truncate rounded px-1 py-0.5 text-[10px] leading-tight",
                      event.isCompleted
                        ? "bg-primary/15 text-primary"
                        : "bg-muted text-muted-foreground",
                    )}
                    title={`${t("calendar.week", { week: event.week })} · ${event.title}`}
                  >
                    {t("calendar.week", { week: event.week })}
                  </div>
                ))}
                {dayEvents.length > 2 ? (
                  <div className="text-[10px] text-muted-foreground">
                    +{dayEvents.length - 2}
                  </div>
                ) : null}
              </div>
            </div>
          )
        })}
      </div>

      {/* 当月事件列表 */}
      {visibleEvents.length > 0 ? (
        <div className="space-y-2">
          <h4 className="text-sm font-semibold">{t("calendar.title")}</h4>
          <ul className="space-y-1.5">
            {visibleEvents.map((event) => (
              <li
                key={event.id}
                className="flex flex-wrap items-center gap-2 rounded-md border p-2 text-xs"
              >
                <Badge variant={event.isCompleted ? "default" : "secondary"}>
                  {event.isCompleted ? t("calendar.completed") : t("calendar.pending")}
                </Badge>
                <span className="font-medium">
                  {t("calendar.week", { week: event.week })}
                </span>
                <span className="text-muted-foreground">{event.title}</span>
                <span className="text-muted-foreground">
                  {event.startDate} ~ {event.endDate}
                </span>
                <span className="text-muted-foreground">
                  {t("calendar.hours", { hours: event.hours })}
                </span>
              </li>
            ))}
          </ul>
        </div>
      ) : (
        <p className="py-4 text-center text-sm text-muted-foreground">
          {t("calendar.noPlans")}
        </p>
      )}
    </div>
  )
}
