'use client';

/**
 * Tiny Web Audio helpers — no audio files needed. Sounds are synthesised so the
 * bundle stays small and there's nothing to download.
 */

let ctx: AudioContext | null = null;

function getCtx(): AudioContext | null {
  if (typeof window === 'undefined') return null;
  if (!ctx) {
    const AC = window.AudioContext || (window as any).webkitAudioContext;
    if (!AC) return null;
    ctx = new AC();
  }
  return ctx;
}

function tone(freq: number, start: number, duration: number, gain = 0.15, type: OscillatorType = 'sine') {
  const ac = getCtx();
  if (!ac) return;
  const osc = ac.createOscillator();
  const g = ac.createGain();
  osc.type = type;
  osc.frequency.setValueAtTime(freq, ac.currentTime + start);
  g.gain.setValueAtTime(0.0001, ac.currentTime + start);
  g.gain.exponentialRampToValueAtTime(gain, ac.currentTime + start + 0.02);
  g.gain.exponentialRampToValueAtTime(0.0001, ac.currentTime + start + duration);
  osc.connect(g);
  g.connect(ac.destination);
  osc.start(ac.currentTime + start);
  osc.stop(ac.currentTime + start + duration + 0.02);
}

/** Happy rising chime for a correct answer. */
export function playCorrect() {
  const ac = getCtx();
  if (ac?.state === 'suspended') ac.resume();
  tone(523.25, 0, 0.15); // C5
  tone(659.25, 0.1, 0.15); // E5
  tone(783.99, 0.2, 0.25); // G5
}

/** Gentle, non-scary "try again" blip for a wrong answer. */
export function playWrong() {
  const ac = getCtx();
  if (ac?.state === 'suspended') ac.resume();
  tone(311.13, 0, 0.18, 0.12, 'triangle');
  tone(233.08, 0.12, 0.22, 0.12, 'triangle');
}

/** Little celebratory arpeggio for finishing a lesson. */
export function playFinish() {
  const ac = getCtx();
  if (ac?.state === 'suspended') ac.resume();
  [523.25, 659.25, 783.99, 1046.5].forEach((f, i) => tone(f, i * 0.12, 0.2));
}
