<template>
  <div class="page" :class="streamLibraryItem ? 'streaming' : ''">
    <app-book-shelf-toolbar page="podcast-search" />

    <div id="bookshelf" class="w-full overflow-y-auto px-2 py-6 sm:px-4 md:p-12 relative">
      <div class="w-full max-w-5xl mx-auto py-4">
        <p class="text-xl mb-2 font-semibold px-4 md:px-0">{{ $strings.HeaderCurrentDownloads }}</p>
        <p v-if="!episodesDownloading.length" class="text-lg py-4">{{ $strings.MessageNoDownloadsInProgress }}</p>
        <template v-for="episode in episodesDownloading">
          <div :key="episode.id" class="flex py-5 relative">
            <covers-preview-cover :src="$store.getters['globals/getLibraryItemCoverSrcById'](episode.libraryItemId)" :width="96" :book-cover-aspect-ratio="bookCoverAspectRatio" :show-resolution="false" class="hidden md:block" />
            <div class="flex-grow pl-4 max-w-2xl">
              <!-- mobile -->
              <div class="flex md:hidden mb-2">
                <covers-preview-cover :src="$store.getters['globals/getLibraryItemCoverSrcById'](episode.libraryItemId)" :width="48" :book-cover-aspect-ratio="bookCoverAspectRatio" :show-resolution="false" class="md:hidden" />
                <div class="flex-grow px-2">
                  <div class="flex items-center">
                    <nuxt-link :to="`/item/${episode.libraryItemId}`" class="text-sm text-gray-200 hover:underline">{{ episode.podcastTitle }}</nuxt-link>
                    <widgets-explicit-indicator :explicit="episode.podcastExplicit" />
                  </div>
                  <p class="text-xs text-gray-300 mb-1">{{ $dateDistanceFromNow(episode.publishedAt) }}</p>
                </div>
              </div>
              <!-- desktop -->
              <div class="hidden md:block">
                <div class="flex items-center">
                  <nuxt-link :to="`/item/${episode.libraryItemId}`" class="text-sm text-gray-200 hover:underline">{{ episode.podcastTitle }}</nuxt-link>
                  <widgets-explicit-indicator :explicit="episode.podcastExplicit" />
                </div>
                <p class="text-xs text-gray-300 mb-1">{{ $dateDistanceFromNow(episode.publishedAt) }}</p>
              </div>

              <div class="flex items-center font-semibold text-gray-200">
                <div v-if="episode.season || episode.episode">#</div>
                <div v-if="episode.season">{{ episode.season }}x</div>
                <div v-if="episode.episode">{{ episode.episode }}</div>
              </div>

              <div class="flex items-center mb-2">
                <span class="font-semibold text-sm md:text-base">{{ episode.episodeDisplayTitle }}</span>
                <widgets-podcast-type-indicator :type="episode.episodeType" />
              </div>

              <p class="text-sm text-gray-200 mb-4">{{ episode.subtitle }}</p>
            </div>
          </div>
        </template>

        <tables-podcast-download-queue-table v-if="episodeDownloadsQueued.length" :queue="episodeDownloadsQueued"></tables-podcast-download-queue-table>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  async asyncData({ params, redirect }) {
    if (!params.library) {
      console.error('No library...', params.library)
      return redirect('/')
    }
    return {
      libraryId: params.library
    }
  },
  data() {
    return {
      episodesDownloading: [],
      episodeDownloadsQueued: [],
      processing: false
    }
  },
  computed: {
    bookCoverAspectRatio() {
      return this.$store.getters['libraries/getBookCoverAspectRatio']
    },
    streamLibraryItem() {
      return this.$store.state.streamLibraryItem
    }
  },
  methods: {
    episodeDownloadQueued(episodeDownload) {
      if (episodeDownload.libraryId === this.libraryId) {
        this.episodeDownloadsQueued.push(episodeDownload)
      }
    },
    episodeDownloadStarted(episodeDownload) {
      if (episodeDownload.libraryId === this.libraryId) {
        this.episodeDownloadsQueued = this.episodeDownloadsQueued.filter((d) => d.id !== episodeDownload.id)
        this.episodesDownloading.push(episodeDownload)
      }
    },
    episodeDownloadFinished(episodeDownload) {
      if (episodeDownload.libraryId === this.libraryId) {
        this.episodeDownloadsQueued = this.episodeDownloadsQueued.filter((d) => d.id !== episodeDownload.id)
        this.episodesDownloading = this.episodesDownloading.filter((d) => d.id !== episodeDownload.id)
      }
    },
    episodeDownloadQueueUpdated(downloadQueueDetails) {
      this.episodeDownloadsQueued = downloadQueueDetails.queue.filter((q) => q.libraryId == this.libraryId)
    },
    async loadInitialDownloadQueue() {
      this.processing = true
      const queuePayload = await this.$axios.$get(`/api/libraries/${this.libraryId}/episode-downloads`).catch((error) => {
        console.error('Failed to get download queue', error)
        this.$toast.error('Failed to get download queue')
        return null
      })
      this.processing = false
      this.episodeDownloadsQueued = queuePayload?.queue || []

      if (queuePayload?.currentDownload) {
        this.episodesDownloading.push(queuePayload.currentDownload)
      }

      // Initialize listeners after load to prevent event race conditions
      this.initListeners()
    },
    initListeners() {
      this.$root.socket.on('episode_download_queued', this.episodeDownloadQueued)
      this.$root.socket.on('episode_download_started', this.episodeDownloadStarted)
      this.$root.socket.on('episode_download_finished', this.episodeDownloadFinished)
      this.$root.socket.on('episode_download_queue_updated', this.episodeDownloadQueueUpdated)
    }
  },
  mounted() {
    if (this.libraryId) {
      this.$store.commit('libraries/setCurrentLibrary', this.libraryId)
    }

    this.loadInitialDownloadQueue()
  },
  beforeDestroy() {
    this.$root.socket.off('episode_download_queued', this.episodeDownloadQueued)
    this.$root.socket.off('episode_download_started', this.episodeDownloadStarted)
    this.$root.socket.off('episode_download_finished', this.episodeDownloadFinished)
    this.$root.socket.off('episode_download_queue_updated', this.episodeDownloadQueueUpdated)
  }
}
</script>
