import { toast } from 'sonner';
import { trpc } from '@/lib/trpc';
import { useSubscriptionWithErrorHandling } from './useSubscriptionWithErrorHandling';

export interface LiveUpdateRule {
  /** Event type prefix to match, e.g. 'task:' or 'agent:' */
  prefix: string;
  /** tRPC query keys to invalidate when a matching event arrives */
  invalidate: string[];
}

/**
 * Opens a single `onEvent` SSE subscription and routes events to query invalidations
 * based on prefix-matching rules. Drops heartbeat events silently.
 *
 * Encapsulates error toast + reconnect config so pages don't duplicate boilerplate.
 */
export function useLiveUpdates(rules: LiveUpdateRule[]) {
  const utils = trpc.useUtils();

  return useSubscriptionWithErrorHandling(
    () => trpc.onEvent.useSubscription(undefined),
    {
      onData: (event) => {
        // Drop heartbeats and malformed events (missing type)
        if (!event?.type || event.type === '__heartbeat__') return;

        for (const rule of rules) {
          if (event.type.startsWith(rule.prefix)) {
            for (const key of rule.invalidate) {
              // eslint-disable-next-line @typescript-eslint/no-explicit-any
              void (utils as any)[key]?.invalidate();
            }
          }
        }
      },
      onError: (error) => {
        toast.error('Live updates disconnected. Refresh to reconnect.', {
          id: 'sub-error',
          duration: Infinity,
        });
        console.error('Live updates subscription error:', error);
      },
      onStarted: () => toast.dismiss('sub-error'),
      autoReconnect: true,
      maxReconnectAttempts: 5,
    },
  );
}
