"use client"

import { useEffect, useRef, useState } from "react"
import Link from "next/link"
import { useRouter } from "next/navigation"
import { useTranslations } from "next-intl"
import { Bell, CheckCheck, MessageSquare, Megaphone, PenTool, GraduationCap, Stethoscope } from "lucide-react"

import { Badge } from "@/shared/components/ui/badge"
import { Button } from "@/shared/components/ui/button"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/shared/components/ui/dropdown-menu"
import { ScrollArea } from "@/shared/components/ui/scroll-area"
import { cn, formatDate } from "@/shared/lib/utils"

import {
  markAllNotificationsAsReadAction,
  markNotificationAsReadAction,
} from "../actions"
import { useDesktopNotifications } from "../hooks/use-desktop-notifications"
import { useNotificationStream } from "../hooks/use-notification-stream"
import type { NotificationType } from "../types"

const TYPE_ICON: Record<NotificationType, typeof Bell> = {
  message: MessageSquare,
  announcement: Megaphone,
  homework: PenTool,
  grade: GraduationCap,
  diagnostic: Stethoscope,
}

/** 轮询降级间隔（毫秒） */
const FALLBACK_POLL_INTERVAL_MS = 30_000

export function NotificationDropdown() {
  const t = useTranslations("notifications")
  const router = useRouter()
  const [open, setOpen] = useState(false)

  // 使用 SSE 实时推送（自动降级为轮询）
  const { unreadCount, notifications } = useNotificationStream({
    fallbackPollInterval: FALLBACK_POLL_INTERVAL_MS,
  })

  // 桌面推送通知（用户切换标签页时仍可收到提醒）
  const { showNotification } = useDesktopNotifications({ enabled: true })

  // 监听新通知并触发桌面推送（使用 ref 避免 setState in effect）
  const prevNotificationIdsRef = useRef<Set<string>>(new Set())

  useEffect(() => {
    if (notifications.length === 0) return

    const currentIds = new Set(notifications.map((n) => n.id))
    const prevIds = prevNotificationIdsRef.current
    // 首次加载不触发桌面推送（避免页面加载时批量推送）
    if (prevIds.size === 0) {
      prevNotificationIdsRef.current = currentIds
      return
    }

    // 找出新增的通知
    const newNotifications = notifications.filter(
      (n) => !prevIds.has(n.id) && !n.isRead
    )

    // 为每个新通知触发桌面推送
    for (const n of newNotifications) {
      showNotification(n)
    }

    prevNotificationIdsRef.current = currentIds
  }, [notifications, showNotification])

  const handleMarkAllRead = async () => {
    const res = await markAllNotificationsAsReadAction()
    if (res.success) {
      router.refresh()
    }
  }

  const handleMarkRead = async (id: string) => {
    const res = await markNotificationAsReadAction(id)
    if (res.success) {
      router.refresh()
    }
  }

  return (
    <DropdownMenu open={open} onOpenChange={setOpen}>
      <DropdownMenuTrigger asChild>
        <Button variant="ghost" size="icon" className="relative text-muted-foreground" aria-label={t("title.dropdown")}>
          <Bell className="size-5" aria-hidden="true" />
          {unreadCount > 0 ? (
            <Badge
              variant="destructive"
              className="absolute -top-0.5 -right-0.5 flex h-4 min-w-4 items-center justify-center px-1 text-[10px]"
            >
              {unreadCount > 9 ? "9+" : unreadCount}
            </Badge>
          ) : null}
          <span className="sr-only">{t("title.dropdown")}</span>
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end" className="w-80 p-0">
        <DropdownMenuLabel className="flex items-center justify-between">
          <span>{t("title.dropdown")}</span>
          {unreadCount > 0 ? (
            <button
              type="button"
              onClick={handleMarkAllRead}
              className="text-primary text-xs hover:underline"
            >
              <CheckCheck className="mr-1 inline h-3 w-3" aria-hidden="true" />
              {t("actions.markAllRead")}
            </button>
          ) : null}
        </DropdownMenuLabel>
        <DropdownMenuSeparator className="mb-0" />
        <ScrollArea className="max-h-[320px]">
          {notifications.length === 0 ? (
            <div className="text-muted-foreground px-4 py-8 text-center text-sm">
              {t("empty.noNotificationsDropdown")}
            </div>
          ) : (
            notifications.map((n) => {
              const Icon = TYPE_ICON[n.type] ?? Bell
              return (
                <DropdownMenuItem
                  key={n.id}
                  className="flex items-start gap-2 py-3"
                  onSelect={(e) => {
                    if (!n.isRead) {
                      e.preventDefault()
                      handleMarkRead(n.id)
                    }
                  }}
                >
                  <div className="bg-muted mt-0.5 flex size-7 shrink-0 items-center justify-center rounded-full">
                    <Icon className="h-3.5 w-3.5" aria-hidden="true" />
                  </div>
                  <div className="min-w-0 flex-1 space-y-0.5">
                    <div className="flex items-center gap-1.5">
                      {!n.isRead ? (
                        <span className="bg-primary size-1.5 shrink-0 rounded-full" aria-hidden="true" />
                      ) : null}
                      <span className={cn("text-xs", !n.isRead ? "font-semibold" : "font-medium")}>
                        {n.title}
                      </span>
                    </div>
                    {n.content ? (
                      <p className="text-muted-foreground line-clamp-2 text-xs">{n.content}</p>
                    ) : null}
                    <span className="text-muted-foreground text-[10px]">
                      {formatDate(n.createdAt)}
                    </span>
                  </div>
                </DropdownMenuItem>
              )
            })
          )}
        </ScrollArea>
        <DropdownMenuSeparator className="mt-0" />
        <DropdownMenuItem asChild>
          <Link href="/messages" className="text-primary justify-center text-xs">
            {t("actions.viewAll")}
          </Link>
        </DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  )
}
