"use client";

import {
  useQuery,
  useMutation,
  useQueryClient,
  type InfiniteData,
  useInfiniteQuery,
} from "@tanstack/react-query";
import { api } from "@/lib/api";
import type {
  NotificationInboxList,
  NotificationInboxItem,
} from "@alqove/api-client";

export type NotificationCategory = "orders" | "shipping" | "payouts" | "system";

export const NOTIFICATION_KEYS = {
  unreadCount: ["notifications", "unread-count"] as const,
  list: (filter: "all" | "unread", category: NotificationCategory | "all") =>
    ["notifications", "list", filter, category] as const,
};

const POLL_INTERVAL_MS = 60_000;

export function useUnreadCount() {
  return useQuery({
    queryKey: NOTIFICATION_KEYS.unreadCount,
    queryFn: async () => {
      const res = await api.notifications.unreadCount();
      return res.data.unread_count;
    },
    refetchInterval: POLL_INTERVAL_MS,
    refetchOnWindowFocus: true,
    staleTime: 30_000,
  });
}

export function useNotifications(
  filter: "all" | "unread" = "all",
  category: NotificationCategory | "all" = "all",
) {
  return useInfiniteQuery<NotificationInboxList>({
    queryKey: NOTIFICATION_KEYS.list(filter, category),
    initialPageParam: 1,
    queryFn: ({ pageParam }) =>
      api.notifications.list({
        filter,
        ...(category !== "all" ? { category } : {}),
        page: pageParam as number,
        per_page: 20,
      }),
    getNextPageParam: (lastPage) =>
      lastPage.meta.current_page < lastPage.meta.last_page
        ? lastPage.meta.current_page + 1
        : undefined,
  });
}

export function useMarkNotificationRead() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (id: string) => api.notifications.markRead(id),
    onMutate: async (id: string) => {
      await qc.cancelQueries({ queryKey: ["notifications"] });

      qc.setQueryData<number | undefined>(NOTIFICATION_KEYS.unreadCount, (prev) =>
        typeof prev === "number" ? Math.max(0, prev - 1) : prev,
      );

      for (const filter of ["all", "unread"] as const) {
        qc.setQueryData<InfiniteData<NotificationInboxList> | undefined>(
          NOTIFICATION_KEYS.list(filter, "all"),
          (prev) => {
            if (!prev) return prev;
            return {
              ...prev,
              pages: prev.pages.map((page) => ({
                ...page,
                data: page.data.map((n): NotificationInboxItem =>
                  n.id === id && n.read_at === null
                    ? { ...n, read_at: new Date().toISOString() }
                    : n,
                ),
              })),
            };
          },
        );
      }
    },
    onSettled: () => {
      qc.invalidateQueries({ queryKey: ["notifications"] });
    },
  });
}

export function useMarkAllNotificationsRead() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: () => api.notifications.markAllRead(),
    onSuccess: () => {
      qc.setQueryData(NOTIFICATION_KEYS.unreadCount, 0);
      qc.invalidateQueries({ queryKey: ["notifications"] });
    },
  });
}
