import { ref, readonly } from 'vue'

const VOLUME_KEY = 'fa_voice_volume'

// Shared volume across all instances — persisted to localStorage per device
const _volume = ref<number>(parseFloat(localStorage.getItem(VOLUME_KEY) ?? '1.0'))

export function useVoiceAudio() {
  const playing = ref(false)
  const isSupported = typeof AudioContext !== 'undefined' || typeof (window as unknown as Record<string, unknown>).webkitAudioContext !== 'undefined'

  let audioCtx: AudioContext | null = null
  let currentSource: AudioBufferSourceNode | null = null

  function _getCtx(): AudioContext {
    if (!audioCtx || audioCtx.state === 'closed') {
      const Ctx = window.AudioContext ?? (window as unknown as Record<string, typeof AudioContext>).webkitAudioContext
      audioCtx = new Ctx()
    }
    return audioCtx
  }

  async function play(blob: Blob): Promise<void> {
    stop()
    const ctx = _getCtx()
    if (ctx.state === 'suspended') await ctx.resume()

    const arrayBuffer = await blob.arrayBuffer()
    const audioBuffer = await ctx.decodeAudioData(arrayBuffer)

    const source = ctx.createBufferSource()
    source.buffer = audioBuffer

    const gain = ctx.createGain()
    gain.gain.value = _volume.value
    source.connect(gain)
    gain.connect(ctx.destination)

    currentSource = source
    playing.value = true

    return new Promise<void>((resolve) => {
      source.onended = () => {
        playing.value = false
        currentSource = null
        resolve()
      }
      source.start(0)
    })
  }

  function stop(): void {
    if (currentSource) {
      try { currentSource.stop() } catch { /* already stopped */ }
      currentSource = null
    }
    playing.value = false
  }

  return {
    playing: readonly(playing),
    volume: _volume,
    isSupported,
    play,
    stop,
  }
}

export function setVoiceVolume(v: number) {
  _volume.value = Math.max(0, Math.min(1, v))
  localStorage.setItem(VOLUME_KEY, String(_volume.value))
}
