import { player } from './store.svelte';

/**
 * Reactive smoothed playhead position in seconds. Mirrors Android's
 * `rememberSmoothPositionMs`: the underlying `player.position` updates
 * every ~250 ms (HTML audio `timeupdate` fires ~4 Hz), so reading it
 * directly snaps the scrubber forward in discrete steps. This helper
 * extrapolates per-frame between server ticks so the bar glides at
 * playback rate.
 *
 * The `$effect` re-runs whenever the canonical position / isPlaying /
 * duration changes, which both handles natural ticks (re-sync to the
 * new authoritative value) and seeks (instant jump on user action).
 * The rAF loop advances at wall-clock seconds since the segment
 * started, so as long as the canonical position keeps up with real
 * time the resync on each tick is sub-frame and invisible.
 *
 * Returns a `{ value }` accessor instead of a bare number so callers
 * can read it reactively inside components (Svelte's rune wiring
 * follows the property access).
 */
export function useSmoothPosition(): { readonly value: number } {
  let displayed = $state(player.position);

  $effect(() => {
    // Reset whenever the canonical position changes (server tick,
    // seek, track change) so we anchor to the truth.
    displayed = player.position;

    if (!player.isPlaying || player.duration <= 0) return;

    const startReal = performance.now();
    const startPos = player.position;
    const duration = player.duration;

    let rafId = 0;
    const tick = () => {
      const elapsed = (performance.now() - startReal) / 1000;
      displayed = Math.min(startPos + elapsed, duration);
      rafId = requestAnimationFrame(tick);
    };
    rafId = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(rafId);
  });

  return {
    get value() {
      return displayed;
    }
  };
}
