// fetch + OfflineAudioContext + bucketize. See ADR-002 / research 02.
// Uses a low-sample-rate mono context to keep memory bounded.

import { bucketize } from '../utils/bucketize';

const SAMPLE_RATE = 22_050;
const DEFAULT_BUCKETS = 1800;

type WebkitWindow = typeof window & {
  webkitOfflineAudioContext?: typeof OfflineAudioContext;
};

function getOfflineCtor(): typeof OfflineAudioContext {
  const w = window as WebkitWindow;
  const Ctor = w.OfflineAudioContext ?? w.webkitOfflineAudioContext;
  if (!Ctor) throw new Error('OfflineAudioContext is not supported');
  return Ctor;
}

export async function decodePeaks(
  src: string,
  buckets: number = DEFAULT_BUCKETS,
  signal?: AbortSignal,
): Promise<Float32Array> {
  const response = await fetch(src, { signal, credentials: 'same-origin' });
  if (!response.ok) {
    throw new Error(`Failed to fetch audio for peaks (${response.status})`);
  }
  const arr = await response.arrayBuffer();
  const Ctor = getOfflineCtor();
  // Length must be ≥ 1; the actual length doesn't matter for decodeAudioData.
  const ctx = new Ctor(1, 1, SAMPLE_RATE);
  const audio = await ctx.decodeAudioData(arr);
  const channel = audio.getChannelData(0);
  return bucketize(channel, buckets);
}
