<template>
  <div>
    <h1>Test Fall 4</h1>
    <h3>Howler als Stream mit der HowlWebAudioBridge (createMediaElementSource)</h3>
    <KeyboardPlayHandler />
    <button @click="play">Play</button>
    <div v-if="false" id="statistics">
      {{ Object.keys(gains).length }}
      {{ Object.keys(nodes).length }}
    </div>
    <HowlWebAudioBridge
      :src="source[0]"
      :audio-context="audioContext"
      :on-ready="(node, howl) => registerAudioNode(node, howl, 63)"
    />
    <HowlWebAudioBridge
      :src="source[1]"
      :audio-context="audioContext"
      :on-ready="(node, howl) => registerAudioNode(node, howl, 125)"
    />
    <HowlWebAudioBridge
      :src="source[2]"
      :audio-context="audioContext"
      :on-ready="(node, howl) => registerAudioNode(node, howl, 250)"
    />
    <HowlWebAudioBridge
      :src="source[3]"
      :audio-context="audioContext"
      :on-ready="(node, howl) => registerAudioNode(node, howl, 500)"
    />
    <HowlWebAudioBridge
      :src="source[4]"
      :audio-context="audioContext"
      :on-ready="(node, howl) => registerAudioNode(node, howl, 1000)"
    />
    <HowlWebAudioBridge
      :src="source[5]"
      :audio-context="audioContext"
      :on-ready="(node, howl) => registerAudioNode(node, howl, 2000)"
    />
    <HowlWebAudioBridge
      :src="source[6]"
      :audio-context="audioContext"
      :on-ready="(node, howl) => registerAudioNode(node, howl, 4000)"
    />
    <HowlWebAudioBridge
      :src="source[7]"
      :audio-context="audioContext"
      :on-ready="(node, howl) => registerAudioNode(node, howl, 8000)"
    />
    <HowlWebAudioBridge
      :src="source[8]"
      :audio-context="audioContext"
      :on-ready="(node, howl) => registerAudioNode(node, howl, 16000)"
    />
  </div>
</template>

<script setup lang="ts">
import type { Logger } from 'pino'
import { useAudioStore } from '~/stores/audio'
import tracksConfig from '~/tracks.config'
import HowlWebAudioBridge from '~/components/Player/HowlWebAudioBridge.vue'
import KeyboardPlayHandler from '~/archive/components/KeyboardPlayHandler.vue'

const source = ref([tracksConfig['63_src'], tracksConfig['125_src'], tracksConfig['250_src'], tracksConfig['500_src'], tracksConfig['1000_src'], tracksConfig['2000_src'], tracksConfig['4000_src'], tracksConfig['8000_src'], tracksConfig['16000_src']])
const audioContext = ref(useAudioStore().getContext()as AudioContext)
const nodes = ref([] as Record<number, AudioNode>)
const gains = ref([] as Record<number, GainNode>)
const howls = ref([] as Array<Howl>)
const masterGain = ref(null as (GainNode | null))
const lastAction = audioContext.value.currentTime
const logger = useNuxtApp().$logger as Logger

const registerAudioNode = (node:AudioNode | null, howl: Howl| null, freq: number) => {
  if (howl) {
    logger.info('register new Node push it', howl.state)
    howls.value.push(howl)
    const mediaElement = (howl as any)._sounds[0]._node as HTMLAudioElement
    mediaElement.muted = false
    logger.info('mediaElement muted')
  }
  if (node) {
    const gainNode = node.context.createGain()
    const pannerNode = audioContext.value.createStereoPanner()
    pannerNode.pan.value = 1

    gainNode.gain.setValueAtTime(0, audioContext.value.currentTime)
    gainNode.gain.linearRampToValueAtTime(0.5, audioContext.value.currentTime + 2)
    const master = masterGain.value || useAudioStore().getMasterGainNoise()
    nodes.value[freq] = node
    gains.value[freq] = gainNode
    node.connect(gainNode)
    gainNode.connect(master)
    pannerNode.connect(master)

    logger.info('mediaElement nicht mehr gemutet')
    logger.info('AudioNode ready, but not connected to destination', { node })
    logger.info('Number of GainNodes', Object.keys(gains.value).length)
    logger.info('Number of AudioNodes', Object.keys(nodes.value).length)
  }
}

watch(() => useAudioStore().playing, // Überwache explizit den state
  (newState) => {
    if (newState) {
      play()
    } else {
      pause()
    }
  }
)

watch(() => lastAction, // Überwache explizit den state
  (lastTimestamp) => {
    if (lastTimestamp > 50) {
      play() // Overlay anzeigen
    } else {
      pause()
    }
  }
)

const pause = () => {
  logger.info('pause')
  const master = masterGain.value
  const currentTime = audioContext.value.currentTime
  // master?.gain.cancelScheduledValues(currentTime)
  master?.gain.linearRampToValueAtTime(0, currentTime + 5)
  const lastAction = currentTime
  howls.value.forEach((howl) => {
    howl.pause()
  }
  )
  master?.disconnect()
  // if (gainNode) {
  //   gainNode.connect(audioContext.value.destination)
  //   gainNode.gain.cancelScheduledValues(audioContext.value.currentTime)
  //   gainNode.gain.setValueAtTime(0, audioContext.value.currentTime)
  //   gainNode.gain.linearRampToValueAtTime(2, audioContext.value.currentTime + 4)
  // } else {
  //   logger.info('GAINNODE NOT CREATED WE WILL NOT START')
  // }
}

const play = () => {
  const newHowls = howls.value
  const master = masterGain.value || useAudioStore().getMasterGainNoise()
  logger.info('Start this', { newHowls })
  howls.value.forEach(async (howl) => {
    howl.play()
    logger.info('Start this', { newHowls })
    masterGain?.value?.gain.linearRampToValueAtTime(1, audioContext.value.currentTime + 3)
    const mediaElement = await (howl as any)._sounds[0]._node as HTMLAudioElement
    mediaElement.muted = false
  }
  )
  master.connect(audioContext.value.destination)
  // if (gainNode) {
  //   gainNode.connect(audioContext.value.destination)
  //   gainNode.gain.cancelScheduledValues(audioContext.value.currentTime)
  //   gainNode.gain.setValueAtTime(0, audioContext.value.currentTime)
  //   gainNode.gain.linearRampToValueAtTime(2, audioContext.value.currentTime + 4)
  // } else {
  //   logger.info('GAINNODE NOT CREATED WE WILL NOT START')
  // }
}
</script>
