// Single-active-player coordination, with optional cross-tab sync.
// Each Player instance registers an id and a `pause()` callback. When another
// player becomes active, all others get paused. Cross-tab via BroadcastChannel.

const CHANNEL = 'djangocfg-audioplayer:active';

type Listener = (activeId: string | null) => void;

let activeId: string | null = null;
let lastActiveId: string | null = null;
const listeners = new Set<Listener>();
const pausers = new Map<string, () => void>();

let channel: BroadcastChannel | null = null;
function getChannel(): BroadcastChannel | null {
  if (typeof BroadcastChannel === 'undefined') return null;
  if (channel) return channel;
  channel = new BroadcastChannel(CHANNEL);
  channel.addEventListener('message', (e) => {
    const next = typeof e.data === 'string' ? e.data : null;
    if (next === activeId) return;
    activeId = next;
    if (next) lastActiveId = next;
    for (const [id, pause] of pausers) {
      if (id !== next) pause();
    }
    for (const l of listeners) l(next);
  });
  return channel;
}

export function registerPlayer(id: string, pause: () => void): () => void {
  pausers.set(id, pause);
  return () => {
    pausers.delete(id);
    if (activeId === id) activeId = null;
  };
}

export function setActivePlayer(id: string | null): void {
  if (activeId === id) return;
  activeId = id;
  if (id) lastActiveId = id;
  for (const [pid, pause] of pausers) {
    if (pid !== id) pause();
  }
  for (const l of listeners) l(id);
  getChannel()?.postMessage(id);
}

export function getActivePlayer(): string | null {
  return activeId;
}

export function getLastActivePlayer(): string | null {
  return lastActiveId;
}

export function subscribeActivePlayer(cb: Listener): () => void {
  listeners.add(cb);
  getChannel(); // ensure channel hot
  return () => listeners.delete(cb);
}
