// Audio player — minimal custom player that matches the site's editorial style.
// Replaces the default <audio controls> chrome with a round play button,
// a waveform-style progress display, and a mono tabular time readout.
//
// Multiple players coexist; whenever one starts, others auto-pause.

// Deterministic pseudo-random waveform shape seeded by the audio URL,
// so the bars look the same every render for the same file.
function buildWaveformBars(src, count) {
  const seed = String(src || "")
    .split("")
    .reduce((s, c) => ((s * 31) + c.charCodeAt(0)) >>> 0, 5381);
  const bars = [];
  for (let i = 0; i < count; i++) {
    const x = i / Math.max(1, count - 1);
    // Mix three sine layers for an organic, varied shape
    const w =
      Math.sin((i + seed) * 0.42) * 0.45 +
      Math.sin((i + seed * 7) * 0.13) * 0.35 +
      Math.cos((i + seed * 3) * 0.71) * 0.20;
    // Soft envelope so the first/last bars taper off slightly
    const envelope = Math.sin(x * Math.PI) ** 0.4;
    const h = (0.32 + Math.abs(w) * 0.68) * (0.55 + 0.45 * envelope);
    bars.push(Math.max(0.14, Math.min(1, h)));
  }
  return bars;
}

function AudioPlayer({ src, dense, barCount }) {
  const audioRef = React.useRef(null);
  const [playing, setPlaying]         = React.useState(false);
  const [duration, setDuration]       = React.useState(0);
  const [currentTime, setCurrentTime] = React.useState(0);
  const [seeking, setSeeking]         = React.useState(false);

  // Wire up native <audio> events
  React.useEffect(() => {
    const a = audioRef.current;
    if (!a) return;
    const onPlay = () => {
      setPlaying(true);
      // Auto-pause the previously-playing player (if any) so only one runs at a time
      if (window.__currentAudio && window.__currentAudio !== a) {
        try { window.__currentAudio.pause(); } catch (e) {}
      }
      window.__currentAudio = a;
    };
    const onPause = () => setPlaying(false);
    const onEnded = () => { setPlaying(false); a.currentTime = 0; setCurrentTime(0); };
    const onTime  = () => { if (!seeking) setCurrentTime(a.currentTime); };
    const onMeta  = () => setDuration(Number.isFinite(a.duration) ? a.duration : 0);
    a.addEventListener("play",  onPlay);
    a.addEventListener("pause", onPause);
    a.addEventListener("ended", onEnded);
    a.addEventListener("timeupdate",     onTime);
    a.addEventListener("loadedmetadata", onMeta);
    a.addEventListener("durationchange", onMeta);
    return () => {
      a.removeEventListener("play",  onPlay);
      a.removeEventListener("pause", onPause);
      a.removeEventListener("ended", onEnded);
      a.removeEventListener("timeupdate",     onTime);
      a.removeEventListener("loadedmetadata", onMeta);
      a.removeEventListener("durationchange", onMeta);
      if (window.__currentAudio === a) window.__currentAudio = null;
    };
  }, [seeking]);

  const toggle = () => {
    const a = audioRef.current;
    if (!a) return;
    if (a.paused) a.play().catch(err => console.warn("Audio play blocked:", err));
    else a.pause();
  };

  // Seek by clicking or dragging the waveform
  const trackRef = React.useRef(null);
  const setTimeFromEvent = (e) => {
    const a    = audioRef.current;
    const trk  = trackRef.current;
    if (!a || !trk || !duration) return;
    const rect = trk.getBoundingClientRect();
    const clientX = "clientX" in e ? e.clientX : (e.touches?.[0]?.clientX ?? 0);
    const x    = clientX - rect.left;
    const pct  = Math.max(0, Math.min(1, x / rect.width));
    a.currentTime = pct * duration;
    setCurrentTime(pct * duration);
  };
  const onPointerDown = (e) => {
    setSeeking(true);
    setTimeFromEvent(e);
    e.preventDefault();
    const move = (ev) => setTimeFromEvent(ev);
    const up   = () => {
      setSeeking(false);
      window.removeEventListener("pointermove", move);
      window.removeEventListener("pointerup",   up);
    };
    window.addEventListener("pointermove", move);
    window.addEventListener("pointerup",   up);
  };

  const progress = duration > 0 ? Math.max(0, Math.min(1, currentTime / duration)) : 0;

  const fmt = (t) => {
    if (!Number.isFinite(t)) return "—:—";
    const m = Math.floor(t / 60);
    const s = Math.floor(t % 60);
    return `${m}:${String(s).padStart(2, "0")}`;
  };

  return (
    <div className={`audio-player ${dense ? "audio-player--dense" : ""}`}>
      <audio ref={audioRef} src={src} preload="metadata" />
      <button
        type="button"
        className={`audio-play ${playing ? "playing" : ""}`}
        onClick={toggle}
        aria-label={playing ? "Pause" : "Play"}
      >
        {playing ? (
          <svg width="10" height="11" viewBox="0 0 10 11" aria-hidden="true">
            <rect x="0" y="0" width="3" height="11" fill="currentColor" />
            <rect x="7" y="0" width="3" height="11" fill="currentColor" />
          </svg>
        ) : (
          <svg width="9" height="11" viewBox="0 0 9 11" aria-hidden="true" style={{ marginLeft: 1 }}>
            <path d="M0 0L9 5.5L0 11V0Z" fill="currentColor" />
          </svg>
        )}
      </button>

      <div
        ref={trackRef}
        className={`audio-track ${playing ? "playing" : ""}`}
        onPointerDown={onPointerDown}
        role="slider"
        aria-valuemin={0}
        aria-valuemax={duration || 0}
        aria-valuenow={currentTime}
        aria-label="Seek position"
      >
        <div className="audio-rail">
          <div className="audio-fill" style={{ width: `${progress * 100}%` }} />
        </div>
      </div>

      <div className="audio-time mono-sm">
        <span>{fmt(currentTime)}</span>
        <span className="audio-time-sep">/</span>
        <span className="audio-time-total">{fmt(duration)}</span>
      </div>
    </div>
  );
}

window.AudioPlayer = AudioPlayer;
