import { useEffect, useState } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useServerFn } from "@tanstack/react-start";
import { Link } from "@tanstack/react-router";
import { Bell, Check, CheckCheck } from "lucide-react";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import { Button } from "@/components/ui/button";
import { ScrollArea } from "@/components/ui/scroll-area";
import { supabase } from "@/integrations/supabase/client";
import {
  listNotifications,
  markAllNotificationsRead,
  markNotificationRead,
} from "@/lib/notifications.functions";

export function NotificationBell() {
  const qc = useQueryClient();
  const fetchList = useServerFn(listNotifications);
  const doMark = useServerFn(markNotificationRead);
  const doMarkAll = useServerFn(markAllNotificationsRead);

  const q = useQuery({
    queryKey: ["notifications"],
    queryFn: () => fetchList({ data: undefined as never }),
    refetchInterval: 60_000,
  });

  const [open, setOpen] = useState(false);

  useEffect(() => {
    let userId: string | null = null;
    supabase.auth.getUser().then(({ data }) => {
      userId = data.user?.id ?? null;
    });
    const channel = supabase
      .channel("notifications-realtime")
      .on(
        "postgres_changes",
        { event: "INSERT", schema: "public", table: "notifications" },
        (payload) => {
          const row = payload.new as { user_id?: string };
          if (userId && row.user_id === userId) {
            qc.invalidateQueries({ queryKey: ["notifications"] });
          }
        },
      )
      .subscribe();
    return () => {
      supabase.removeChannel(channel);
    };
  }, [qc]);

  const unread = q.data?.filter((n) => !n.read_at).length ?? 0;

  async function mark(id: string) {
    await doMark({ data: { id } }).catch(() => {});
    qc.invalidateQueries({ queryKey: ["notifications"] });
  }

  async function markAll() {
    await doMarkAll({ data: undefined as never }).catch(() => {});
    qc.invalidateQueries({ queryKey: ["notifications"] });
  }

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <Button variant="ghost" size="icon" className="relative">
          <Bell className="h-4 w-4" />
          {unread > 0 && (
            <span className="absolute right-1 top-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-primary px-1 text-[10px] font-semibold text-primary-foreground">
              {unread > 99 ? "99+" : unread}
            </span>
          )}
          <span className="sr-only">Notifications</span>
        </Button>
      </PopoverTrigger>
      <PopoverContent align="end" className="w-80 p-0">
        <div className="flex items-center justify-between border-b p-3">
          <div className="text-sm font-semibold">Notifications</div>
          {unread > 0 && (
            <Button variant="ghost" size="sm" onClick={markAll}>
              <CheckCheck className="mr-1 h-3.5 w-3.5" /> Mark all read
            </Button>
          )}
        </div>
        <ScrollArea className="max-h-96">
          {q.isLoading && (
            <div className="p-4 text-center text-xs text-muted-foreground">Loading…</div>
          )}
          {q.data?.length === 0 && (
            <div className="p-8 text-center text-sm text-muted-foreground">
              You're all caught up.
            </div>
          )}
          <ul className="divide-y">
            {q.data?.map((n) => (
              <li
                key={n.id}
                className={`flex items-start gap-3 p-3 text-sm ${
                  !n.read_at ? "bg-primary/5" : ""
                }`}
              >
                <div className="mt-1 h-2 w-2 shrink-0 rounded-full bg-primary/70" />
                <div className="min-w-0 flex-1">
                  <div className="font-medium">{n.title}</div>
                  {n.body && (
                    <div className="mt-0.5 text-xs text-muted-foreground line-clamp-2">
                      {n.body}
                    </div>
                  )}
                  <div className="mt-1 text-[10px] uppercase tracking-wide text-muted-foreground">
                    {new Date(n.created_at).toLocaleString()}
                  </div>
                </div>
                {!n.read_at && (
                  <button
                    onClick={() => mark(n.id)}
                    className="rounded-md p-1 text-muted-foreground hover:bg-muted"
                    aria-label="Mark read"
                  >
                    <Check className="h-3.5 w-3.5" />
                  </button>
                )}
              </li>
            ))}
          </ul>
        </ScrollArea>
        <div className="border-t p-2">
          <Button asChild variant="ghost" size="sm" className="w-full">
            <Link to="/notifications" onClick={() => setOpen(false)}>
              View all
            </Link>
          </Button>
        </div>
      </PopoverContent>
    </Popover>
  );
}
