<template>
  <div>
    <b-modal
      ref="modalPlaylistSelector"
      :title="$t('playlistSelector.title')"
      :cancel-title="$t('cancel')"
      size="lg"
    >
      <p v-if="loaded">
        {{ $t('playlistSelector.currentPlaylistLabel') }}:

        <span v-if="timeslot === null || timeslot.playlist_id === null">
          <i
            ><small>{{ $t('noneSetFeminine') }}</small></i
          >
        </span>
        <span v-else>
          {{ timeslot.playlist_id }}<br />
          <span v-if="currentPlaylistDescription">
            {{ $t('showMeta.description') }}: <b>{{ currentPlaylistDescription }}</b></span
          >
        </span>
      </p>

      <div v-if="loaded">
        <div v-if="playlists.length">
          <b-table ref="playlistsTable" striped :fields="playlistsTableFields" :items="playlists">
            <!-- Column: Entries
                        This column displays the number of entries of the playlist.
                        -->
            <template #cell(entries)="data">
              <span
                v-b-tooltip.html="playlistToolTip(data.value)"
                class="tw-underline hover:tw-no-underline tw-cursor-help"
              >
                {{ $t('playlistTable.items', { smart_count: data.value.length }) }}
              </span>
            </template>

            <!-- Column: Duration
                        This column displays the number of entries of the playlist.
                        -->
            <template #cell(duration)="data">
              <span :class="{ 'is-mismatched': isMismatchedLength(data) }">
                {{ playlistDuration(data.item) }}
                <abbr v-if="isMismatchedLength(data)" :title="title(data)"> (?) </abbr>
              </span>
            </template>

            <!-- Column: Actions
                        This column displays the available buttons for actions the user can
                        take on this playlist (e.g. editing and deleting).
                        -->
            <template #cell(actions)="data">
              <b-button-group size="sm">
                <b-button
                  v-if="data.item.id !== timeslot.playlist_id"
                  variant="info"
                  @click="choose(data)"
                >
                  {{ $t('playlistTable.assign') }}
                </b-button>
                <b-button v-else variant="danger" @click="choose(null)">
                  {{ $t('playlistTable.unset') }}
                </b-button>
              </b-button-group>
            </template>
          </b-table>
        </div>

        <!-- If no playlists are available -->
        <div v-else class="tw-mb-4">
          {{ $t('playlistSelector.noPlaylistsAvailable') }}
        </div>
      </div>

      <div v-else>
        <img src="/assets/radio.gif" :alt="$t('loading')" />
      </div>

      <div>
        <div class="tw-space-x-2">
          <b-button :to="'files'">
            {{ $t('playlistSelector.goToFiles') }}
          </b-button>

          <b-button v-if="!audioUpload" v-model="audioFile" @click="toggleAudioUpload">
            {{ $t('playlistSelector.uploadAudio') }}
          </b-button>
        </div>

        <div v-if="audioUpload" class="tw-mt-4 tw-space-x-2 tw-flex">
          <b-form-file v-model="audioFile" accept="audio/*" />

          <b-button :disabled="!audioFile" @click="upload">
            {{ $t('playlistSelector.upload') }}
          </b-button>
        </div>
      </div>
    </b-modal>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'

import prettyDate from '@/mixins/prettyDate'
import playlist from '@/mixins/playlist'

export default {
  mixins: [prettyDate, playlist],

  data() {
    return {
      scheduleId: null,
      timeslot: null,

      audioFile: null,
      audioUpload: false,
      audioUploadError: '',
    }
  },

  computed: {
    loaded() {
      return this.$store.state.playlists.loaded.playlists
    },

    playlistsTableFields() {
      return [
        { key: 'id', label: this.$t('playlistTable.index') },
        { key: 'description', label: this.$t('playlistTable.description') },
        { key: 'entries', label: this.$t('playlistTable.entries') },
        { key: 'duration', label: this.$t('playlistTable.duration') },
        { key: 'actions', label: this.$t('playlistTable.actions'), class: 'text-right' },
      ]
    },

    timeslotDurationInNs() {
      const mm = this.timeslotDuration % 60
      const hh = (this.timeslotDuration - mm) / 60

      return this.hmsToNanoseconds(`${this.leadingZero(hh)}:${this.leadingZero(mm)}:00`)
    },

    timeslotDuration() {
      const { start, end } = this.timeslot

      return parseInt(this.prettyDuration(start, end).minutes, 10)
    },

    currentPlaylistDescription() {
      let description = false
      if (this.timeslot && this.timeslot.playlist_id !== null) {
        const choosenList = this.playlists.find((list) => list.id === this.timeslot.playlist_id)
        if (choosenList && choosenList.description.length > 0) {
          description = choosenList.description
        }
      }
      return description
    },

    ...mapGetters({
      selectedShow: 'shows/selectedShow',
      timeslots: 'shows/timeslots',
      playlists: 'playlists/playlists',
      getTimeslotById: 'shows/getTimeslotById',
    }),
  },

  methods: {
    upload(event) {
      event.preventDefault()
      event.stopPropagation()

      if (!this.audioFile) {
        this.audioUploadError = this.$t('playlistSelector.missingFile')
        return
      }

      this.audioUpload = false
      this.$store.dispatch('files/addFile', {
        show: this.selectedShow.slug,
        uploadSourceFile: this.audioFile,
        callback: this.handleUploadedFile,
      })
    },

    handleUploadedFile() {
      this.$store.dispatch('files/fetchFiles', {
        slug: this.selectedShow.slug,
        callback: this.createPlaylistForUploadedFile,
      })
    },

    createPlaylistForUploadedFile(files) {
      const file = files.slice(-1)[0]
      const { slug } = this.selectedShow
      const playlist = {
        description: 'Automatisch erstellt durch Dateiupload',
        entries: [{ file }],
      }

      this.$store.dispatch('playlists/add', {
        slug,
        playlist,
      })
    },

    toggleAudioUpload() {
      this.audioUpload = !this.audioUpload
    },

    open(scheduleId, timeslotId) {
      this.audioFile = null
      this.audioUpload = false
      this.scheduleId = scheduleId
      this.timeslot = this.getTimeslotById(timeslotId)
      this.$refs.modalPlaylistSelector.show()
    },

    choose(data) {
      const { item } = data || {}
      const { id } = item || {}
      let confirmed = true

      if (data && this.isMismatchedLength(data)) {
        confirmed = confirm(this.$t('playlistSelector.mismatchedLengthConfirmation'))
      }

      if (confirmed) {
        const ts = { ...this.timeslot }
        ts.playlist_id = id
        this.$store.dispatch('shows/updateTimeslot', {
          show: this.selectedShow.id,
          schedule: this.scheduleId,
          timeslot: ts,
          callback: () => {
            this.timeslot = this.getTimeslotById(ts.id)
          },
        })
      }
    },

    title(data) {
      if (this.isMismatchedLength(data)) {
        return this.$t('playlistSelector.mismatchedLength')
      }

      return ''
    },

    playlistToolTip(entries) {
      let text = '<div style="white-space: nowrap;" align="left">'
      for (const i in entries) {
        text += i + ': ' + entries[i].uri + '<br>'
      }
      text += '</div>'
      return text
    },

    isMismatchedLength(playlist) {
      const totalDuration = this.playlistDuration(playlist.item)
      let delta = 0

      const unknowns = (playlist.item.entries ?? []).filter((entry) => !entry.duration)
      if (unknowns.length === 1) {
        delta = this.timeslotDurationInNs - totalDuration
      }

      return this.timeslotDurationInNs !== totalDuration + delta
    },
  },
}
</script>