<script setup lang="ts">
import { usePlayer } from '~/composables/audio/player'
import { useQueue } from '~/composables/audio/queue'

import { useMouse, useWindowSize } from '@vueuse/core'
import { useGettext } from 'vue3-gettext'
import { computed, ref } from 'vue'
import { useStore } from '~/store'

import onKeyboardShortcut from '~/composables/onKeyboardShortcut'
import time from '~/utils/time'

// import TrackFavoriteIcon from '~/components/favorites/TrackFavoriteIcon.vue'
// import TrackPlaylistIcon from '~/components/playlists/TrackPlaylistIcon.vue'
import VolumeControl from './VolumeControl.vue'
import PlayerControls from './PlayerControls.vue'

const {
  LoopingMode,
  initializeFirstTrack,
  isPlaying,
  mute,
  volume,
  toggleLooping,
  looping,
  seekBy,
  seekTo,
  currentTime,
  duration,
  progress,
  bufferProgress,
  loading: isLoadingAudio
} = usePlayer()

const {
  playPrevious,
  playNext,
  queue,
  currentIndex,
  currentTrack,
  shuffle
} = useQueue()

const store = useStore()
const { $pgettext } = useGettext()

const toggleMobilePlayer = () => {
  store.commit('ui/queueFocused', ['queue', 'player'].includes(store.state.ui.queueFocused as string) ? null : 'player')
}

// Key binds
onKeyboardShortcut('e', toggleMobilePlayer)
onKeyboardShortcut('p', () => { isPlaying.value = !isPlaying.value })
onKeyboardShortcut('s', shuffle)
onKeyboardShortcut('q', () => store.dispatch('queue/clean'))
onKeyboardShortcut('m', mute)
onKeyboardShortcut('l', toggleLooping)
onKeyboardShortcut('f', () => store.dispatch('favorites/toggle', currentTrack.value?.id))
onKeyboardShortcut('escape', () => store.commit('ui/queueFocused', null))

onKeyboardShortcut(['shift', 'up'], () => (volume.value += 0.1), true)
onKeyboardShortcut(['shift', 'down'], () => (volume.value -= 0.1), true)

onKeyboardShortcut('right', () => seekBy(5), true)
onKeyboardShortcut(['shift', 'right'], () => seekBy(30), true)
onKeyboardShortcut('left', () => seekBy(-5), true)
onKeyboardShortcut(['shift', 'left'], () => seekBy(-30), true)

onKeyboardShortcut(['ctrl', 'shift', 'left'], playPrevious, true)
onKeyboardShortcut(['ctrl', 'shift', 'right'], playNext, true)

const labels = computed(() => ({
  audioPlayer: $pgettext('Sidebar/Player/Hidden text', 'Media player'),
  previous: $pgettext('Sidebar/Player/Icon.Tooltip', 'Previous track'),
  play: $pgettext('Sidebar/Player/Icon.Tooltip/Verb', 'Play'),
  pause: $pgettext('Sidebar/Player/Icon.Tooltip/Verb', 'Pause'),
  next: $pgettext('Sidebar/Player/Icon.Tooltip', 'Next track'),
  unmute: $pgettext('Sidebar/Player/Icon.Tooltip/Verb', 'Unmute'),
  mute: $pgettext('Sidebar/Player/Icon.Tooltip/Verb', 'Mute'),
  expandQueue: $pgettext('Sidebar/Player/Icon.Tooltip/Verb', 'Expand queue'),
  shuffle: $pgettext('Sidebar/Player/Icon.Tooltip/Verb', 'Shuffle your queue'),
  clear: $pgettext('Sidebar/Player/Icon.Tooltip/Verb', 'Clear your queue'),
  addArtistContentFilter: $pgettext('Sidebar/Player/Icon.Tooltip/Verb', 'Hide content from this artist…')
}))

const switchTab = () => {
  store.commit('ui/queueFocused', store.state.ui.queueFocused === 'player' ? 'queue' : 'player')
}

