'use client';

// Lazily creates an AnalyserNode bound to the player's <audio> via the cached
// MediaElementSourceNode, samples it at ~30 Hz into a Float32Array, and pushes
// frames into the LevelsStore. Only mounted by LiveWaveform / reactive cover.

import { useEffect } from 'react';
import { getAudioContext } from '../audio/audioContext';
import { getMediaElementSource } from '../audio/mediaElementSourceCache';
import type { LevelsStore } from '../store/createLevelsStore';

const FFT_SIZE = 1024;
const READ_INTERVAL_MS = 33;
const SMOOTHING = 0.8;

export function useAnalyser(audio: HTMLAudioElement, store: LevelsStore, enabled: boolean) {
  useEffect(() => {
    if (!enabled) return;
    let analyser: AnalyserNode | null = null;
    let interval: ReturnType<typeof setInterval> | null = null;
    let buffer = new Uint8Array(0);
    let normalized = new Float32Array(0);
    let cancelled = false;

    try {
      const ctx = getAudioContext();
      const source = getMediaElementSource(audio);
      analyser = ctx.createAnalyser();
      analyser.fftSize = FFT_SIZE;
      analyser.smoothingTimeConstant = SMOOTHING;
      source.connect(analyser);
      buffer = new Uint8Array(analyser.frequencyBinCount);
      normalized = new Float32Array(analyser.frequencyBinCount);
      store.setActive(true);

      const tick = () => {
        if (cancelled || !analyser) return;
        if (typeof document !== 'undefined' && document.hidden) return;
        analyser.getByteFrequencyData(buffer);
        for (let i = 0; i < buffer.length; i++) normalized[i] = buffer[i] / 255;
        store.set(normalized);
      };
      interval = setInterval(tick, READ_INTERVAL_MS);
    } catch {
      // Not supported in this environment; leave levels empty.
      store.setActive(false);
    }

    return () => {
      cancelled = true;
      if (interval) clearInterval(interval);
      if (analyser) {
        try {
          analyser.disconnect();
        } catch {
          // ignore
        }
      }
      store.setActive(false);
    };
  }, [audio, store, enabled]);
}
