import { useEffect } from "react";
import { supabase } from "../lib/supabase";
import type { RealtimeChannel } from "@supabase/supabase-js";
import { useDevicesStore } from "../stores/devices";

/**
 * Realtime-Subscription auf `rebreak.user_devices` für den eingeloggten User.
 *
 * Trigger-Fall: Die Magic-Desktop-App (Mac/Windows) ruft serverseitig
 * /api/magic/register → neues UserDevice-INSERT. Diese Subscription lässt die
 * Geräte-Liste in den Settings sofort nachladen, ohne dass der User pullt.
 *
 * Spiegelt [[useProtectedDevicesRealtime]]: publication-only (keine RLS), wir
 * reagieren auf jedes Event und reloaden den Store — keine Abhängigkeit von
 * payload.old (REPLICA IDENTITY irrelevant).
 */
export function useUserDevicesRealtime(enabled: boolean = true) {
  useEffect(() => {
    if (!enabled) return;
    let channel: RealtimeChannel | null = null;
    let cancelled = false;
    let reconnectTimer: ReturnType<typeof setTimeout> | null = null;

    async function subscribe() {
      const { data } = await supabase.auth.getSession();
      const session = data.session;
      if (!session?.access_token || cancelled) return;

      const userId = session.user.id;

      channel = supabase
        .channel(`user-devices:${userId}:${Date.now()}`)
        .on(
          "postgres_changes",
          {
            event: "*",
            schema: "rebreak",
            table: "user_devices",
            filter: `user_id=eq.${userId}`,
          },
          () => {
            useDevicesStore.getState().loadDevices();
          },
        )
        .subscribe((status: string) => {
          if (status === "CHANNEL_ERROR" || status === "TIMED_OUT") {
            cleanup();
            if (reconnectTimer) clearTimeout(reconnectTimer);
            reconnectTimer = setTimeout(() => {
              if (!cancelled) subscribe();
            }, 3000);
          }
        });
    }

    function cleanup() {
      if (channel) {
        supabase.removeChannel(channel);
        channel = null;
      }
    }

    subscribe();

    return () => {
      cancelled = true;
      if (reconnectTimer) clearTimeout(reconnectTimer);
      cleanup();
    };
  }, [enabled]);
}
