/** Script execution complete sound presets (Web Audio API). */

export type ScriptCompleteSoundId = 'off' | 'beep_short' | 'beep_double' | 'chime_soft'

export const SCRIPT_COMPLETE_SOUND_OPTIONS: Array<{ value: ScriptCompleteSoundId; title: string }> = [
  { value: 'off', title: '关闭' },
  { value: 'beep_short', title: '短促单音' },
  { value: 'beep_double', title: '双音提示（默认）' },
  { value: 'chime_soft', title: '柔和三音' },
]

export const DEFAULT_SCRIPT_COMPLETE_SOUND: ScriptCompleteSoundId = 'beep_double'

const VALID_IDS = new Set(SCRIPT_COMPLETE_SOUND_OPTIONS.map(o => o.value))

export function normalizeScriptCompleteSound(raw: unknown): ScriptCompleteSoundId {
  const s = String(raw ?? '').trim().toLowerCase()
  if (VALID_IDS.has(s as ScriptCompleteSoundId)) {
    return s as ScriptCompleteSoundId
  }
  return DEFAULT_SCRIPT_COMPLETE_SOUND
}

function tone(
  ctx: AudioContext,
  freq: number,
  startAt: number,
  duration: number,
  gain = 0.08,
) {
  const osc = ctx.createOscillator()
  const g = ctx.createGain()
  osc.type = 'sine'
  osc.frequency.value = freq
  g.gain.value = gain
  osc.connect(g)
  g.connect(ctx.destination)
  osc.start(startAt)
  osc.stop(startAt + duration)
}

export function playScriptCompleteSoundById(mode: ScriptCompleteSoundId): void {
  if (mode === 'off') return
  try {
    const ctx = new AudioContext()
    const t0 = ctx.currentTime
    if (mode === 'beep_short') {
      tone(ctx, 880, t0, 0.12)
      return
    }
    if (mode === 'beep_double') {
      tone(ctx, 880, t0, 0.15)
      tone(ctx, 1174, t0 + 0.12, 0.2)
      return
    }
    if (mode === 'chime_soft') {
      tone(ctx, 523.25, t0, 0.1, 0.06)
      tone(ctx, 659.25, t0 + 0.1, 0.1, 0.06)
      tone(ctx, 783.99, t0 + 0.2, 0.14, 0.06)
    }
  } catch {
    /* non-critical */
  }
}
