'use client';

import { useEffect, useState } from 'react';
import { Bell } from 'lucide-react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';

import { Button } from '@/components/ui/button';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Separator } from '@/components/ui/separator';
import { apiFetch } from '@/lib/api/client';
import { useNotifications } from '@/hooks/use-notifications';
import { NotificationItem } from './notification-item';

interface NotificationListResponse {
  data: Array<{
    id: string;
    type: string;
    title: string;
    description: string | null;
    link: string | null;
    isRead: boolean;
    createdAt: Date;
  }>;
  total: number;
}

export function NotificationBell() {
  const { unreadCount } = useNotifications();
  const queryClient = useQueryClient();
  // Track popover open state so we only fire the list fetch when the user
  // actually opens the bell. Without this, an instance of NotificationBell
  // mounted alongside <Inbox /> would populate the same ['notifications',
  // 'list'] cache key without the gating Inbox carefully applies, defeating
  // Inbox's enabled-on-open optimization.
  const [open, setOpen] = useState(false);

  const { data, isLoading } = useQuery<NotificationListResponse>({
    queryKey: ['notifications', 'list'],
    queryFn: () => apiFetch('/api/v1/notifications?limit=20'),
    staleTime: 30_000,
    enabled: open,
  });

  const markReadMutation = useMutation({
    mutationFn: (notificationId: string) =>
      apiFetch(`/api/v1/notifications/${notificationId}`, { method: 'PATCH' }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['notifications'] });
    },
  });

  const markAllReadMutation = useMutation({
    mutationFn: () => apiFetch('/api/v1/notifications/read-all', { method: 'POST' }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['notifications'] });
    },
  });

  const notifications = data?.data ?? [];

  // Auto-mark-as-read on display: when the dropdown opens and lists land,
  // POST /read-all so the badge clears once the user has actually seen the
  // items. Individual rows still link out - the auto-clear here is the
  // "I've seen these" gesture; the per-row mark-read action stays
  // available for selective dismissal in the inbox page.
  useEffect(() => {
    if (!open || isLoading) return;
    if (notifications.some((n) => !n.isRead)) {
      markAllReadMutation.mutate();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [open, isLoading, notifications.length]);

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <Button variant="ghost" size="icon" className="relative" aria-label="Notifications">
          <Bell className="h-5 w-5" aria-hidden />
          {unreadCount > 0 && (
            <span
              key={unreadCount}
              className="absolute -top-0.5 -right-0.5 flex h-4 w-4 items-center justify-center rounded-full bg-gradient-brand text-xs font-bold text-white shadow-sm ring-2 ring-background animate-badge-pop"
            >
              {unreadCount > 99 ? '99+' : unreadCount}
            </span>
          )}
        </Button>
      </PopoverTrigger>
      <PopoverContent align="end" className="w-80 p-0">
        {/* Header */}
        <div className="flex items-center justify-between px-4 py-3">
          <h4 className="text-sm font-semibold">Notifications</h4>
          {unreadCount > 0 && (
            <Button
              variant="ghost"
              size="sm"
              className="h-auto p-0 text-xs text-muted-foreground hover:text-foreground"
              onClick={() => markAllReadMutation.mutate()}
              disabled={markAllReadMutation.isPending}
            >
              Mark all read
            </Button>
          )}
        </div>
        <Separator />

        {/* Notification list */}
        <ScrollArea className="max-h-[400px]">
          {isLoading ? (
            <div className="flex items-center justify-center py-8 text-sm text-muted-foreground">
              Loading...
            </div>
          ) : notifications.length === 0 ? (
            <div className="flex flex-col items-center justify-center py-8 text-sm text-muted-foreground">
              <Bell className="mb-2 h-8 w-8 opacity-30" />
              No notifications
            </div>
          ) : (
            <div className="divide-y">
              {notifications.map((notification) => (
                <NotificationItem
                  key={notification.id}
                  notification={notification}
                  onMarkRead={(id) => markReadMutation.mutate(id)}
                />
              ))}
            </div>
          )}
        </ScrollArea>
      </PopoverContent>
    </Popover>
  );
}
