// audio.jsx — bips (Web Audio) + voz (SpeechSynthesis) para o treino
const ZAudio = (() => {
  let ctx = null;

  function ensure() {
    if (!ctx) {
      try { ctx = new (window.AudioContext || window.webkitAudioContext)(); } catch (e) { ctx = null; }
    }
    if (ctx && ctx.state === 'suspended') ctx.resume();
    return ctx;
  }

  // tom genérico
  function tone(freq, dur = 0.15, type = 'sine', gain = 0.22) {
    const c = ensure();
    if (!c) return;
    const o = c.createOscillator();
    const g = c.createGain();
    o.type = type;
    o.frequency.value = freq;
    o.connect(g); g.connect(c.destination);
    const t = c.currentTime;
    g.gain.setValueAtTime(0.0001, t);
    g.gain.exponentialRampToValueAtTime(gain, t + 0.01);
    g.gain.exponentialRampToValueAtTime(0.0001, t + dur);
    o.start(t); o.stop(t + dur + 0.02);
  }

  // bips distintos
  const beepPrep     = () => tone(620, 0.10, 'sine', 0.16);       // preparação
  const beepExercise = () => tone(900, 0.12, 'sine', 0.20);       // contagem do exercício
  const beepRest     = () => tone(480, 0.12, 'triangle', 0.20);   // contagem do descanso
  const beepGo       = () => { tone(1180, 0.18, 'square', 0.20); }; // início do exercício
  function beepDone() {                                            // fim do treino (acorde)
    tone(660, 0.22, 'sawtooth', 0.18);
    setTimeout(() => tone(880, 0.22, 'sawtooth', 0.18), 110);
    setTimeout(() => tone(1175, 0.30, 'sawtooth', 0.18), 220);
  }

  // ---- voz ----
  let voices = [];
  function loadVoices() {
    try { voices = window.speechSynthesis ? window.speechSynthesis.getVoices() : []; } catch (e) { voices = []; }
  }
  if (window.speechSynthesis) {
    loadVoices();
    try { window.speechSynthesis.onvoiceschanged = loadVoices; } catch (e) {}
  }

  // target: 'f' (feminina) ou 'm' (masculina)
  function pickVoice(target) {
    loadVoices();
    const pt = voices.filter(v => /pt[-_]?br/i.test(v.lang)) ;
    const pool = pt.length ? pt : voices.filter(v => /^pt/i.test(v.lang));
    const search = (pool.length ? pool : voices);
    const female = /(luciana|maria|fernanda|joana|catarina|in[eê]s|vit[oó]ria|female|mulher|fem)/i;
    const male   = /(daniel|felipe|jo[aã]o|ricardo|ant[oô]nio|hugo|male|homem|masc)/i;
    const re = target === 'f' ? female : male;
    return search.find(v => re.test(v.name)) || search[0] || null;
  }

  // userSex: 'masc' | 'fem' | 'na'  → homem ouve voz feminina, mulher ouve voz masculina
  function speak(text, userSex) {
    if (!window.speechSynthesis) return;
    const target = userSex === 'fem' ? 'm' : 'f';
    try {
      const u = new SpeechSynthesisUtterance(text);
      const v = pickVoice(target);
      if (v) { u.voice = v; u.lang = v.lang; } else { u.lang = 'pt-BR'; }
      u.pitch = target === 'f' ? 1.3 : 0.75;  // reforça o timbre mesmo sem voz dedicada
      u.rate = 1.06;
      u.volume = 1;
      window.speechSynthesis.cancel();
      window.speechSynthesis.speak(u);
    } catch (e) {}
  }

  function stopVoice() { try { window.speechSynthesis && window.speechSynthesis.cancel(); } catch (e) {} }

  const NUM = ['', 'um', 'dois', 'três', 'quatro', 'cinco'];
  const numWord = (n) => NUM[n] || String(n);

  return { ensure, beepPrep, beepExercise, beepRest, beepGo, beepDone, speak, stopVoice, numWord };
})();

window.ZAudio = ZAudio;