const progressBar = ref()
const touchProgress = (event: MouseEvent) => {
  const time = ((event.clientX - ((event.target as Element).closest('.progress')?.getBoundingClientRect().left ?? 0)) / progressBar.value.offsetWidth) * duration.value
  seekTo(time)
}

const { x } = useMouse({ type: 'client' })
const { width: screenWidth } = useWindowSize({ includeScrollbar: false })

initializeFirstTrack()

const loopingTitle = computed(() => {
  const mode = looping.value
  return mode === LoopingMode.None
    ? $pgettext('Sidebar/Player/Icon.Tooltip', 'Looping disabled. Click to switch to single-track looping.')
    : mode === LoopingMode.LoopTrack
      ? $pgettext('Sidebar/Player/Icon.Tooltip', 'Looping on a single track. Click to switch to whole queue looping.')
      : $pgettext('Sidebar/Player/Icon.Tooltip', 'Looping on whole queue. Click to disable looping.')
})
</script>

<template>
  <section
    v-if="currentTrack"
    role="complementary"
    class="player-wrapper ui bottom-player component-player"
    aria-labelledby="player-label"
  >
    <h1
      id="player-label"
      class="visually-hidden"
    >
      <translate translate-context="*/*/*">
        Audio player and controls
      </translate>
    </h1>
    <div
      class="ui inverted segment fixed-controls"
      @click.prevent.stop="toggleMobilePlayer"
    >
      <div
        ref="progressBar"
        :class="['ui', 'top attached', 'small', 'inverted', {'indicating': isLoadingAudio}, 'progress']"
        @click.prevent.stop="touchProgress"
      >
        <div
          class="buffer bar"
          :style="{ 'transform': `translateX(${bufferProgress - 100}%)` }"
        />
        <div
          class="position bar"
          :style="{ 'transform': `translateX(${progress - 100}%)` }"
        />
        <div
          class="seek bar"
          :style="{ 'transform': `translateX(${x / screenWidth * 100 - 100}%)` }"
        />
      </div>
      <div class="controls-row">
        <div class="controls track-controls queue-not-focused desktop-and-up">
          <div
            class="ui tiny image"
            @click.stop.prevent="$router.push({name: 'library.tracks.detail', params: {id: currentTrack.id }})"
          >
            <img
              ref="cover"
              alt=""
              :src="$store.getters['instance/absoluteUrl'](currentTrack.coverUrl)"
            >
          </div>
          <div
            class="middle aligned content ellipsis"
            @click.stop.prevent=""
          >
            <strong>
              <router-link
                class="small header discrete link track"
                :to="{name: 'library.tracks.detail', params: {id: currentTrack.id }}"
                @click.stop.prevent=""
              >
                {{ currentTrack.title }}
              </router-link>
            </strong>
            <div class="meta">
              <router-link
                class="discrete link"
                :to="{name: 'library.artists.detail', params: {id: currentTrack.artistId }}"
                @click.stop.prevent=""
              >
                {{ currentTrack.artistName }}
              </router-link>
              <template v-if="currentTrack.albumId !== -1">
                /
                <router-link
                  class="discrete link"
                  :to="{name: 'library.albums.detail', params: {id: currentTrack.albumId }}"
                  @click.stop.prevent=""
                >
                  {{ currentTrack.albumTitle }}
                </router-link>
              </template>
            </div>
          </div>
        </div>
        <div class="controls track-controls queue-not-focused desktop-and-below">
          <div class="ui tiny image">
            <img
              ref="cover"
              alt=""
              :src="$store.getters['instance/absoluteUrl'](currentTrack.coverUrl)"
            >
          </div>
          <div class="middle aligned content ellipsis">
            <strong>
              {{ currentTrack.title }}
            </strong>
            <div class="meta">
              {{ currentTrack.artistName }}
              <template v-if="currentTrack.albumId !== -1">
                / {{ currentTrack.albumTitle }}
              </template>
            </div>
          </div>
        </div>
        <div
          v-if="$store.state.auth.authenticated"
          class="controls desktop-and-up fluid align-right"
        >
          <!-- TODO (wvffle): Uncomment -->
          <!-- <track-favorite-icon
            class="control white"
            :track="currentTrack"
          />
          <track-playlist-icon
            class="control white"
            :track="currentTrack"
          />
          <button
            :class="['ui', 'really', 'basic', 'circular', 'icon', 'button', 'control']"
            :aria-label="labels.addArtistContentFilter"
            :title="labels.addArtistContentFilter"
            @click="$store.dispatch('moderation/hide', {type: 'artist', target: currentTrack.artist})"
          >
            <i :class="['eye slash outline', 'basic', 'icon']" />
          </button> -->
        </div>
        <player-controls class="controls queue-not-focused" />
        <div class="controls progress-controls queue-not-focused tablet-and-up small align-left">
          <div class="timer">
            <template v-if="!isLoadingAudio">
              <span
                class="start"
                @click.stop.prevent="seekTo(0)"
              >
                {{ time.parse(Math.round(currentTime)) }}
              </span>
              |
              <span class="total">{{ time.parse(Math.round(duration)) }}</span>
            </template>
          </div>
        </div>
        <div class="controls queue-controls when-queue-focused align-right">
          <div class="group">
            <volume-control class="expandable" />
            <button
              class="circular control button"
              :class="{ looping: looping !== LoopingMode.None }"
              :title="loopingTitle"
              :aria-label="loopingTitle"
              :disabled="!currentTrack"
              @click.prevent.stop="toggleLooping"
            >
              <i class="repeat icon">
                <span
                  v-if="looping !== LoopingMode.None"
                  class="ui circular tiny vibrant label"
                >
                  <template v-if="looping === LoopingMode.LoopTrack">1</template>
                  <template v-else-if="looping === LoopingMode.LoopQueue">&infin;</template>
                </span>
              </i>
            </button>

            <button
              class="circular control button"
              :disabled="queue.length === 0"
              :title="labels.shuffle"
              :aria-label="labels.shuffle"
              @click.prevent.stop="shuffle()"
            >
              <i :class="['ui', 'random', {'disabled': queue.length === 0}, 'icon']" />
            </button>
          </div>
          <div class="group">
            <div class="fake-dropdown">
              <button
                class="position circular control button desktop-and-up"
                aria-expanded="true"
                @click.stop="toggleMobilePlayer"
              >
                <i class="stream icon" />
                <translate
                  translate-context="Sidebar/Queue/Text"
                  :translate-params="{index: currentIndex + 1, length: queue.length}"
                >
                  %{ index } of %{ length }
                </translate>
              </button>
              <button
                class="position circular control button desktop-and-below"
                @click.stop="switchTab"
              >
                <i class="stream icon" />
                <translate
                  translate-context="Sidebar/Queue/Text"
                  :translate-params="{index: currentIndex + 1, length: queue.length}"
                >
                  %{ index } of %{ length }
                </translate>
              </button>

              <button
                v-if="$store.state.ui.queueFocused"
                class="circular control button close-control desktop-and-up"
                @click.stop="toggleMobilePlayer"
              >
                <i class="large down angle icon" />
              </button>
              <button
                v-else
                class="circular control button desktop-and-up"
                @click.stop="toggleMobilePlayer"
              >
                <i class="large up angle icon" />
              </button>
              <button
                v-if="$store.state.ui.queueFocused === 'player'"
                class="circular control button close-control desktop-and-below"
                @click.stop="switchTab"
              >
                <i class="large up angle icon" />
              </button>
              <button
                v-if="$store.state.ui.queueFocused === 'queue'"
                class="circular control button desktop-and-below"
                @click.stop="switchTab"
              >
                <i class="large down angle icon" />
              </button>
            </div>
            <button
              class="circular control button close-control desktop-and-below"
              @click.stop="$store.commit('ui/queueFocused', null)"
            >
              <i class="x icon" />
            </button>
          </div>
        </div>
      </div>
    </div>
  </section>
</template>
