import { defineComponent, nextTick } from 'vue'
import { mapActions } from 'vuex'
import FtShareButton from '../ft-share-button/ft-share-button.vue'
import FtFlexBox from '../ft-flex-box/ft-flex-box.vue'
import FtIconButton from '../ft-icon-button/ft-icon-button.vue'
import FtInput from '../ft-input/ft-input.vue'
import FtPrompt from '../ft-prompt/ft-prompt.vue'
import {
  formatNumber,
  showToast,
} from '../../helpers/utils'

export default defineComponent({
  name: 'PlaylistInfo',
  components: {
    'ft-share-button': FtShareButton,
    'ft-flex-box': FtFlexBox,
    'ft-icon-button': FtIconButton,
    'ft-input': FtInput,
    'ft-prompt': FtPrompt,
  },
  props: {
    id: {
      type: String,
      required: true,
    },
    firstVideoId: {
      type: String,
      required: true,
    },
    firstVideoPlaylistItemId: {
      type: String,
      required: true,
    },
    playlistThumbnail: {
      type: String,
      required: true,
    },
    title: {
      type: String,
      required: true,
    },
    channelThumbnail: {
      type: String,
      required: true,
    },
    channelName: {
      type: String,
      required: true,
    },
    channelId: {
      type: String,
      default: null,
    },
    videoCount: {
      type: Number,
      required: true,
    },
    videos: {
      type: Array,
      required: true
    },
    viewCount: {
      type: Number,
      required: true,
    },
    lastUpdated: {
      type: String,
      default: undefined,
    },
    description: {
      type: String,
      required: true,
    },
    infoSource: {
      type: String,
      required: true,
    },
    moreVideoDataAvailable: {
      type: Boolean,
      required: true,
    },
  },
  data: function () {
    return {
      editMode: false,
      showDeletePlaylistPrompt: false,
      showRemoveVideosOnWatchPrompt: false,
      newTitle: '',
      newDescription: '',
      deletePlaylistPromptValues: [
        'yes',
        'no'
      ],
    }
  },
  computed: {
    hideSharingActions: function () {
      return this.$store.getters.getHideSharingActions
    },

    currentInvidiousInstance: function () {
      return this.$store.getters.getCurrentInvidiousInstance
    },

    historyCacheById: function () {
      return this.$store.getters.getHistoryCacheById
    },

    thumbnailPreference: function () {
      return this.$store.getters.getThumbnailPreference
    },

    blurThumbnails: function () {
      return this.$store.getters.getBlurThumbnails
    },

    blurThumbnailsStyle: function () {
      return this.blurThumbnails ? 'blur(20px)' : null
    },

    backendPreference: function () {
      return this.$store.getters.getBackendPreference
    },

    hideViews: function () {
      return this.$store.getters.getHideVideoViews
    },

    showPlaylists: function () {
      return !this.$store.getters.getHidePlaylists
    },

    selectedUserPlaylist: function () {
      return this.$store.getters.getPlaylist(this.id)
    },

    deletePlaylistPromptNames: function () {
      return [
        this.$t('Yes'),
        this.$t('No')
      ]
    },

    firstVideoIdExists() {
      return this.firstVideoId !== ''
    },

    parsedViewCount() {
      return formatNumber(this.viewCount)
    },

    parsedVideoCount() {
      return formatNumber(this.videoCount)
    },

    thumbnail: function () {
      if (this.thumbnailPreference === 'hidden' || !this.firstVideoIdExists) {
        return require('../../assets/img/thumbnail_placeholder.svg')
      }

      let baseUrl = 'https://i.ytimg.com'
      if (this.backendPreference === 'invidious') {
        baseUrl = this.currentInvidiousInstance
      } else if (typeof this.playlistThumbnail === 'string' && this.playlistThumbnail.length > 0) {
        // Use playlist thumbnail provided by YT when available
        return this.playlistThumbnail
      }

      switch (this.thumbnailPreference) {
        case 'start':
          return `${baseUrl}/vi/${this.firstVideoId}/mq1.jpg`
        case 'middle':
          return `${baseUrl}/vi/${this.firstVideoId}/mq2.jpg`
        case 'end':
          return `${baseUrl}/vi/${this.firstVideoId}/mq3.jpg`
        default:
          return `${baseUrl}/vi/${this.firstVideoId}/mqdefault.jpg`
      }
    },

    isUserPlaylist() {
      return this.infoSource === 'user'
    },

    videoPlaylistType() {
      return this.isUserPlaylist ? 'user' : ''
    },

    deletePlaylistButtonVisible: function() {
      if (!this.isUserPlaylist) { return false }
      // Cannot delete during edit
      if (this.editMode) { return false }

      // Cannot delete protected playlist
      return !this.selectedUserPlaylist.protected
    },

    sharePlaylistButtonVisible: function() {
      // Only online playlists can be shared
      if (this.isUserPlaylist) { return false }

      // Cannot delete protected playlist
      return !this.hideSharingActions
    },

    quickBookmarkPlaylistId() {
      return this.$store.getters.getQuickBookmarkTargetPlaylistId
    },
    quickBookmarkPlaylist() {
      return this.$store.getters.getPlaylist(this.quickBookmarkPlaylistId)
    },
    quickBookmarkEnabled() {
      return this.quickBookmarkPlaylist != null
    },
    markedAsQuickBookmarkTarget() {
      // Only user playlists can be target
      if (this.selectedUserPlaylist == null) { return false }
      if (this.quickBookmarkPlaylist == null) { return false }

      return this.quickBookmarkPlaylist._id === this.selectedUserPlaylist._id
    },
  },
  watch: {
    showDeletePlaylistPrompt(shown) {
      this.$emit(shown ? 'prompt-open' : 'prompt-close')
    },
    showRemoveVideosOnWatchPrompt(shown) {
      this.$emit(shown ? 'prompt-open' : 'prompt-close')
    },
  },
  created: function () {
    this.newTitle = this.title
    this.newDescription = this.description
  },
  methods: {
    toggleCopyVideosPrompt: function (force = false) {
      if (this.moreVideoDataAvailable && !this.isUserPlaylist && !force) {
        showToast(this.$t('User Playlists.SinglePlaylistView.Toast["Some videos in the playlist are not loaded yet. Click here to copy anyway."]'), 5000, () => {
          this.toggleCopyVideosPrompt(true)
        })
        return
      }

      this.showAddToPlaylistPromptForManyVideos({
        videos: this.videos,
        newPlaylistDefaultProperties: { title: this.title },
      })
    },

    savePlaylistInfo: function () {
      if (this.newTitle === '') {
        showToast(this.$t('User Playlists.SinglePlaylistView.Toast["Playlist name cannot be empty. Please input a name."]'))
        return
      }

      const playlist = {
        playlistName: this.newTitle,
        protected: this.selectedUserPlaylist.protected,
        description: this.newDescription,
        videos: this.selectedUserPlaylist.videos,
        _id: this.id,
      }
      try {
        this.updatePlaylist(playlist)
        showToast(this.$t('User Playlists.SinglePlaylistView.Toast["Playlist has been updated."]'))
      } catch (e) {
        showToast(this.$t('User Playlists.SinglePlaylistView.Toast["There was an issue with updating this playlist."]'))
        console.error(e)
      } finally {
        this.exitEditMode()
      }
    },

    enterEditMode: function () {
      this.newTitle = this.title
      this.newDescription = this.description
      this.editMode = true

      this.$emit('enter-edit-mode')

      nextTick(() => {
        // Some elements only present after rendering update
        this.$refs.playlistTitleInput.focus()
      })
    },

    exitEditMode: function () {
      this.editMode = false

      this.$emit('exit-edit-mode')
    },

    handleRemoveVideosOnWatchPromptAnswer: function (option) {
      if (option === 'yes') {
        const videosToWatch = this.selectedUserPlaylist.videos.filter((video) => {
          return this.historyCacheById[video.videoId] == null
        })

        const removedVideosCount = this.selectedUserPlaylist.videos.length - videosToWatch.length

        if (removedVideosCount === 0) {
          showToast(this.$t('User Playlists.SinglePlaylistView.Toast["There were no videos to remove."]'))
          this.showRemoveVideosOnWatchPrompt = false
          return
        }

        const playlist = {
          playlistName: this.title,
          protected: this.selectedUserPlaylist.protected,
          description: this.description,
          videos: videosToWatch,
          _id: this.id
        }
        try {
          this.updatePlaylist(playlist)
          showToast(this.$tc('User Playlists.SinglePlaylistView.Toast.{videoCount} video(s) have been removed', removedVideosCount, {
            videoCount: removedVideosCount,
          }))
        } catch (e) {
          showToast(this.$t('User Playlists.SinglePlaylistView.Toast["There was an issue with updating this playlist."]'))
          console.error(e)
        }
      }
      this.showRemoveVideosOnWatchPrompt = false
    },

    handleDeletePlaylistPromptAnswer: function (option) {
      if (option === 'yes') {
        if (this.selectedUserPlaylist.protected) {
          showToast(this.$t('User Playlists.SinglePlaylistView.Toast["This playlist is protected and cannot be removed."]'))
        } else {
          this.removePlaylist(this.id)
          this.$router.push(
            {
              path: '/userPlaylists'
            }
          )
          showToast(this.$t('User Playlists.SinglePlaylistView.Toast["Playlist {playlistName} has been deleted."]', {
            playlistName: this.title,
          }))
        }
      }
      this.showDeletePlaylistPrompt = false
    },

    enableQuickBookmarkForThisPlaylist() {
      const currentQuickBookmarkTargetPlaylist = this.quickBookmarkPlaylist

      this.updateQuickBookmarkTargetPlaylistId(this.id)
      if (currentQuickBookmarkTargetPlaylist != null) {
        showToast(
          this.$t('User Playlists.SinglePlaylistView.Toast["This playlist is now used for quick bookmark instead of {oldPlaylistName}. Click here to undo"]', {
            oldPlaylistName: currentQuickBookmarkTargetPlaylist.playlistName,
          }),
          5000,
          () => {
            this.updateQuickBookmarkTargetPlaylistId(currentQuickBookmarkTargetPlaylist._id)
            showToast(
              this.$t('User Playlists.SinglePlaylistView.Toast["Reverted to use {oldPlaylistName} for quick bookmark"]', {
                oldPlaylistName: currentQuickBookmarkTargetPlaylist.playlistName,
              }),
              5000,
            )
          },
        )
      } else {
        showToast(this.$t('User Playlists.SinglePlaylistView.Toast.This playlist is now used for quick bookmark'))
      }
    },
    disableQuickBookmark() {
      this.updateQuickBookmarkTargetPlaylistId(null)
      showToast(this.$t('User Playlists.SinglePlaylistView.Toast.Quick bookmark disabled'))
    },

    ...mapActions([
      'showAddToPlaylistPromptForManyVideos',
      'updatePlaylist',
      'removePlaylist',
      'updateQuickBookmarkTargetPlaylistId',
    ]),
  },
})
