import { useEventListener } from '@vueuse/core'

export default function useAudioContext(audioTrack: Ref<MediaStreamTrack | undefined>) {
  const ctx = new (window.AudioContext || window.webkitAudioContext)()

  const stream = new MediaStream()

  const sourceNode = shallowRef<MediaStreamAudioSourceNode>()
  const gainNode = ctx.createGain()

  let hackExecuted = false

  watch(audioTrack, (track, prevTrack) => {
    if (prevTrack)
      stream.removeTrack(prevTrack)

    if (!track)
      return

    stream.addTrack(track)

    if (!hackExecuted) {
      const audioEl = new Audio()
      audioEl.srcObject = stream
      audioEl.muted = true
      hackExecuted = true
    }

    sourceNode.value = ctx.createMediaStreamSource(stream)

    connect()
  }, { immediate: true })

  useEventListener(document, 'click', async () => {
    if (ctx.state === 'suspended') {
      await ctx.resume()
    }

    connect()
  }, { once: true })

  function connect() {
    if (!sourceNode.value || ctx.state === 'suspended')
      return

    sourceNode.value.connect(gainNode)
    gainNode.connect(ctx.destination)

    ctx.resume()
  }

  function setGain(value: number) {
    gainNode.gain.value = value
  }

  return {
    setGain,
  }
}
