'use client';

// One rAF loop reads audio.currentTime and writes a single CSS variable.
// Pauses on document.hidden and when the audio is paused (with a final
// flush to keep the bar in sync after the seek that triggered the pause).

import { useEffect } from 'react';

const VAR = '--p';

export function usePlayheadLoop(
  audio: HTMLAudioElement,
  el: HTMLElement | null,
  enabled = true,
): void {
  useEffect(() => {
    if (!enabled || !el) return;
    let raf = 0;
    let lastPct = -1;

    const writePct = () => {
      const dur = audio.duration;
      if (!Number.isFinite(dur) || dur <= 0) return;
      const pct = Math.max(0, Math.min(100, (audio.currentTime / dur) * 100));
      if (Math.abs(pct - lastPct) < 0.01) return;
      lastPct = pct;
      el.style.setProperty(VAR, `${pct.toFixed(2)}%`);
    };

    const tick = () => {
      if (typeof document !== 'undefined' && document.hidden) {
        raf = 0;
        return;
      }
      writePct();
      raf = requestAnimationFrame(tick);
    };

    const start = () => {
      if (raf) return;
      raf = requestAnimationFrame(tick);
    };
    const stop = () => {
      if (!raf) return;
      cancelAnimationFrame(raf);
      raf = 0;
      writePct();
    };

    if (!audio.paused) start();

    const onPlay = () => start();
    const onPauseOrEnd = () => stop();
    const onSeek = () => writePct();
    const onVisibility = () => {
      if (document.hidden) stop();
      else if (!audio.paused) start();
    };

    audio.addEventListener('play', onPlay);
    audio.addEventListener('pause', onPauseOrEnd);
    audio.addEventListener('ended', onPauseOrEnd);
    audio.addEventListener('seeked', onSeek);
    audio.addEventListener('timeupdate', writePct);
    document.addEventListener('visibilitychange', onVisibility);

    return () => {
      stop();
      audio.removeEventListener('play', onPlay);
      audio.removeEventListener('pause', onPauseOrEnd);
      audio.removeEventListener('ended', onPauseOrEnd);
      audio.removeEventListener('seeked', onSeek);
      audio.removeEventListener('timeupdate', writePct);
      document.removeEventListener('visibilitychange', onVisibility);
    };
  }, [audio, el, enabled]);
}
