'use client';

/**
 * useAudioBus — Global audio exclusivity via Zustand store.
 *
 * Ensures only one audio player plays at a time across the entire page.
 * No provider needed — singleton store, works anywhere in the tree.
 *
 * Also integrates with @djangocfg/ui-tools AudioPlayer automatically
 * (wired into useHybridAudio).
 *
 * @example
 * const { announce } = useAudioBus('my-player-id', () => pause());
 *
 * // When playback starts:
 * announce(); // all other players will pause
 */

import { useEffect, useRef, useCallback } from 'react';
import { create } from 'zustand';

// =============================================================================
// Store
// =============================================================================

interface AudioBusStore {
  /** ID of the currently active (playing) player, null if none */
  activeId: string | null;
  setActiveId: (id: string | null) => void;
}

export const useAudioBusStore = create<AudioBusStore>((set) => ({
  activeId: null,
  setActiveId: (id) => set({ activeId: id }),
}));

// =============================================================================
// Hook
// =============================================================================

export interface UseAudioBusReturn {
  /** Broadcast: this player is now playing — all others should stop */
  announce: () => void;
  /** Release: this player stopped (clears activeId if it was ours) */
  release: () => void;
}

/**
 * @param playerId  Stable unique ID for this player instance
 * @param onStop    Called when another player announces — should pause this player
 */
export function useAudioBus(playerId: string, onStop: () => void): UseAudioBusReturn {
  const onStopRef = useRef(onStop);
  onStopRef.current = onStop;

  const setActiveId = useAudioBusStore((s) => s.setActiveId);

  // Subscribe to store changes — if another player becomes active, stop this one
  useEffect(() => {
    return useAudioBusStore.subscribe((state) => {
      if (state.activeId !== null && state.activeId !== playerId) {
        onStopRef.current();
      }
    });
  }, [playerId]);

  const announce = useCallback(() => {
    setActiveId(playerId);
  }, [playerId, setActiveId]);

  const release = useCallback(() => {
    useAudioBusStore.setState((s) => s.activeId === playerId ? { activeId: null } : s);
  }, [playerId]);

  return { announce, release };
}
