import Vue from 'vue'
import { mapActions } from 'vuex'
import FtCard from '../../components/ft-card/ft-card.vue'
import FtLoader from '../../components/ft-loader/ft-loader.vue'
import FtElementList from '../../components/ft-element-list/ft-element-list.vue'
import FtIconButton from '../../components/ft-icon-button/ft-icon-button.vue'
import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue'

import $ from 'jquery'
import ytrend from 'yt-trending-scraper'

export default Vue.extend({
  name: 'Trending',
  components: {
    'ft-card': FtCard,
    'ft-loader': FtLoader,
    'ft-element-list': FtElementList,
    'ft-icon-button': FtIconButton,
    'ft-flex-box': FtFlexBox
  },
  data: function () {
    return {
      isLoading: false,
      shownResults: [],
      currentTab: 'default',
      tabInfoValues: [
        'default',
        'music',
        'gaming',
        'movies'
      ]
    }
  },
  computed: {
    usingElectron: function () {
      return this.$store.getters.getUsingElectron
    },
    backendPreference: function () {
      return this.$store.getters.getBackendPreference
    },
    backendFallback: function () {
      return this.$store.getters.getBackendFallback
    },
    currentInvidiousInstance: function () {
      return this.$store.getters.getCurrentInvidiousInstance
    },
    region: function () {
      return this.$store.getters.getRegion.toUpperCase()
    },
    trendingCache () {
      return this.$store.getters.getTrendingCache
    }
  },
  mounted: function () {
    if (this.trendingCache[this.currentTab] && this.trendingCache[this.currentTab].length > 0) {
      this.shownResults = this.trendingCache
    } else {
      this.getTrendingInfo()
    }
  },
  methods: {
    changeTab: function (tab, event) {
      if (event instanceof KeyboardEvent) {
        if (event.key === 'Tab') {
          return
        } else if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
          // navigate trending tabs with arrow keys
          const index = this.tabInfoValues.indexOf(tab)
          // tabs wrap around from leftmost to rightmost, and vice versa
          tab = (event.key === 'ArrowLeft')
            ? this.tabInfoValues[(index > 0 ? index : this.tabInfoValues.length) - 1]
            : this.tabInfoValues[(index + 1) % this.tabInfoValues.length]

          const tabNode = $(`#${tab}Tab`)
          event.target.setAttribute('tabindex', '-1')
          tabNode.attr('tabindex', '0')
          tabNode[0].focus()
        }

        event.preventDefault()
        if (event.key !== 'Enter' && event.key !== ' ') {
          return
        }
      }
      const currentTabNode = $('.trendingInfoTabs > .tab[aria-selected="true"]')
      const newTabNode = $(`#${tab}Tab`)

      // switch selectability from currently focused tab to new tab
      $('.trendingInfoTabs > .tab[tabindex="0"]').attr('tabindex', '-1')
      newTabNode.attr('tabindex', '0')

      currentTabNode.attr('aria-selected', 'false')
      newTabNode.attr('aria-selected', 'true')
      this.currentTab = tab
      this.getTrendingInfo()
    },

    getTrendingInfo () {
      if (!this.usingElectron) {
        this.getVideoInformationInvidious()
      } else {
        switch (this.backendPreference) {
          case 'local':
            this.getTrendingInfoLocal()
            break
          case 'invidious':
            this.getTrendingInfoInvidious()
            break
        }
      }
    },

    getTrendingInfoLocal: function () {
      this.isLoading = true

      console.log('getting local trending')
      const param = {
        parseCreatorOnRise: false,
        page: this.currentTab,
        geoLocation: this.region
      }

      ytrend.scrape_trending_page(param).then((result) => {
        const returnData = result.filter((item) => {
          return item.type === 'video' || item.type === 'channel' || item.type === 'playlist'
        })

        this.shownResults = returnData
        this.isLoading = false
        this.$store.commit('setTrendingCache', this.shownResults, this.currentTab)
      }).then(() => {
        document.querySelector(`#${this.currentTab}Tab`).focus()
      }).catch((err) => {
        console.log(err)
        const errorMessage = this.$t('Local API Error (Click to copy)')
        this.showToast({
          message: `${errorMessage}: ${err}`,
          time: 10000,
          action: () => {
            navigator.clipboard.writeText(err)
          }
        })
        if (!this.usingElectron || (this.backendPreference === 'local' && this.backendFallback)) {
          this.showToast({
            message: this.$t('Falling back to Invidious API')
          })
          this.getTrendingInfoInvidious()
        } else {
          this.isLoading = false
        }
      })
    },

    getTrendingInfoInvidious: function () {
      this.isLoading = true

      const trendingPayload = {
        resource: 'trending',
        id: '',
        params: { region: this.region }
      }

      if (this.currentTab !== 'default') {
        trendingPayload.params.type = this.currentTab.charAt(0).toUpperCase() + this.currentTab.slice(1)
      }

      this.invidiousAPICall(trendingPayload).then((result) => {
        if (!result) {
          return
        }

        console.log(result)

        const returnData = result.filter((item) => {
          return item.type === 'video' || item.type === 'channel' || item.type === 'playlist'
        })

        this.shownResults = returnData
        this.isLoading = false
        this.$store.commit('setTrendingCache', this.shownResults, this.trendingCache)
      }).then(() => {
        document.querySelector(`#${this.currentTab}Tab`).focus()
      }).catch((err) => {
        console.log(err)
        const errorMessage = this.$t('Invidious API Error (Click to copy)')
        this.showToast({
          message: `${errorMessage}: ${err.responseText}`,
          time: 10000,
          action: () => {
            navigator.clipboard.writeText(err)
          }
        })

        if (!this.usingElectron || (this.backendPreference === 'invidious' && this.backendFallback)) {
          this.showToast({
            message: this.$t('Falling back to Local API')
          })
          this.getTrendingInfoLocal()
        } else {
          this.isLoading = false
        }
      })
    },

    ...mapActions([
      'showToast',
      'invidiousAPICall'
    ])
  }
})
