import { createFileRoute, Link } from "@tanstack/react-router";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { useServerFn } from "@tanstack/react-start";
import { Bell, CheckCheck, ChevronRight } from "lucide-react";
import { listNotifications, markAllNotificationsRead } from "@/lib/notifications.functions";
import { formatDate } from "@/lib/format";
import { cn } from "@/lib/utils";

export const Route = createFileRoute("/app/notifications")({
  head: () => ({
    meta: [
      { title: "Notifications — Billsline" },
      { name: "description", content: "All your Billsline alerts, offers and transaction updates in one place." },
      { property: "og:title", content: "Notifications — Billsline" },
      { property: "og:description", content: "All your Billsline alerts, offers and transaction updates in one place." },
    ],
  }),
  component: NotificationsPage,
});

type Row = {
  id: string;
  title: string;
  body: string | null;
  severity: string;
  read_at: string | null;
  created_at: string;
  metadata: Record<string, unknown> | null;
};

function NotificationsPage() {
  const qc = useQueryClient();
  const fetchList = useServerFn(listNotifications);
  const markAll = useServerFn(markAllNotificationsRead);
  const { data = [], isPending } = useQuery({ queryKey: ["notifications"], queryFn: () => fetchList() });
  const items = data as unknown as Row[];
  const unread = items.filter((n) => !n.read_at).length;

  const allMut = useMutation({
    mutationFn: () => markAll(),
    onSuccess: () => qc.invalidateQueries({ queryKey: ["notifications"] }),
  });

  return (
    <div className="space-y-3 p-3 pb-8">
      <div className="flex items-center justify-between">
        <h1 className="flex items-center gap-2 text-lg font-bold">
          <Bell className="h-5 w-5 text-primary" /> Notifications
        </h1>
        {unread > 0 && (
          <button onClick={() => allMut.mutate()} className="flex items-center gap-1 text-xs font-semibold text-primary">
            <CheckCheck className="h-3.5 w-3.5" /> Mark all read
          </button>
        )}
      </div>

      {isPending ? (
        <p className="py-10 text-center text-sm text-muted-foreground">Loading…</p>
      ) : items.length === 0 ? (
        <p className="py-16 text-center text-sm text-muted-foreground">You're all caught up.</p>
      ) : (
        <ul className="space-y-2">
          {items.map((n) => {
            const image = (n.metadata as { image_url?: string } | null)?.image_url;
            return (
              <li key={n.id}>
                <Link
                  to="/app/notifications/$id"
                  params={{ id: n.id }}
                  className={cn(
                    "flex items-center gap-3 rounded-2xl bg-card p-3 shadow-card ring-1 ring-border/40 transition active:scale-[0.99]",
                    !n.read_at && "ring-primary/40",
                  )}
                >
                  {image ? (
                    <img src={image} alt="" loading="lazy" className="h-12 w-12 shrink-0 rounded-xl object-cover" />
                  ) : (
                    <span className="grid h-12 w-12 shrink-0 place-items-center rounded-xl bg-primary/10">
                      <Bell className="h-5 w-5 text-primary" />
                    </span>
                  )}
                  <div className="min-w-0 flex-1">
                    <div className="flex items-center gap-2">
                      <span className="truncate text-sm font-semibold">{n.title}</span>
                      {!n.read_at && <span className="h-2 w-2 shrink-0 rounded-full bg-primary" />}
                    </div>
                    {n.body && <p className="line-clamp-2 text-xs text-muted-foreground">{n.body}</p>}
                    <p className="mt-0.5 text-[10px] text-muted-foreground">{formatDate(n.created_at)}</p>
                  </div>
                  <ChevronRight className="h-4 w-4 shrink-0 text-muted-foreground" />
                </Link>
              </li>
            );
          })}
        </ul>
      )}
    </div>
  );
}
