"use client";

import { useCallback, useEffect } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import * as signalR from "@microsoft/signalr";
import { useRouter } from "@/i18n/routing";
import {
  fetchNotifications,
  markNotificationsRead,
  type CafeNotification,
} from "@/lib/api/notifications";
import { useAuthStore } from "@/lib/stores/auth.store";
import { notify } from "@/lib/notify";

type UseNotificationsFeedOptions = {
  unreadOnly?: boolean;
  limit?: number;
  /** Show toast when a new guest order notification arrives (topbar). */
  enableToasts?: boolean;
};

type OpenNotificationOptions = {
  /** Navigate to KDS/tables after marking read (notifications page only). */
  navigate?: boolean;
};

export function useNotificationsFeed(options: UseNotificationsFeedOptions = {}) {
  const { unreadOnly = false, limit = 50, enableToasts = false } = options;
  const cafeId = useAuthStore((s) => s.user?.cafeId);
  const router = useRouter();
  const qc = useQueryClient();

  const queryKey = ["notifications", cafeId, unreadOnly] as const;

  const { data, isLoading, isFetching, refetch } = useQuery({
    queryKey,
    queryFn: () => fetchNotifications(cafeId!, unreadOnly, limit),
    enabled: !!cafeId,
    refetchInterval: 60_000,
  });

  const refresh = useCallback(() => {
    if (!cafeId) return;
    void qc.invalidateQueries({ queryKey: ["notifications", cafeId] });
  }, [qc, cafeId]);

  useEffect(() => {
    if (!cafeId) return;
    const token = localStorage.getItem("meezi_access_token");
    const baseUrl = process.env.NEXT_PUBLIC_API_URL ?? "https://localhost:7208";
    const connection = new signalR.HubConnectionBuilder()
      .withUrl(`${baseUrl}/hubs/kds`, { accessTokenFactory: () => token ?? "" })
      .withAutomaticReconnect()
      .build();

    connection
      .start()
      .then(() => connection.invoke("JoinCafe", cafeId))
      .catch(() => undefined);

    connection.on("NotificationReceived", (n: CafeNotification) => {
      refresh();
      if (enableToasts) {
        if (n.type === "table_call_waiter") {
          notify.warning(n.title, { description: n.body ?? undefined });
        } else if (n.type === "guest_order_new") {
          notify.info(n.title, { description: n.body ?? undefined });
        }
      }
    });
    connection.on("OrderCreated", refresh);

    return () => {
      void connection.stop();
    };
  }, [cafeId, refresh, enableToasts]);

  const openNotification = useCallback(
    async (n: CafeNotification, opts: OpenNotificationOptions = {}) => {
      if (!cafeId) return;
      if (!n.isRead) await markNotificationsRead(cafeId, { ids: [n.id] });
      refresh();
      if (!opts.navigate) return;
      if (n.referenceId) router.push("/kds");
      else if (n.type.startsWith("guest_order")) router.push("/tables");
    },
    [cafeId, refresh, router]
  );

  const markAllRead = useCallback(async () => {
    if (!cafeId) return;
    await markNotificationsRead(cafeId, { all: true });
    refresh();
  }, [cafeId, refresh]);

  return {
    cafeId,
    items: data?.items ?? [],
    unreadCount: data?.unreadCount ?? 0,
    isLoading,
    isFetching,
    refetch,
    refresh,
    openNotification,
    markAllRead,
  };
}
