<template>
  <div class="slider-wrapper">
    <!-- Slot for passing any audio element -->
    <slot />
    <div class="slider">
      <input
        id="gain-control"
        v-model.number="volumeValue"
        type="range"
        min="0"
        max="1"
        step="0.001"
        data-toggle="tooltip"
        data-placement="top"
        :title="tooltipTitle"
        @wheel.prevent="changeVolumeOnWheel"
      >
      <span
        class="slider-progress-bar"
        :style="{ width: `${volumeValue * 100}%` }"
      />
    </div>
    <audio
      :id="title"
      ref="audioElement"
      hidden
      loop
      @loadedmetadata="handleUpdatedMetadata"
      @canplay="ready=true"
    />
  </div>
</template>

<script lang="ts">
import { ref, watch, onMounted } from 'vue'
import { useAudioStore } from '~/stores/audio'
import { useUserStore } from '~/stores/user'

export default {
  name: 'AudioElement',
  props: {
    src: {
      type: String,
      required: true
    },
    title: {
      type: String,
      default: 'Unknown'
    },
    tooltipTitle: {
      type: String,
      default: 'Change the volume by click, scroll or touch.',
      required: false
    },
    volume: {
      type: Number,
      default: 1
    }
  },
  emits: ['update:volume', 'update:loaded', 'update:playing', 'update:canplay'],
  setup (props, { emit }) {
    const audioStore = useAudioStore()
    const audioElement = ref<HTMLAudioElement | null>(null)
    const volumeValue = ref(props.volume)
    const ready = ref(false)

    const mute = () => {
      if ((audioElement.value instanceof HTMLAudioElement)) {
        const ae = audioElement.value
        ae.muted = true
      }
    }
    const play = async () => {
      try {
        const { $audioPrepared } = useNuxtApp()
        await $audioPrepared
        const sink = useUserStore().audioOutputDevice as MediaDeviceInfo
        audioElement.value?.setSinkId(sink.deviceId)
        if (audioElement.value instanceof HTMLAudioElement) {
          // set audio element to mute, will be anyway muted after connecting to the web audio graph
          audioElement.value.play()
        }
      } catch (error) {
        useNuxtApp().$logger.error('Oouh sorry! Error while setting up audio, please reload.', error)
      }
    }

    const pause = () => {
      audioElement.value?.pause()
    }

    const togglePlayPause = async () => {
      if (audioElement.value) {
        if (audioStore.playing) {
          await audioElement.value.play()
        } else {
          audioElement.value.pause()
        }
      }
    }
    watch(() => props.volume, (newValue) => {
      volumeValue.value = newValue
    })
    watch(() => audioStore.playing, async (newValue) => {
      if (newValue) {
        updateMediaSession()
        await togglePlayPause()
      } else {
        await togglePlayPause()
      }
    })

    watch(volumeValue, (newValue) => {
      if (audioElement.value) {
        audioElement.value.volume = newValue
        emit('update:volume', newValue) // Gib die Änderungen an die Elternkomponente weiter
      }
    })

    const changeVolumeOnWheel = (event:WheelEvent) => {
      // Adjust volume on wheel scroll
      const deltaY = event.deltaY
      if (deltaY < 0) {
        const volumeAdd = (Math.min(1, volumeValue.value + 0.02))
        volumeValue.value = volumeAdd
      } else {
        const volumeCut = (Math.max(0, volumeValue.value - 0.02))
        volumeValue.value = volumeCut
      }
    }

    const updateMediaSession = () => {
      try {
        const path = window.location.origin + '/images/scenery/' + props.title.toLowerCase() + '.jpg'
        // useNuxtApp().$logger.log(navigator.mediaSession.metadata)
        if (audioElement.value) {
          audioElement.value.controls = true
          navigator.mediaSession.metadata = new MediaMetadata({
            title: props.title,
            artist: 'mindboost',
            album: 'mindboost Originale',
            artwork: [
              { src: path, sizes: '192x192', type: 'image/jpeg' }
            ]
          })
        }
      } catch (e) {
        // useNuxtApp().$logger.error(e)
      }
    }

    const handleUpdatedMetadata = () => {
    // use the navigator for the soundscape.
      if (props.title !== 'Noise') {
        updateMediaSession()
      }
    }

    onMounted(() => {
      if (audioElement.value) {
        audioElement.value.src = props.src
        audioElement.value.volume = volumeValue.value
      }
    })

    onUnmounted(() => {
      audioElement.value = null
      volumeValue.value = 0
    })

    return {
      audioElement,
      ready,
      play,
      pause,
      handleUpdatedMetadata,
      volumeValue,
      togglePlayPause,
      changeVolumeOnWheel,
      updateMediaSession
    }
  }

}
</script>
<style>
.slider-wrapper{
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-bottom: 1.5em;
}

.slider {
  position: relative;
  width: 100%;
  margin: 1em auto;
}

.slider-icon {
  cursor: pointer;
}

@media only screen and (max-width: 576px) {
  .slider{
    max-width: 80%;
  }
}

.slider-progress-bar {
  position: absolute;
  height: 10px;
  background-color: #e9c046;
  border-top-left-radius: 5px;
  border-bottom-left-radius: 5px;
  border-radius: 5px;
  left: 0;
  z-index: 0;
}

/* Allgemeine Einstellungen für den Slider */
input[type="range"] {
  -webkit-appearance: none; /* Entfernt das Standard-Styling in Webkit-Browsern */
  appearance: none; /* Entfernt Standard-Styling in anderen Browsern */
  width: 100%;
  height: 10px;
  background: #fff;
  border-radius: 5px;
  outline: none;
  cursor: pointer;
  position: absolute;
  z-index:1;
  left: 0;
}

/* Styling für den Track in Webkit-Browsern */
input[type="range"]::-webkit-slider-runnable-track {
  height: 10px;
  background: transparent;
  border-radius: 5px;
  position: relative;
  z-index: 2;
}

/* Styling für den Thumb in Webkit-Browsern */
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  height: 20px;
  width: 20px;
  background: #fff;
  border-radius: 50%;
  margin-top: -5px;
  position: relative;
  z-index: 10;
  border: 2px solid #e9c046;
}

/* Styling für den Track in Firefox */
input[type="range"]::-moz-range-track {
  height: 10px;
  background: transparent;
  border-radius: 5px;
  position: relative;
  z-index: 1;
}

/* Styling für den Thumb in Firefox */
input[type="range"]::-moz-range-thumb {
  height: 20px;
  width: 20px;
  background-color: #e9c046;
  border: none;
  border-radius: 50%;
  position: relative;
  z-index: 1;
  border: 2px solid #e9c046;
  margin-top: -5px;
}

input[type="range"]::-moz-range-progress {
  height: 10px;
  background-color: #e9c046;
  border-radius: 5px;
}

/* Styling für den Track in Internet Explorer/Edge */
input[type="range"]::-ms-track {
  height: 10px;
  background: transparent;
  border-color: transparent;
  color: transparent;
  border-radius: 5px;
}

/* Styling für den Thumb in Internet Explorer/Edge */
input[type="range"]::-ms-thumb {
  height: 20px;
  width: 20px;
  background: #f5f5f5;
  border: none;
  border-radius: 50%;
  box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);
  position: relative;
  z-index: 2;
  border: 2px solid #e9c046;
}

/* Entfernt Ticks in IE */
input[type="range"]::-ms-ticks-after,
input[type="range"]::-ms-ticks-before {
  display: none;
}
</style>
