"use client";

import { useEffect } from "react";
import * as signalR from "@microsoft/signalr";
import { useLocale } from "next-intl";
import { useQueryClient } from "@tanstack/react-query";
import { useAuthStore } from "@/lib/stores/auth.store";
import { notify } from "@/lib/notify";
import { useNotifPrefs } from "@/lib/notifications/notification-prefs.store";
import { playSound } from "@/lib/notifications/sounds";
import { showDesktopNotification } from "@/lib/notifications/use-desktop-notifications";

type LiveOrder = {
  displayNumber?: number;
  tableNumber?: string | null;
  source?: string;
};

type CafeNotification = {
  id: string;
  type: string;
  title: string;
  body?: string | null;
  referenceId?: string | null;
  tableNumber?: string | null;
};

/**
 * Single source of truth for real-time alerts in the dashboard shell. Mounted once
 * (dashboard layout) so staff are alerted on ANY screen. For every persisted
 * café notification (new guest order, order ready, waiter call, platform broadcast)
 * it fires — each gated by the per-device preferences ([[notification-prefs.store]]):
 *   • a configurable sound,
 *   • an in-app toast,
 *   • a native OS/Windows popup when the tab is backgrounded.
 * Preferences are read via getState() inside the handler so changing them never
 * tears down and rebuilds the SignalR connection.
 */
export function useOrderAlerts() {
  const cafeId = useAuthStore((s) => s.user?.cafeId);
  const locale = useLocale();
  const qc = useQueryClient();

  useEffect(() => {
    if (!cafeId) return;

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

    let stopped = false;

    const severityFor = (type: string) => {
      if (type === "table_call_waiter") return notify.warning;
      if (type === "guest_order_ready") return notify.success;
      return notify.info;
    };

    // Persisted notifications are the canonical alert trigger (guest order placed /
    // ready, waiter call, admin broadcast). Staff-created POS orders do NOT create
    // one, so they correctly stay silent.
    connection.on("NotificationReceived", (n: CafeNotification | null) => {
      if (!n) return;
      const prefs = useNotifPrefs.getState();

      if (prefs.soundEnabled) playSound(prefs.soundId, prefs.volume);
      if (prefs.toastEnabled) {
        severityFor(n.type)(n.title, { description: n.body ?? undefined });
      }
      showDesktopNotification({
        title: n.title,
        body: n.body ?? undefined,
        tag: n.referenceId ?? n.id,
      });

      void qc.invalidateQueries({ queryKey: ["notifications", cafeId] });
    });

    // Real-time board refresh nudge (no alert here — guest orders are alerted via
    // NotificationReceived above; this also covers silent staff POS orders).
    connection.on("OrderCreated", (_order: LiveOrder | null) => {
      void qc.invalidateQueries({ queryKey: ["kds"] });
      void qc.invalidateQueries({ queryKey: ["orders"] });
      void qc.invalidateQueries({ queryKey: ["pos"] });
    });

    void connection
      .start()
      .then(() => {
        if (!stopped) return connection.invoke("JoinCafe", cafeId);
      })
      .catch(() => {
        // connection/auth failed — alerts simply won't fire; no UI breakage
      });

    return () => {
      stopped = true;
      void connection.stop();
    };
  }, [cafeId, locale, qc]);
}
