import { ondaDoAudio } from "./onda-do-audio";

/*
 * A forma de onda do som de um vídeo (a faixa "Som do vídeo" da linha do
 * tempo, como no CapCut), medida uma vez por arquivo: o mesmo arquivo que o
 * palco toca, já no cache do navegador. `null` = o arquivo não tem som.
 * Vídeo longo demais (mais de 10 min) fica sem desenho: medir pesaria.
 */

const prontas = new Map<string, number[] | null>();
const pedidas = new Map<string, Promise<number[] | null | undefined>>();

/** A onda já medida: number[] (tem som), null (sem som) ou undefined (ainda não sei). */
export function ondaJaMedida(src: string): number[] | null | undefined {
  return prontas.get(src);
}

/** Mede a onda (uma vez por arquivo). undefined = não deu para baixar agora (tenta de novo depois). */
export function ondaDoVideo(src: string, duracao: number): Promise<number[] | null | undefined> {
  if (prontas.has(src)) return Promise.resolve(prontas.get(src));
  if (duracao > 600) return Promise.resolve(undefined);
  const pedida = pedidas.get(src);
  if (pedida) return pedida;
  const nova = fetch(src)
    .then((r) => (r.ok ? r.arrayBuffer() : Promise.reject(new Error(String(r.status)))))
    .then(async (bruto) => {
      const som = await ondaDoAudio(bruto);
      const onda = som ? som.onda : null;
      prontas.set(src, onda);
      return onda;
    })
    .catch(() => undefined)
    .finally(() => pedidas.delete(src));
  pedidas.set(src, nova);
  return nova;
}
