<template>
  <div>
    <!-- Search field + recent searches -->
    <section class="section pb-0">
      <div class="container">
        <div class="columns is-centered">
          <div class="column is-four-fifths">
            <form @submit.prevent="new_search">
              <div class="field">
                <p class="control is-expanded has-icons-left">
                  <input
                    ref="search_field"
                    v-model="search_query"
                    class="input is-rounded is-shadowless"
                    type="text"
                    :placeholder="$t('page.spotify.search.placeholder')"
                    autocomplete="off"
                  />
                  <mdicon class="icon is-left" name="magnify" size="16" />
                </p>
              </div>
            </form>
            <div class="tags mt-4">
              <a
                v-for="recent_search in recent_searches"
                :key="recent_search"
                class="tag"
                @click="open_recent_search(recent_search)"
                v-text="recent_search"
              />
            </div>
          </div>
        </div>
      </div>
    </section>
    <tabs-search :query="search_query" />
    <!-- Tracks -->
    <content-with-heading v-if="show_tracks && tracks.total" class="pt-0">
      <template #heading-left>
        <p class="title is-4" v-text="$t('page.spotify.search.tracks')" />
      </template>
      <template #content>
        <list-item-track-spotify
          v-for="track in tracks.items"
          :key="track.id"
          :track="track"
          :position="0"
          :context_uri="track.uri"
        >
          <template #actions>
            <a @click.prevent.stop="open_track_dialog(track)">
              <mdicon
                class="icon has-text-dark"
                name="dots-vertical"
                size="16"
              />
            </a>
          </template>
        </list-item-track-spotify>
        <VueEternalLoading
          v-if="query.type === 'track'"
          :load="search_tracks_next"
        >
          <template #no-more> . </template>
        </VueEternalLoading>
        <modal-dialog-track-spotify
          :show="show_track_details_modal"
          :track="selected_track"
          :album="selected_track.album"
          @close="show_track_details_modal = false"
        />
      </template>
      <template #footer>
        <nav v-if="show_all_tracks_button" class="level">
          <p class="level-item">
            <a
              class="button is-light is-small is-rounded"
              @click="open_search_tracks"
              v-text="
                $t('page.spotify.search.show-all-tracks', tracks.total, {
                  count: $filters.number(tracks.total)
                })
              "
            />
          </p>
        </nav>
      </template>
    </content-with-heading>
    <content-text v-if="show_tracks && !tracks.total" class="pt-0">
      <template #content>
        <p><i v-text="$t('page.spotify.search.no-tracks')" /></p>
      </template>
    </content-text>
    <!-- Artists -->
    <content-with-heading v-if="show_artists && artists.total">
      <template #heading-left>
        <p class="title is-4" v-text="$t('page.spotify.search.artists')" />
      </template>
      <template #content>
        <list-item-artist-spotify
          v-for="artist in artists.items"
          :key="artist.id"
          :artist="artist"
        >
          <template #actions>
            <a @click.prevent.stop="open_artist_dialog(artist)">
              <mdicon
                class="icon has-text-dark"
                name="dots-vertical"
                size="16"
              />
            </a>
          </template>
        </list-item-artist-spotify>
        <VueEternalLoading
          v-if="query.type === 'artist'"
          :load="search_artists_next"
        >
          <template #no-more> . </template>
        </VueEternalLoading>
        <modal-dialog-artist-spotify
          :show="show_artist_details_modal"
          :artist="selected_artist"
          @close="show_artist_details_modal = false"
        />
      </template>
      <template #footer>
        <nav v-if="show_all_artists_button" class="level">
          <p class="level-item">
            <a
              class="button is-light is-small is-rounded"
              @click="open_search_artists"
              v-text="
                $t('page.spotify.search.show-all-artists', artists.total, {
                  count: $filters.number(artists.total)
                })
              "
            />
          </p>
        </nav>
      </template>
    </content-with-heading>
    <content-text v-if="show_artists && !artists.total">
      <template #content>
        <p><i v-text="$t('page.spotify.search.no-artists')" /></p>
      </template>
    </content-text>
    <!-- Albums -->
    <content-with-heading v-if="show_albums && albums.total">
      <template #heading-left>
        <p class="title is-4" v-text="$t('page.spotify.search.albums')" />
      </template>
      <template #content>
        <list-item-album-spotify
          v-for="album in albums.items"
          :key="album.id"
          :album="album"
          @click="open_album(album)"
        >
          <template v-if="is_visible_artwork" #artwork>
            <cover-artwork
              :artwork_url="artwork_url(album)"
              :artist="album.artist"
              :album="album.name"
              class="is-clickable fd-has-shadow fd-cover fd-cover-small-image"
              :maxwidth="64"
              :maxheight="64"
            />
          </template>
          <template #actions>
            <a @click.prevent.stop="open_album_dialog(album)">
              <mdicon
                class="icon has-text-dark"
                name="dots-vertical"
                size="16"
              />
            </a>
          </template>
        </list-item-album-spotify>
        <VueEternalLoading
          v-if="query.type === 'album'"
          :load="search_albums_next"
        >
          <template #no-more> . </template>
        </VueEternalLoading>
        <modal-dialog-album-spotify
          :show="show_album_details_modal"
          :album="selected_album"
          @close="show_album_details_modal = false"
        />
      </template>
      <template #footer>
        <nav v-if="show_all_albums_button" class="level">
          <p class="level-item">
            <a
              class="button is-light is-small is-rounded"
              @click="open_search_albums"
              v-text="
                $t('page.spotify.search.show-all-albums', albums.total, {
                  count: $filters.number(albums.total)
                })
              "
            />
          </p>
        </nav>
      </template>
    </content-with-heading>
    <content-text v-if="show_albums && !albums.total">
      <template #content>
        <p><i v-text="$t('page.spotify.search.no-albums')" /></p>
      </template>
    </content-text>
    <!-- Playlists -->
    <content-with-heading v-if="show_playlists && playlists.total">
      <template #heading-left>
        <p class="title is-4" v-text="$t('page.spotify.search.playlists')" />
      </template>
      <template #content>
        <list-item-playlist-spotify
          v-for="playlist in playlists.items"
          :key="playlist.id"
          :playlist="playlist"
        >
          <template #actions>
            <a @click.prevent.stop="open_playlist_dialog(playlist)">
              <mdicon
                class="icon has-text-dark"
                name="dots-vertical"
                size="16"
              />
            </a>
          </template>
        </list-item-playlist-spotify>
        <VueEternalLoading
          v-if="query.type === 'playlist'"
          :load="search_playlists_next"
        >
          <template #no-more> . </template>
        </VueEternalLoading>
        <modal-dialog-playlist-spotify
          :show="show_playlist_details_modal"
          :playlist="selected_playlist"
          @close="show_playlist_details_modal = false"
        />
      </template>
      <template #footer>
        <nav v-if="show_all_playlists_button" class="level">
          <p class="level-item">
            <a
              class="button is-light is-small is-rounded"
              @click="open_search_playlists"
              v-text="
                $t('page.spotify.search.show-all-playlists', playlists.total, {
                  count: $filters.number(playlists.total)
                })
              "
            />
          </p>
        </nav>
      </template>
    </content-with-heading>
    <content-text v-if="show_playlists && !playlists.total">
      <template #content>
        <p><i v-text="$t('page.spotify.search.no-playlists')" /></p>
      </template>
    </content-text>
  </div>
