"use client";

import { useEffect, useState } from "react";
import Link from "next/link";
import { useTranslations } from "next-intl";
import { Bell } from "lucide-react";
import { Button } from "@/components/ui/button";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Badge } from "@/components/ui/badge";
import { cn } from "@/lib/utils";

type Notification = {
  id: string;
  type: "follow" | "comment" | "reply" | "reaction" | "rating" | "mention";
  recipeId: string | null;
  commentId: string | null;
  read: boolean;
  createdAt: string;
  actorId: string;
  actorName: string;
  actorUsername: string | null;
};

function notificationHref(n: Notification): string {
  if (n.type === "follow") return n.actorUsername ? `/u/${n.actorUsername}` : "#";
  if (n.recipeId) return `/recipes/${n.recipeId}`;
  return "#";
}

export function NotificationBell() {
  const t = useTranslations("notifications");
  const [notifications, setNotifications] = useState<Notification[]>([]);
  const [unreadCount, setUnreadCount] = useState(0);
  const [open, setOpen] = useState(false);

  async function load() {
    try {
      const res = await fetch("/api/v1/notifications");
      if (!res.ok) return;
      const data = (await res.json()) as { notifications: Notification[]; unreadCount: number };
      setNotifications(data.notifications);
      setUnreadCount(data.unreadCount);
    } catch {
      // silent — bell just stays at last known state
    }
  }

  useEffect(() => {
    void load();
    const interval = setInterval(() => { void load(); }, 30_000);
    return () => clearInterval(interval);
  }, []);

  async function markAllRead() {
    setUnreadCount(0);
    setNotifications((prev) => prev.map((n) => ({ ...n, read: true })));
    await fetch("/api/v1/notifications/read", { method: "POST" });
  }

  return (
    <DropdownMenu open={open} onOpenChange={(next) => { setOpen(next); if (next) void load(); }}>
      <DropdownMenuTrigger render={<Button variant="ghost" size="icon" className="relative" />}>
        <Bell className="h-4 w-4" />
        {unreadCount > 0 && (
          <Badge
            variant="destructive"
            className="absolute -top-1 -right-1 h-4 min-w-4 px-1 text-[10px] leading-none flex items-center justify-center"
          >
            {unreadCount > 9 ? "9+" : unreadCount}
          </Badge>
        )}
        <span className="sr-only">{t("title")}</span>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end" className="w-80">
        <div className="flex items-center justify-between px-2 py-1.5">
          <span className="text-sm font-medium">{t("title")}</span>
          {unreadCount > 0 && (
            <button
              type="button"
              onClick={() => { void markAllRead(); }}
              className="text-xs text-muted-foreground hover:text-foreground underline underline-offset-4"
            >
              {t("markAllRead")}
            </button>
          )}
        </div>
        {notifications.length === 0 && (
          <p className="px-2 py-4 text-sm text-muted-foreground text-center">{t("empty")}</p>
        )}
        <div className="max-h-96 overflow-y-auto">
          {notifications.map((n) => (
            <DropdownMenuItem key={n.id} render={<Link href={notificationHref(n)} />}>
              <div className={cn("flex items-start gap-2 py-1", !n.read && "font-medium")}>
                {!n.read && <span className="mt-1.5 h-1.5 w-1.5 rounded-full bg-primary shrink-0" />}
                <span className={cn("text-sm", n.read && "text-muted-foreground")}>
                  {t(n.type, { name: n.actorName })}
                </span>
              </div>
            </DropdownMenuItem>
          ))}
        </div>
      </DropdownMenuContent>
    </DropdownMenu>
  );
}
