import { useStore } from './store'

let ctx: AudioContext | null = null

function getCtx(): AudioContext | null {
  if (ctx && ctx.state !== 'closed') return ctx
  try { ctx = new AudioContext() } catch { return null }
  return ctx
}

function isSoundEnabled(): boolean {
  return useStore.getState().narratorSettings.sounds
}

function tone(freq: number, duration: number, type: OscillatorType = 'sine', gain = 0.15) {
  if (!isSoundEnabled()) return
  const ac = getCtx()
  if (!ac) return
  if (ac.state === 'suspended') ac.resume()
  const osc = ac.createOscillator()
  const g = ac.createGain()
  osc.type = type
  osc.frequency.value = freq
  g.gain.value = gain
  g.gain.exponentialRampToValueAtTime(0.001, ac.currentTime + duration / 1000)
  osc.connect(g).connect(ac.destination)
  osc.start()
  osc.stop(ac.currentTime + duration / 1000)
}

export function playKeyClick() {
  tone(1200, 50, 'sine', 0.08)
}

export function playDelete() {
  tone(400, 50, 'sine', 0.08)
}

export function playComplete() {
  if (!isSoundEnabled()) return
  const ac = getCtx()
  if (!ac) return
  if (ac.state === 'suspended') ac.resume()
  const notes = [523, 659, 784]
  notes.forEach((freq, i) => {
    const osc = ac.createOscillator()
    const g = ac.createGain()
    osc.type = 'sine'
    osc.frequency.value = freq
    g.gain.value = 0.15
    const start = ac.currentTime + i * 0.1
    g.gain.exponentialRampToValueAtTime(0.001, start + 0.15)
    osc.connect(g).connect(ac.destination)
    osc.start(start)
    osc.stop(start + 0.15)
  })
}

export function playHint() {
  tone(660, 100, 'sine', 0.1)
}

export function playWordComplete() {
  if (!isSoundEnabled()) return
  const ac = getCtx()
  if (!ac) return
  if (ac.state === 'suspended') ac.resume()
  const notes = [587, 784]
  notes.forEach((freq, i) => {
    const osc = ac.createOscillator()
    const g = ac.createGain()
    osc.type = 'sine'
    osc.frequency.value = freq
    g.gain.value = 0.12
    const start = ac.currentTime + i * 0.1
    g.gain.exponentialRampToValueAtTime(0.001, start + 0.12)
    osc.connect(g).connect(ac.destination)
    osc.start(start)
    osc.stop(start + 0.12)
  })
}
