import { useEffect, useEffectEvent } from 'react';
import { researchBridge } from './researchBridge';
import type {
  ResearchGhostUpdateEvent,
  ResearchJobUpdateEvent,
  ResearchNoteUpdateEvent,
  ResearchWorkspaceUpdateEvent,
} from '../types/research';

interface UseResearchEventSubscriptionsArgs {
  workspaceId?: string;
  onWorkspaceUpdate?: (payload: ResearchWorkspaceUpdateEvent) => void;
  onNoteUpdate?: (payload: ResearchNoteUpdateEvent) => void;
  onGhostUpdate?: (payload: ResearchGhostUpdateEvent) => void;
  onJobUpdate?: (payload: ResearchJobUpdateEvent) => void;
}

export const useResearchEventSubscriptions = ({
  workspaceId,
  onWorkspaceUpdate,
  onNoteUpdate,
  onGhostUpdate,
  onJobUpdate,
}: UseResearchEventSubscriptionsArgs) => {
  const handleWorkspaceUpdate = useEffectEvent((payload: ResearchWorkspaceUpdateEvent) => {
    if (!workspaceId || payload.workspaceId === workspaceId) {
      onWorkspaceUpdate?.(payload);
    }
  });
  const handleNoteUpdate = useEffectEvent((payload: ResearchNoteUpdateEvent) => {
    if (!workspaceId || payload.workspaceId === workspaceId) {
      onNoteUpdate?.(payload);
    }
  });
  const handleGhostUpdate = useEffectEvent((payload: ResearchGhostUpdateEvent) => {
    if (!workspaceId || payload.workspaceId === workspaceId) {
      onGhostUpdate?.(payload);
    }
  });
  const handleJobUpdate = useEffectEvent((payload: ResearchJobUpdateEvent) => {
    if (!workspaceId || payload.workspaceId === workspaceId) {
      onJobUpdate?.(payload);
    }
  });

  useEffect(() => {
    let disposed = false;
    const unlisteners: Array<() => void> = [];

    void Promise.all([
      researchBridge.listenForWorkspaceUpdates(handleWorkspaceUpdate),
      researchBridge.listenForNoteUpdates(handleNoteUpdate),
      researchBridge.listenForGhostUpdates(handleGhostUpdate),
      researchBridge.listenForJobUpdates(handleJobUpdate),
    ]).then((listeners) => {
      if (disposed) {
        listeners.forEach((listener) => listener());
        return;
      }
      unlisteners.push(...listeners);
    });

    return () => {
      disposed = true;
      unlisteners.forEach((listener) => listener());
    };
  }, [
    handleGhostUpdate,
    handleJobUpdate,
    handleNoteUpdate,
    handleWorkspaceUpdate,
  ]);
};
