import {
  NOTIFICATION_WS_EVENTS,
  NOTIFICATION_WS_NAMESPACE,
  type NotificationDto,
} from "@edr/types";
import { useQueryClient } from "@tanstack/react-query";
import { useEffect, useRef } from "react";
import { io } from "socket.io-client";

import { API_BASE_URL } from "@/constants/apiConfig";
import { AUTH_TOKEN_COOKIE, getCookie } from "@/auth/cookies";

import { NOTIFICATIONS_KEY, UNREAD_KEY } from "./useNotifications";

// The socket namespace lives at the server root, not under the `/api` REST
// prefix — strip a trailing `/api` if the base URL carries one.
const SOCKET_ORIGIN = String(API_BASE_URL ?? "").replace(/\/api\/?$/, "");

/**
 * Subscribes to live notification pushes for the signed-in staff user. New
 * items invalidate the cached lists + fire `onNew` (the host shows a rich
 * toast); unread-count pushes update the badge.
 */
export function useNotificationSocket(
  enabled: boolean,
  onNew?: (notification: NotificationDto) => void,
) {
  const qc = useQueryClient();
  const onNewRef = useRef(onNew);
  onNewRef.current = onNew;

  useEffect(() => {
    if (!enabled) return;
    const token = getCookie(AUTH_TOKEN_COOKIE);
    if (!token) return;

    const socket = io(`${SOCKET_ORIGIN}/${NOTIFICATION_WS_NAMESPACE}`, {
      auth: { token },
      transports: ["websocket"],
      withCredentials: true,
    });

    socket.on(NOTIFICATION_WS_EVENTS.NEW, (n: NotificationDto) => {
      qc.invalidateQueries({ queryKey: NOTIFICATIONS_KEY });
      qc.invalidateQueries({ queryKey: UNREAD_KEY });
      onNewRef.current?.(n);
    });

    socket.on(NOTIFICATION_WS_EVENTS.UNREAD_COUNT, (count: number) => {
      if (typeof count === "number") qc.setQueryData(UNREAD_KEY, count);
    });

    return () => {
      socket.off();
      socket.disconnect();
    };
  }, [enabled, qc]);
}
