'use client';

import * as React from 'react';
import { useQueryClient } from '@tanstack/react-query';
import { adminClient } from '@/lib/api';

type LiveEvent = {
  id?: string;
  event?: string;
  data?: unknown;
  timestamp?: number;
};

/**
 * Single SSE subscription with reconnect + exponential backoff.
 * Invalidates React Query caches on relevant events.
 */
export function useAdminEvents(enabled = true) {
  const queryClient = useQueryClient();
  const [connected, setConnected] = React.useState(false);
  const [lastEvent, setLastEvent] = React.useState<LiveEvent | null>(null);

  React.useEffect(() => {
    if (!enabled || typeof window === 'undefined') return;

    let cancelled = false;
    let unsubscribe: (() => void) | undefined;
    let attempt = 0;
    let timer: ReturnType<typeof setTimeout> | undefined;

    const invalidateFor = (ev: LiveEvent) => {
      const type = String(ev.event || '');
      if (
        type.includes('message') ||
        type.includes('delivery') ||
        type === 'message_updated' ||
        type === 'delivery_updated'
      ) {
        void queryClient.invalidateQueries({ queryKey: ['messages'] });
        void queryClient.invalidateQueries({ queryKey: ['stats'] });
        void queryClient.invalidateQueries({ queryKey: ['insights'] });
        void queryClient.invalidateQueries({ queryKey: ['logs'] });
      }
      if (type.includes('provider') || type.includes('health') || type === 'audit_event') {
        void queryClient.invalidateQueries({ queryKey: ['providers'] });
        void queryClient.invalidateQueries({ queryKey: ['stats'] });
      }
      if (type.includes('application') || type.includes('app_') || type === 'audit_event') {
        void queryClient.invalidateQueries({ queryKey: ['applications'] });
      }
    };

    const connect = () => {
      if (cancelled) return;
      unsubscribe = adminClient.subscribeEvents(
        (ev) => {
          attempt = 0;
          setConnected(true);
          setLastEvent(ev);
          invalidateFor(ev);
        },
        () => {
          setConnected(false);
          if (cancelled) return;
          const delay = Math.min(30_000, 1000 * 2 ** attempt);
          attempt += 1;
          timer = setTimeout(connect, delay);
        },
      );
    };

    connect();

    return () => {
      cancelled = true;
      setConnected(false);
      if (timer) clearTimeout(timer);
      unsubscribe?.();
    };
  }, [enabled, queryClient]);

  return { connected, lastEvent };
}
