import { useEffect, useState } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useServerFn } from "@tanstack/react-start";
import { useNavigate } from "@tanstack/react-router";
import { Dialog, DialogContent } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { listNotifications, markNotificationRead } from "@/lib/notifications.functions";
import { Megaphone } from "lucide-react";

const SEEN_KEY = "billsline.popup.seen";

type Row = {
  id: string;
  title: string;
  body: string | null;
  kind: string;
  read_at: string | null;
  metadata: { image_url?: string; popup?: boolean } | null;
};

/** Shows the newest unread announcement as a rich pop-up (image + message). */
export function AnnouncementPopup() {
  const qc = useQueryClient();
  const navigate = useNavigate();
  const fetchList = useServerFn(listNotifications);
  const markRead = useServerFn(markNotificationRead);
  const [open, setOpen] = useState(false);
  const [current, setCurrent] = useState<Row | null>(null);

  const { data } = useQuery({ queryKey: ["notifications"], queryFn: () => fetchList(), staleTime: 30_000 });

  useEffect(() => {
    const rows = (data ?? []) as unknown as Row[];
    const candidate = rows.find((n) => !n.read_at && (n.kind === "announcement" || n.metadata?.popup));
    if (!candidate) return;
    let seen: string[] = [];
    try {
      seen = JSON.parse(localStorage.getItem(SEEN_KEY) ?? "[]") as string[];
    } catch {
      seen = [];
    }
    if (seen.includes(candidate.id)) return;
    setCurrent(candidate);
    setOpen(true);
    localStorage.setItem(SEEN_KEY, JSON.stringify([candidate.id, ...seen].slice(0, 40)));
  }, [data]);

  if (!current) return null;
  const image = current.metadata?.image_url;

  const dismiss = () => {
    setOpen(false);
    void markRead({ data: { id: current.id } })
      .then(() => qc.invalidateQueries({ queryKey: ["notifications"] }))
      .catch(() => {});
  };

  return (
    <Dialog open={open} onOpenChange={(o) => (o ? setOpen(true) : dismiss())}>
      <DialogContent className="max-w-sm overflow-hidden p-0">
        {image ? (
          <img src={image} alt="" className="h-40 w-full object-cover" />
        ) : (
          <div className="grid h-24 place-items-center bg-gradient-primary">
            <Megaphone className="h-8 w-8 text-primary-foreground" />
          </div>
        )}
        <div className="space-y-2 px-4 pb-4">
          <h2 className="text-base font-bold leading-snug">{current.title}</h2>
          {current.body && <p className="line-clamp-4 text-sm text-muted-foreground">{current.body}</p>}
          <div className="flex gap-2 pt-1">
            <Button variant="outline" className="flex-1" onClick={dismiss}>
              Dismiss
            </Button>
            <Button
              className="flex-1"
              onClick={() => {
                const id = current.id;
                dismiss();
                void navigate({ to: "/app/notifications/$id", params: { id } });
              }}
            >
              Read more
            </Button>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );
}
