import axios from 'axios'
import handleApiError from '../handleApiError'

const cloneMinimalShowObject = function (show) {
  /* returns a new minimal object from the current show object with all
  properties needed for a PUT request to the /show/ endpoint */
  let s = {}
  s.name = show.name
  s.slug = show.slug
  s.short_description = show.short_description
  s.fundingcategory = show.fundingcategory
  s.type = show.type
  // we do not want the arrays do be passed as references, because the
  // current show object should not get modified when the update object
  // gets modified, therefore we use slice to clone the arrays
  s.category = show.category.slice()
  s.hosts = show.hosts.slice()
  s.owners = show.owners.slice()
  s.language = show.language.slice()
  s.topic = show.topic.slice()
  s.musicfocus = show.musicfocus.slice()
  return s
}

const state = {
  shows: [],
  timeslots: [],
  loaded: {
    shows: false,
    timeslots: false,
    schedules: false,
  },
  selected: {
    index: 0, // index of the currently selected show in our shows array
    id: 0,    // actual id of the currently selected show
  }
}

const getters = {
  shows: state => state.shows,
  selectedShow: state => state.shows[state.selected.index],
  getShowByDataParam: state => data => {
    let show
    if (data.id !== undefined) {
      show = state.shows.find(s => s.id === data.id)
      if (show === undefined) { this.$log.error('getShowByDataParam: ID not found in store!') }
    } else if (data.index !== undefined) {
      show = state.shows[data.index]
    } else {
      this.$log.error('getShowByDataParam: no ID or index was provided')
    }
    return show
  }
}

const mutations = {
  loading(state, item) {
    state.loaded[item] = false
  },
  finishLoading(state, item) {
    state.loaded[item] = true
  },

  setShows(state, shows) {
    state.shows = shows
  },
  setTimeslots(state, slots) {
    state.timeslots = slots
  },

  setName (state, data) {
    let index = state.shows.findIndex(s => s.id === data.id)
    state.shows[index].name = data.text
  },
  setShortDescription (state, data) {
    let index = state.shows.findIndex(s => s.id === data.id)
    state.shows[index].short_description = data.text
  },
  setDescription (state, data) {
    let index = state.shows.findIndex(s => s.id === data.id)
    state.shows[index].description = data.text
  },
  setActive (state, data) {
    let index = state.shows.findIndex(s => s.id === data.id)
    state.shows[index].is_active = data.active
  },

  switchShow (state, index) {
    state.selected.index = index
    state.selected.id = state.shows[index].id
  }
}

const actions = {
  fetchShows (ctx, data) {
    ctx.commit('loading', 'shows')
    let uri = process.env.VUE_APP_API_STEERING + 'shows'
    axios.get(uri, {
      withCredentials: true,
      headers: { 'Authorization': 'Bearer ' + ctx.rootState.auth.user.access_token }
    }).then(response => {
      ctx.commit('setShows', response.data)
      ctx.commit('finishLoading', 'shows')
      if (data && typeof(data.callback) === 'function') { data.callback() }
    }).catch(error => {
      handleApiError(this, error, 'could not load shows')
      if (data && typeof(data.callbackCancel) === 'function') { data.callbackCancel() }
    })
  },

  fetchTimeslots (ctx, data) {
    ctx.commit('loading', 'timeslots')
    let uri = process.env.VUE_APP_API_STEERING + 'timeslots?start=' + data.start + '&end=' + data.end
    axios.get(uri, {
      withCredentials: true,
      headers: { 'Authorization': 'Bearer ' + ctx.rootState.auth.user.access_token }
    }).then(response => {
      ctx.commit('setTimeslots', response.data)
      ctx.commit('finishLoading', 'timeslots')
      if (data && typeof(data.callback) === 'function') { data.callback() }
    }).catch(error => {
      handleApiError(this, error, 'could not load timeslots')
      if (data && typeof(data.callbackCancel) === 'function') { data.callbackCancel() }
    })
  },

  submitSchedule (ctx, data) {
    ctx.commit('loading', 'schedules')
    let uri = process.env.VUE_APP_API_STEERING_SHOWS + data.showId + '/schedules/'
    axios.post(uri, data.schedule, {
      withCredentials: true,
      headers: { 'Authorization': 'Bearer ' + ctx.rootState.auth.user.access_token }
    }).then(response => {
      ctx.commit('finishLoading', 'schedules')
      if (data && typeof(data.callback) === 'function') { data.callback(response) }
    }).catch(error => {
      handleApiError(this, error, 'could not load timeslots')
      if (data && typeof(data.callbackCancel) === 'function') { data.callbackCancel() }
    })
  },

  updateShow (ctx, data) {
    ctx.commit('loading', 'shows')
    let uri = process.env.VUE_APP_API_STEERING_SHOWS + data.id + '/'
    axios.put(uri, data.show , {
      withCredentials: true,
      headers: { 'Authorization': 'Bearer ' + ctx.rootState.auth.user.access_token }
    }).then(response => {
      ctx.commit('finishLoading', 'shows')
      if (data && typeof(data.callback) === 'function') { data.callback(response) }
    }).catch(error => {
      handleApiError(this, error, 'could not update show')
      if (data && typeof(data.callbackCancel) === 'function') { data.callbackCancel() }
    })
  },

  updateName (ctx, data) {
    let show = cloneMinimalShowObject(ctx.getters.getShowByDataParam(data))
    show.name = data.text
    ctx.dispatch('updateShow', {
      id: data.id,
      show: show,
      callback: () => {
        ctx.commit('setName', {
          id: data.id,
          text: data.text
        })
        if (typeof(data.callback) === 'function') { data.callback() }
      }
    })
  },

  updateShortDescription (ctx, data) {
    let show = cloneMinimalShowObject(ctx.getters.getShowByDataParam(data))
    show.short_description = data.text
    ctx.dispatch('updateShow', {
      id: data.id,
      show: show,
      callback: () => {
        ctx.commit('setShortDescription', {
          id: data.id,
          text: data.text
        })
      }
    })
  },

  updateDescription (ctx, data) {
    let show = cloneMinimalShowObject(ctx.getters.getShowByDataParam(data))
    show.description = data.text
    ctx.dispatch('updateShow', {
      id: data.id,
      show: show,
      callback: () => {
        ctx.commit('setDescription', {
          id: data.id,
          text: data.text
        })
      }
    })
  },

  activateShow (ctx, data) {
    let show = cloneMinimalShowObject(ctx.getters.getShowByDataParam(data))
    show.is_active = true
    ctx.dispatch('updateShow', {
      id: data.id,
      show: show,
      callback: () => {
        ctx.commit('setActive', {
          id: data.id,
          active: true
        })
      }
    })
  },

  deactivateShow (ctx, data) {
    let show = cloneMinimalShowObject(ctx.getters.getShowByDataParam(data))
    show.is_active = false
    ctx.dispatch('updateShow', {
      id: data.id,
      show: show,
      callback: () => {
        ctx.commit('setActive', {
          id: data.id,
          active: false
        })
      }
    })
  },
}

export default {
  namespaced: true,
  state,
  getters,
  actions,
  mutations,
}