/**
 * Bantokens Streaming — puente de datos para overlays de OBS.
 * Cada overlay (subtitles.html, socials.html, alerts.html) se suscribe a los tipos de mensaje que
 * le interesan. Los datos llegan por BroadcastChannel o window.postMessage con la forma:
 *   { channel: "bantokens-overlay", type: "caption" | "goal" | "tip" | "topFans" | "socials" | "room", payload: {...} }
 *
 * OBS Browser Source no comparte perfil con Chrome ni carga chrome-extension://, así que la fuente
 * real de estos mensajes debe ser una página abierta en el propio navegador (o un relay) que reenvíe
 * los eventos de la extensión hacia esta URL vía postMessage/BroadcastChannel. Sin esa fuente conectada,
 * cada overlay usa datos de muestra para poder previsualizarse solo.
 */
(function () {
  const CHANNEL_NAME = "bantokens-overlay";
  const listeners = new Map();

  function dispatch(type, payload) {
    const set = listeners.get(type);
    if (!set) return;
    set.forEach((fn) => {
      try {
        fn(payload);
      } catch (err) {
        console.error("[BantokensOverlay]", err);
      }
    });
  }

  function handleMessage(data) {
    if (!data || data.channel !== CHANNEL_NAME || !data.type) return;
    dispatch(data.type, data.payload);
    dispatch("__any__", data);
  }

  try {
    const bc = new BroadcastChannel(CHANNEL_NAME);
    bc.onmessage = (e) => handleMessage(e.data);
  } catch {
    // BroadcastChannel no disponible en este contexto
  }

  window.addEventListener("message", (e) => handleMessage(e.data));

  window.BantokensOverlay = {
    /** Suscribirse a un tipo de mensaje ("caption", "goal", "tip", "topFans", "socials", "room"). */
    on(type, fn) {
      if (!listeners.has(type)) listeners.set(type, new Set());
      listeners.get(type).add(fn);
      return () => listeners.get(type)?.delete(fn);
    },
    /** Si no llega ningún mensaje real en delayMs, ejecuta fn() con datos de muestra para previsualizar. */
    demo(delayMs, fn) {
      let received = false;
      const off = this.on("__any__", () => {
        received = true;
        off();
      });
      setTimeout(() => {
        if (!received) fn();
      }, delayMs);
    },
  };
})();
