// ============ YOUTUBE IFRAME ADAPTER ============
// Fallback playback path for hosted environments where YouTube blocks backend
// extraction. This keeps YouTube links playable, but iframe streams cannot be
// routed through Web Audio, so tempo sync/EQ/FX are limited like SoundCloud.

const YouTubeAdapter = (() => {
  let apiPromise = null;
  const players = {};

  function loadApi() {
    if (apiPromise) return apiPromise;
    apiPromise = new Promise((resolve, reject) => {
      if (window.YT?.Player) return resolve();
      const prev = window.onYouTubeIframeAPIReady;
      window.onYouTubeIframeAPIReady = () => {
        try { prev?.(); } catch {}
        resolve();
      };
      const s = document.createElement('script');
      s.src = 'https://www.youtube.com/iframe_api';
      s.onerror = () => reject(new Error('Could not load YouTube player'));
      document.head.appendChild(s);
    });
    return apiPromise;
  }

  function getHiddenContainer() {
    let el = document.getElementById('__yt_widgets');
    if (!el) {
      el = document.createElement('div');
      el.id = '__yt_widgets';
      Object.assign(el.style, {
        position: 'fixed',
        left: '-10000px',
        top: '0',
        width: '240px',
        height: '135px',
        overflow: 'hidden',
        opacity: '0.01',
        pointerEvents: 'none',
      });
      document.body.appendChild(el);
    }
    return el;
  }

  function withTimeout(promise, ms, message) {
    let timer = null;
    return new Promise((resolve, reject) => {
      timer = setTimeout(() => reject(new Error(message)), ms);
      promise.then(
        (value) => { clearTimeout(timer); resolve(value); },
        (err) => { clearTimeout(timer); reject(err); },
      );
    });
  }

  function isYouTubeEmbedTrack(track) {
    return track?.source === 'youtube-embed';
  }

  async function attachPlayer(side, ytId) {
    if (!ytId) throw new Error('Missing YouTube video ID');
    await loadApi();
    destroy(side);

    const container = getHiddenContainer();
    const host = document.createElement('div');
    host.id = `__yt_player_${side}_${Date.now()}`;
    container.appendChild(host);

    const player = await withTimeout(new Promise((resolve, reject) => {
      const p = new window.YT.Player(host.id, {
        width: 240,
        height: 135,
        videoId: ytId,
        playerVars: {
          autoplay: 0,
          controls: 0,
          disablekb: 1,
          playsinline: 1,
          rel: 0,
          origin: window.location.origin,
        },
        events: {
          onReady: () => resolve(p),
          onError: () => reject(new Error('YouTube embed playback is unavailable for this video')),
        },
      });
    }), 15000, 'YouTube player timed out');

    const entry = {
      host,
      player,
      playing: false,
      duration: Number(player.getDuration?.() || 0),
      position: 0,
      onProgress: null,
      progressHandle: null,
    };
    players[side] = entry;
    entry.progressHandle = setInterval(() => {
      try {
        entry.duration = Number(player.getDuration?.() || entry.duration || 0);
        entry.position = Number(player.getCurrentTime?.() || 0);
        entry.onProgress?.(entry.position, entry.duration || 1);
      } catch {}
    }, 120);
    return entry;
  }

  function play(side) {
    const p = players[side];
    if (!p) return false;
    p.player.playVideo();
    p.playing = true;
    return true;
  }

  function pause(side) {
    const p = players[side];
    if (!p) return;
    p.player.pauseVideo();
    p.playing = false;
  }

  function seek(side, seconds) {
    const p = players[side];
    if (!p) return;
    p.player.seekTo(Math.max(0, seconds), true);
    p.position = seconds;
  }

  function setVolume(side, v01) {
    const p = players[side];
    if (!p) return;
    p.player.setVolume(Math.max(0, Math.min(100, v01 * 100)));
  }

  function isPlaying(side) {
    return !!players[side]?.playing;
  }

  function onProgress(side, fn) {
    if (players[side]) players[side].onProgress = fn;
  }

  function destroy(side) {
    const p = players[side];
    if (!p) return;
    clearInterval(p.progressHandle);
    try { p.player.destroy(); } catch {}
    try { p.host.parentNode?.removeChild(p.host); } catch {}
    delete players[side];
  }

  return {
    isYouTubeEmbedTrack,
    attachPlayer,
    play,
    pause,
    seek,
    setVolume,
    isPlaying,
    onProgress,
    destroy,
  };
})();

window.YouTubeAdapter = YouTubeAdapter;
