// ============ SOUNDCLOUD WIDGET ADAPTER ============
// Plays SoundCloud tracks in-browser via the SoundCloud Widget API.
// These tracks run in "limited mode" — volume + crossfader work, but EQ/FX
// can't route through Web Audio (the Widget's audio is sandboxed in an iframe).
//
// Docs: https://developers.soundcloud.com/docs/api/html5-widget

const SoundCloudAdapter = (() => {
  let widgetScriptPromise = null;
  const widgets = {}; // side -> { iframe, widget, meta }

  function loadWidgetScript() {
    if (widgetScriptPromise) return widgetScriptPromise;
    widgetScriptPromise = new Promise((resolve, reject) => {
      if (window.SC?.Widget) return resolve();
      const s = document.createElement('script');
      s.src = 'https://w.soundcloud.com/player/api.js';
      s.onload = resolve;
      s.onerror = () => reject(new Error('Could not load SoundCloud Widget API'));
      document.head.appendChild(s);
    });
    return widgetScriptPromise;
  }

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

  // Fetch track metadata via SoundCloud's oEmbed endpoint (public, no auth, CORS-allowed)
  async function fetchOEmbed(url) {
    const resp = await fetch(`https://soundcloud.com/oembed?format=json&url=${encodeURIComponent(url)}`);
    if (!resp.ok) throw new Error(`SoundCloud oEmbed ${resp.status}`);
    return await resp.json();
    // returns { title, author_name, thumbnail_url, html, ... }
  }

  function isSoundCloudUrl(url) {
    if (!url) return false;
    try {
      const u = new URL(url.trim());
      return /(^|\.)soundcloud\.com$/.test(u.hostname) || /(^|\.)snd\.sc$/.test(u.hostname);
    } catch { return false; }
  }

  async function loadTrackMeta(url) {
    const meta = await fetchOEmbed(url);
    // Try to pull a thumbnail at better resolution
    const thumb = meta.thumbnail_url?.replace('-large.', '-t500x500.') || meta.thumbnail_url;
    return {
      title: meta.title || 'SoundCloud Track',
      artist: meta.author_name || 'SoundCloud',
      thumb,
      embedHtml: meta.html,
      url,
    };
  }

  // Create a Widget for a given side (a or b). Reuses if exists.
  async function attachWidget(side, trackUrl) {
    await loadWidgetScript();
    const container = getHiddenContainer();
    let w = widgets[side];

    // Build/replace iframe
    if (w?.iframe) {
      try { container.removeChild(w.iframe); } catch {}
    }
    const iframe = document.createElement('iframe');
    iframe.id = `__sc_iframe_${side}`;
    iframe.allow = 'autoplay';
    iframe.width = '100%';
    iframe.height = '166';
    iframe.scrolling = 'no';
    iframe.frameBorder = 'no';
    iframe.src = `https://w.soundcloud.com/player/?url=${encodeURIComponent(trackUrl)}&auto_play=false&visual=false&show_comments=false&show_user=false&show_reposts=false&buying=false&sharing=false&download=false&show_playcount=false&show_artwork=false&single_active=false`;
    container.appendChild(iframe);

    const widget = window.SC.Widget(iframe);
    await new Promise((resolve) => widget.bind(window.SC.Widget.Events.READY, resolve));

    const info = await new Promise((resolve) => widget.getCurrentSound(resolve));
    const duration = await new Promise((resolve) => widget.getDuration(resolve)); // ms

    w = { iframe, widget, duration: (duration || 0) / 1000, info, playing: false, onProgress: null, progressHandle: null };
    widgets[side] = w;

    // Progress polling (Widget doesn't emit time cleanly enough otherwise)
    w.progressHandle = setInterval(() => {
      if (!w.playing) return;
      widget.getPosition((pos) => {
        w.position = (pos || 0) / 1000;
        w.onProgress?.(w.position, w.duration);
      });
    }, 100);
    widget.bind(window.SC.Widget.Events.FINISH, () => {
      w.playing = false;
      w.position = w.duration;
      w.onProgress?.(w.duration, w.duration);
    });

    return w;
  }

  function play(side) {
    const w = widgets[side];
    if (!w) return false;
    w.widget.play();
    w.playing = true;
    return true;
  }
  function pause(side) {
    const w = widgets[side];
    if (!w) return;
    w.widget.pause();
    w.playing = false;
  }
  function seek(side, seconds) {
    const w = widgets[side];
    if (!w) return;
    w.widget.seekTo(Math.max(0, seconds * 1000));
    w.position = seconds;
  }
  function setVolume(side, v01) {
    const w = widgets[side];
    if (!w) return;
    // Widget volume is 0..100
    w.widget.setVolume(Math.max(0, Math.min(100, v01 * 100)));
  }
  function getCurrentTime(side) {
    return widgets[side]?.position || 0;
  }
  function getDuration(side) {
    return widgets[side]?.duration || 0;
  }
  function isPlaying(side) {
    return !!widgets[side]?.playing;
  }
  function onProgress(side, fn) {
    if (!widgets[side]) return;
    widgets[side].onProgress = fn;
  }
  function destroy(side) {
    const w = widgets[side];
    if (!w) return;
    clearInterval(w.progressHandle);
    try { w.iframe.parentNode?.removeChild(w.iframe); } catch {}
    delete widgets[side];
  }

  return {
    isSoundCloudUrl,
    loadTrackMeta,
    attachWidget,
    play, pause, seek,
    setVolume,
    getCurrentTime, getDuration, isPlaying,
    onProgress,
    destroy,
  };
})();

window.SoundCloudAdapter = SoundCloudAdapter;
