/*
  O som de mensagem.

  O sistema ja tinha dois sons: um aviso comum e o do dinheiro entrando. Este e
  o terceiro e precisa ser reconhecivel de longe — duas notas curtas subindo,
  como em qualquer aplicativo de mensagem, e nao o mesmo bipe de tudo.

  Navegador nao deixa tocar som antes de a pessoa mexer na pagina. Por isso o
  contexto e criado uma vez, reaproveitado, e o primeiro toque acontece so
  depois do primeiro clique — silencio e melhor do que erro no console.
*/

let contexto: AudioContext | null = null;

function pegarContexto() {
  if (typeof window === "undefined") return null;
  const Fabrica =
    window.AudioContext ||
    (window as typeof window & { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;
  if (!Fabrica) return null;
  if (!contexto) contexto = new Fabrica();
  return contexto;
}

export async function tocarSomDeMensagem() {
  const audio = pegarContexto();
  if (!audio) return;

  if (audio.state === "suspended") {
    try {
      await audio.resume();
    } catch {
      return;
    }
  }

  const notas = [
    { frequencia: 587.33, inicio: 0, duracao: 0.09, volume: 0.1 },
    { frequencia: 880, inicio: 0.085, duracao: 0.16, volume: 0.13 },
  ];

  notas.forEach((nota) => {
    const oscilador = audio.createOscillator();
    const ganho = audio.createGain();
    oscilador.type = "sine";
    oscilador.frequency.setValueAtTime(nota.frequencia, audio.currentTime + nota.inicio);
    ganho.gain.setValueAtTime(0.0001, audio.currentTime + nota.inicio);
    ganho.gain.exponentialRampToValueAtTime(nota.volume, audio.currentTime + nota.inicio + 0.012);
    ganho.gain.exponentialRampToValueAtTime(0.0001, audio.currentTime + nota.inicio + nota.duracao);
    oscilador.connect(ganho);
    ganho.connect(audio.destination);
    oscilador.start(audio.currentTime + nota.inicio);
    oscilador.stop(audio.currentTime + nota.inicio + nota.duracao + 0.02);
  });
}

/* Destrava o som no primeiro toque da pessoa na tela. */
export function prepararSom() {
  if (typeof window === "undefined") return;
  const destravar = () => {
    const audio = pegarContexto();
    void audio?.resume().catch(() => undefined);
  };
  window.addEventListener("pointerdown", destravar, { once: true });
  window.addEventListener("keydown", destravar, { once: true });
}
