"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import { Tooltip } from "@/components/ui/tooltip";
import {
  loadAllNotifications,
  NOTIFICATIONS_FEED_KEY,
  NOTIFICATIONS_READ_STATE_KEY,
  prune,
  type Notification,
} from "@/lib/notifications/registry";
import { ACTIVITY_STORAGE_KEY } from "@/lib/activity/log";
import { NotificationsPanel } from "@/components/app/notifications-panel";

const RECONCILE_INTERVAL_MS = 60_000;

export function NotificationsBell() {
  const [open, setOpen] = useState(false);
  const [notifications, setNotifications] = useState<Notification[]>([]);
  const ref = useRef<HTMLDivElement>(null);

  const refresh = useCallback(() => {
    prune();
    setNotifications(loadAllNotifications());
  }, []);

  // Initial load + 60s reconcile tick. Defer the first refresh to a
  // separate task so React doesn't see a synchronous setState during
  // the effect body (react-hooks/set-state-in-effect lint rule).
  useEffect(() => {
    const init = setTimeout(refresh, 0);
    const id = setInterval(refresh, RECONCILE_INTERVAL_MS);
    return () => {
      clearTimeout(init);
      clearInterval(id);
    };
  }, [refresh]);

  // Cross-tab sync — re-pull when feed / read-state / activity changes elsewhere.
  useEffect(() => {
    function onStorage(e: StorageEvent) {
      if (
        e.key === NOTIFICATIONS_FEED_KEY ||
        e.key === NOTIFICATIONS_READ_STATE_KEY ||
        e.key === ACTIVITY_STORAGE_KEY ||
        e.key === null // localStorage cleared
      ) {
        refresh();
      }
    }
    window.addEventListener("storage", onStorage);
    return () => window.removeEventListener("storage", onStorage);
  }, [refresh]);

  // Outside-click + escape close.
  useEffect(() => {
    if (!open) return;
    function onClick(e: MouseEvent) {
      if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);
    }
    function onKey(e: KeyboardEvent) {
      if (e.key === "Escape") setOpen(false);
    }
    document.addEventListener("mousedown", onClick);
    document.addEventListener("keydown", onKey);
    return () => {
      document.removeEventListener("mousedown", onClick);
      document.removeEventListener("keydown", onKey);
    };
  }, [open]);

  const unread = notifications.filter((n) => !n.readAt).length;

  return (
    <div className="relative" ref={ref}>
      <Tooltip
        content={unread > 0 ? `${unread} unread notification${unread === 1 ? "" : "s"}` : "Notifications"}
      >
        <button
          type="button"
          onClick={() => setOpen((v) => !v)}
          aria-haspopup="menu"
          aria-expanded={open}
          aria-label={`Notifications${unread > 0 ? ` — ${unread} unread` : ""}`}
          className="relative inline-flex items-center justify-center rounded-md border bg-background px-2.5 py-1.5 hover:bg-accent transition-colors"
        >
          <span className="text-base" aria-hidden="true">
            🔔
          </span>
          {unread > 0 && (
            <span
              aria-hidden="true"
              className="absolute -top-1.5 -right-1.5 rounded-full bg-destructive text-destructive-foreground text-[10px] font-mono font-semibold px-1.5 py-0.5 min-w-[18px] text-center leading-none"
            >
              {unread > 99 ? "99+" : unread}
            </span>
          )}
        </button>
      </Tooltip>

      {open && (
        <div
          role="menu"
          className="absolute right-0 mt-2 rounded-md border bg-popover text-popover-foreground shadow-2xl z-50 overflow-hidden"
        >
          <NotificationsPanel
            notifications={notifications}
            onAfterRead={() => {
              refresh();
              setOpen(false);
            }}
          />
        </div>
      )}
    </div>
  );
}
