import logger from '@/logging'
import _ from 'lodash'

export default {
  namespaced: true,
  state: {
    tracks: [],
    currentIndex: -1,
    ended: true,
    previousQueue: null
  },
  mutations: {
    currentIndex (state, value) {
      state.currentIndex = value
    },
    ended (state, value) {
      state.ended = value
    },
    splice (state, {start, size}) {
      state.tracks.splice(start, size)
    },
    tracks (state, value) {
      state.tracks = value
    },
    insert (state, {track, index}) {
      state.tracks.splice(index, 0, track)
    },
    reorder (state, {oldIndex, newIndex}) {
      // called when the user uses drag / drop to reorder
      // tracks in queue
      if (oldIndex === state.currentIndex) {
        state.currentIndex = newIndex
        return
      }
      if (oldIndex < state.currentIndex && newIndex >= state.currentIndex) {
        // item before was moved after
        state.currentIndex -= 1
      }
      if (oldIndex > state.currentIndex && newIndex <= state.currentIndex) {
        // item after was moved before
        state.currentIndex += 1
      }
    }
  },
  getters: {
    currentTrack: state => {
      return state.tracks[state.currentIndex]
    },
    hasNext: state => {
      return state.currentIndex < state.tracks.length - 1
    },
    hasPrevious: state => {
      return state.currentIndex > 0
    }
  },
  actions: {
    append ({commit, state, dispatch}, {track, index, skipPlay}) {
      index = index || state.tracks.length
      if (index > state.tracks.length - 1) {
        // we simply push to the end
        commit('insert', {track, index: state.tracks.length})
      } else {
        // we insert the track at given position
        commit('insert', {track, index})
      }
      if (!skipPlay) {
        dispatch('resume')
      }
    },

    appendMany ({state, dispatch}, {tracks, index}) {
      logger.default.info('Appending many tracks to the queue', tracks.map(e => { return e.title }))
      if (state.tracks.length === 0) {
        index = 0
      } else {
        index = index || state.tracks.length
      }
      tracks.forEach((t) => {
        dispatch('append', {track: t, index: index, skipPlay: true})
        index += 1
      })
      dispatch('resume')
    },

    cleanTrack ({state, dispatch, commit}, index) {
      // are we removing current playin track
      let current = index === state.currentIndex
      if (current) {
        dispatch('player/stop', null, {root: true})
      }
      if (index < state.currentIndex) {
        dispatch('currentIndex', state.currentIndex - 1)
      }
      commit('splice', {start: index, size: 1})
      if (current) {
        // we play next track, which now have the same index
        dispatch('currentIndex', index)
      }
    },

    resume ({state, dispatch, rootState}) {
      if (state.ended | rootState.player.errored) {
        dispatch('next')
      }
    },
    previous ({state, dispatch}) {
      if (state.currentIndex > 0) {
        dispatch('currentIndex', state.currentIndex - 1)
      }
    },
    next ({state, dispatch, commit, rootState}) {
      if (rootState.player.looping === 2 && state.currentIndex >= state.tracks.length - 1) {
        logger.default.info('Going back to the beginning of the queue')
        return dispatch('currentIndex', 0)
      } else {
        if (state.currentIndex < state.tracks.length - 1) {
          logger.default.debug('Playing next track')
          return dispatch('currentIndex', state.currentIndex + 1)
        } else {
          commit('ended', true)
        }
      }
    },
    currentIndex ({commit, state, rootState, dispatch}, index) {
      commit('ended', false)
      commit('player/currentTime', 0, {root: true})
      commit('player/playing', true, {root: true})
      commit('player/errored', false, {root: true})
      commit('currentIndex', index)
      if (state.tracks.length - index <= 2 && rootState.radios.running) {
        dispatch('radios/populateQueue', null, {root: true})
      }
    },
    clean ({dispatch, commit}) {
      dispatch('radios/stop', null, {root: true})
      dispatch('player/stop', null, {root: true})
      commit('tracks', [])
      dispatch('currentIndex', -1)
      // so we replay automatically on next track append
      commit('ended', true)
    },
    shuffle ({dispatch, commit, state}) {
      let toKeep = state.tracks.slice(0, state.currentIndex + 1)
      let toShuffle = state.tracks.slice(state.currentIndex + 1)
      let shuffled = toKeep.concat(_.shuffle(toShuffle))
      commit('player/currentTime', 0, {root: true})
      commit('tracks', [])
      dispatch('appendMany', {tracks: shuffled})
    }
  }
}
