'use client';

import { useCallback, useEffect, useRef, useState } from 'react';
import { Bell } from 'lucide-react';
import { useTranslations } from 'next-intl';
import { Link, useRouter } from '@/i18n/navigation';
import { notificationsApi } from '@/lib/api/notifications';
import { useRealtime } from '@/lib/realtime/RealtimeProvider';
import { NavBadgePill } from '@/components/ui/shared/NavBadgePill';
import { NotificationCard } from '@/components/ui/notifications/NotificationCard';
import type { UserNotificationItem } from '@/types/notifications';

const DROPDOWN_LIMIT = 10;

export function NotificationBell() {
  const t = useTranslations('notifications');
  const router = useRouter();
  const { lastNotification, unreadCount: liveUnread, setUnreadCount } = useRealtime();
  const [open, setOpen] = useState(false);
  const [items, setItems] = useState<UserNotificationItem[]>([]);
  const [unreadCount, setLocalUnread] = useState(0);
  const [loading, setLoading] = useState(false);
  const menuRef = useRef<HTMLDivElement>(null);

  const refreshUnread = useCallback(async () => {
    try {
      const res = await notificationsApi.inboxUnreadCount();
      const count = res.data.count;
      setLocalUnread(count);
      setUnreadCount(count);
    } catch {
      /* ignore */
    }
  }, [setUnreadCount]);

  const loadRecent = useCallback(async () => {
    setLoading(true);
    try {
      const res = await notificationsApi.listInbox({ limit: DROPDOWN_LIMIT });
      setItems(res.data.items);
    } catch {
      setItems([]);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    void refreshUnread();
  }, [refreshUnread]);

  useEffect(() => {
    if (typeof liveUnread === 'number') {
      setLocalUnread(liveUnread);
    }
  }, [liveUnread]);

  useEffect(() => {
    if (!lastNotification) return;
    setItems((prev) => {
      if (prev.some((item) => item.id === lastNotification.id)) return prev;
      return [lastNotification, ...prev].slice(0, DROPDOWN_LIMIT);
    });
  }, [lastNotification]);

  useEffect(() => {
    const onDocClick = (e: MouseEvent) => {
      if (menuRef.current && !menuRef.current.contains(e.target as Node)) {
        setOpen(false);
      }
    };
    document.addEventListener('mousedown', onDocClick);
    return () => document.removeEventListener('mousedown', onDocClick);
  }, []);

  useEffect(() => {
    if (open) {
      void loadRecent();
    }
  }, [open, loadRecent]);

  const handleSelect = async (item: UserNotificationItem) => {
    setOpen(false);
    try {
      if (!item.readAt) {
        await notificationsApi.markInboxRead(item.id);
        setItems((prev) =>
          prev.map((row) =>
            row.id === item.id ? { ...row, readAt: new Date().toISOString() } : row,
          ),
        );
        await refreshUnread();
      }
    } catch {
      /* still navigate */
    }
    router.push(item.href);
  };

  return (
    <div className="relative" ref={menuRef}>
      <button
        type="button"
        onClick={() => setOpen((value) => !value)}
        className="relative inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-[var(--radius-md)] border border-border/60 bg-background-secondary/80 text-text-primary hover:border-border-strong hover:bg-background-card/80 transition-colors"
        aria-label={t('bellAria')}
        aria-expanded={open}
        aria-haspopup="dialog"
      >
        <Bell className="h-[18px] w-[18px] icon-flat" />
        {unreadCount > 0 ? (
          <span className="absolute -top-1 -end-1">
            <NavBadgePill count={unreadCount} ariaLabel={t('unreadCount', { count: unreadCount })} />
          </span>
        ) : null}
      </button>

      {open ? (
        <div
          role="dialog"
          aria-label={t('dropdownTitle')}
          className="fixed inset-x-3 top-[4.75rem] z-[200] max-h-[min(70dvh,28rem)] overflow-hidden rounded-[var(--radius-md)] border border-border bg-background-secondary/95 shadow-lg backdrop-blur-sm sm:absolute sm:inset-x-auto sm:end-0 sm:top-auto sm:mt-2 sm:w-[min(22rem,calc(100vw-1.5rem))]"
        >
          <div className="flex items-center justify-between gap-2 border-b border-border/70 px-3 py-2">
            <p className="text-sm font-medium text-text-primary">{t('dropdownTitle')}</p>
            <Link
              href="/notifications"
              className="text-xs text-primary hover:underline shrink-0"
              onClick={() => setOpen(false)}
            >
              {t('viewAll')}
            </Link>
          </div>
          <div className="max-h-[min(calc(70dvh-2.75rem),24rem)] overflow-y-auto overscroll-contain p-2 space-y-1.5">
            {loading && items.length === 0 ? (
              <p className="text-xs text-text-muted px-2 py-3">{t('loading')}</p>
            ) : items.length === 0 ? (
              <p className="text-xs text-text-muted px-2 py-3">{t('empty')}</p>
            ) : (
              items.map((item) => (
                <NotificationCard
                  key={item.id}
                  item={item}
                  compact
                  onSelect={handleSelect}
                />
              ))
            )}
          </div>
        </div>
      ) : null}
    </div>
  );
}