</template>

<script>
import * as types from '@/store/mutation_types'
import ContentText from '@/templates/ContentText.vue'
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
import CoverArtwork from '@/components/CoverArtwork.vue'
import ListItemAlbumSpotify from '@/components/ListItemAlbumSpotify.vue'
import ListItemArtistSpotify from '@/components/ListItemArtistSpotify.vue'
import ListItemPlaylistSpotify from '@/components/ListItemPlaylistSpotify.vue'
import ListItemTrackSpotify from '@/components/ListItemTrackSpotify.vue'
import ModalDialogAlbumSpotify from '@/components/ModalDialogAlbumSpotify.vue'
import ModalDialogArtistSpotify from '@/components/ModalDialogArtistSpotify.vue'
import ModalDialogPlaylistSpotify from '@/components/ModalDialogPlaylistSpotify.vue'
import ModalDialogTrackSpotify from '@/components/ModalDialogTrackSpotify.vue'
import SpotifyWebApi from 'spotify-web-api-js'
import TabsSearch from '@/components/TabsSearch.vue'
import { VueEternalLoading } from '@ts-pro/vue-eternal-loading'
import webapi from '@/webapi'

const PAGE_SIZE = 50

export default {
  name: 'PageSearchSpotify',
  components: {
    ContentText,
    ContentWithHeading,
    CoverArtwork,
    ListItemAlbumSpotify,
    ListItemArtistSpotify,
    ListItemPlaylistSpotify,
    ListItemTrackSpotify,
    ModalDialogAlbumSpotify,
    ModalDialogArtistSpotify,
    ModalDialogPlaylistSpotify,
    ModalDialogTrackSpotify,
    TabsSearch,
    VueEternalLoading
  },

  data() {
    return {
      albums: { items: [], total: 0 },
      artists: { items: [], total: 0 },
      playlists: { items: [], total: 0 },
      query: {},
      search_param: {},
      search_query: '',
      selected_album: {},
      selected_artist: {},
      selected_playlist: {},
      selected_track: {},
      show_album_details_modal: false,
      show_artist_details_modal: false,
      show_playlist_details_modal: false,
      show_track_details_modal: false,
      tracks: { items: [], total: 0 },
      validSearchTypes: ['track', 'artist', 'album', 'playlist']
    }
  },

  computed: {
    is_visible_artwork() {
      return this.$store.getters.settings_option(
        'webinterface',
        'show_cover_artwork_in_album_lists'
      ).value
    },
    recent_searches() {
      return this.$store.state.recent_searches.filter(
        (search) => !search.startsWith('query:')
      )
    },
    show_albums() {
      return this.$route.query.type && this.$route.query.type.includes('album')
    },
    show_all_albums_button() {
      return this.albums.total > this.albums.items.length
    },
    show_all_artists_button() {
      return this.artists.total > this.artists.items.length
    },
    show_all_playlists_button() {
      return this.playlists.total > this.playlists.items.length
    },
    show_all_tracks_button() {
      return this.tracks.total > this.tracks.items.length
    },
    show_artists() {
      return this.$route.query.type && this.$route.query.type.includes('artist')
    },
    show_playlists() {
      return (
        this.$route.query.type && this.$route.query.type.includes('playlist')
      )
    },
    show_tracks() {
      return this.$route.query.type && this.$route.query.type.includes('track')
    }
  },

  watch: {
    $route(to, from) {
      this.query = to.query
      this.search()
    }
  },

  mounted() {
    this.query = this.$route.query
    this.search()
  },

  methods: {
    artwork_url(album) {
      if (album.images && album.images.length > 0) {
        return album.images[0].url
      }
      return ''
    },
    new_search() {
      if (!this.search_query) {
        return
      }
      this.$router.push({
        name: 'search-spotify',
        query: {
          limit: 3,
          offset: 0,
          query: this.search_query,
          type: 'track,artist,album,playlist,audiobook,podcast'
        }
      })
      this.$refs.search_field.blur()
    },
    open_album(album) {
      this.$router.push({
        name: 'music-spotify-album',
        params: { id: album.id }
      })
    },
    open_album_dialog(album) {
      this.selected_album = album
      this.show_album_details_modal = true
    },
    open_artist_dialog(artist) {
      this.selected_artist = artist
      this.show_artist_details_modal = true
    },
    open_playlist_dialog(playlist) {
      this.selected_playlist = playlist
      this.show_playlist_details_modal = true
    },
    open_recent_search(query) {
      this.search_query = query
      this.new_search()
    },
    open_search_albums() {
      this.$router.push({
        name: 'search-spotify',
        query: {
          query: this.$route.query.query,
          type: 'album'
        }
      })
    },
    open_search_artists() {
      this.$router.push({
        name: 'search-spotify',
        query: {
          query: this.$route.query.query,
          type: 'artist'
        }
      })
    },
    open_search_playlists() {
      this.$router.push({
        name: 'search-spotify',
        query: {
          query: this.$route.query.query,
          type: 'playlist'
        }
      })
    },
    open_search_tracks() {
      this.$router.push({
        name: 'search-spotify',
        query: {
          query: this.$route.query.query,
          type: 'track'
        }
      })
    },
    open_track_dialog(track) {
      this.selected_track = track
      this.show_track_details_modal = true
    },
    reset() {
      this.tracks = { items: [], total: 0 }
      this.artists = { items: [], total: 0 }
      this.albums = { items: [], total: 0 }
      this.playlists = { items: [], total: 0 }
    },
    search() {
      this.reset()
      // If no search query present reset and focus search field
      if (
        !this.query.query ||
        this.query.query === '' ||
        this.query.query.startsWith('query:')
      ) {
        this.search_query = ''
        this.$refs.search_field.focus()
        return
      }
      this.search_query = this.query.query
      this.search_param.limit = this.query.limit ? this.query.limit : PAGE_SIZE
      this.search_param.offset = this.query.offset ? this.query.offset : 0
      this.$store.commit(types.ADD_RECENT_SEARCH, this.query.query)
      this.search_all()
    },
    search_albums_next({ loaded }) {
      this.spotify_search().then((data) => {
        this.albums.items = this.albums.items.concat(data.albums.items)
        this.albums.total = data.albums.total
        this.search_param.offset += data.albums.limit
        loaded(data.albums.items.length, PAGE_SIZE)
      })
    },
    search_all() {
      this.spotify_search().then((data) => {
        this.tracks = data.tracks ? data.tracks : { items: [], total: 0 }
        this.artists = data.artists ? data.artists : { items: [], total: 0 }
        this.albums = data.albums ? data.albums : { items: [], total: 0 }
        this.playlists = data.playlists
          ? data.playlists
          : { items: [], total: 0 }
      })
    },
    search_artists_next({ loaded }) {
      this.spotify_search().then((data) => {
        this.artists.items = this.artists.items.concat(data.artists.items)
        this.artists.total = data.artists.total
        this.search_param.offset += data.artists.limit
        loaded(data.artists.items.length, PAGE_SIZE)
      })
    },
    search_playlists_next({ loaded }) {
      this.spotify_search().then((data) => {
        this.playlists.items = this.playlists.items.concat(data.playlists.items)
        this.playlists.total = data.playlists.total
        this.search_param.offset += data.playlists.limit
        loaded(data.playlists.items.length, PAGE_SIZE)
      })
    },
    search_tracks_next({ loaded }) {
      this.spotify_search().then((data) => {
        this.tracks.items = this.tracks.items.concat(data.tracks.items)
        this.tracks.total = data.tracks.total
        this.search_param.offset += data.tracks.limit
        loaded(data.tracks.items.length, PAGE_SIZE)
      })
    },
    spotify_search() {
      return webapi.spotify().then(({ data }) => {
        this.search_param.market = data.webapi_country
        const spotifyApi = new SpotifyWebApi()
        spotifyApi.setAccessToken(data.webapi_token)
        const types = this.query.type
          .split(',')
          .filter((type) => this.validSearchTypes.includes(type))
        return spotifyApi.search(this.query.query, types, this.search_param)
      })
    }
  }
}
</script>

<style></style>
