import Vue from 'vue'

export const state = () => ({
  products: [],
  remote: {},
  local: { filtersGrouped: {} },
  images: [],
  cover: {
    name: '',
    url: '',
    file: null,
  },
  tile: {
    name: '',
    url: '',
    file: null,
  },
  columns: [
    {
      text: 'learning.product',
      sortable: false,
      value: 'cover',
      fixed: true,
    },
    {
      text: '',
      sortable: false,
      value: 'title',
      fixed: true,
      divider: true,
    },
    {
      text: 'learning.code',
      sortable: true,
      value: 'code',
      display: true,
    },
    {
      text: 'learning.partner',
      sortable: true,
      value: 'partner',
      display: true,
    },
    {
      text: 'learning.owner',
      sortable: true,
      value: 'owner',
      display: true,
    },
    {
      text: 'learning.status.title',
      sortable: false,
      value: 'status',
      display: true,
    },
    {
      text: 'learning.product_overview.duration',
      sortable: true,
      value: 'lead_time',
      display: true,
    },
    {
      text: 'learning.filters.product_type',
      sortable: false,
      value: 'product_type',
      display: true,
    },
    {
      text: 'learning.filters.theme',
      sortable: true,
      value: 'theme',
      display: true,
    },
    {
      text: 'learning.filters.course',
      sortable: false,
      value: 'course',
      display: true,
    },
  ],
  filters: [],
  columnsSorted: [],
  columnsSortedSubset: [],
  filtersSelected: [],
  filtersDisabledForSearch: ['format_version'],
  versionsFiltersSelected: {},
  accreditationsFiltersSelected: {},
  checklists: [],
  checklistsSelected: [],
  synonyms: [],
  synonymsSelected: [],
  coursesTableOptions: {},
})

export const actions = {
  async pullProducts({ commit, state }) {
    try {
      const response = await this.$axios.get('/learning-products')
      const learningProducts = response.data
      await commit('STORE_PRODUCTS', learningProducts)
    } catch (error) {
      console.log('pullProducts -> error', error)
    }
  },

  async setColumns({ commit, state }, arrayColumns = state.columns) {
    await commit('SORT_COLUMNS', arrayColumns)
  },
  async setFilters({ commit, state }, arrayFilters = state.filters) {
    await commit('SORT_FILTERS', arrayFilters)
  },
  async resetProduct({ commit }) {
    await commit('RESET_PRODUCT')
    await commit('RESET_COVER')
    await commit('RESET_TILE')
    await commit('RESET_SELECTED_SYNONYMS')
  },

  async storeProduct({ commit, state, rootGetters }, published = false) {
    // Set product to save as published
    if (published)
      await commit('UPDATE_FIELD', { field: 'published', value: 1 })
    if (state.local.in_the_picture)
      await commit('UPDATE_FIELD', { field: 'in_the_picture', value: 1 })
    if (state.local.for_members)
      await commit('UPDATE_FIELD', { field: 'for_members', value: 1 })
    if (state.local.voor_opleiders)
      await commit('UPDATE_FIELD', { field: 'voor_opleiders', value: 1 })

    // Check if remotely the product was already set as published
    const wasPublished = state.remote.published

    // If it has a parent_id, it's a draft of a product published
    const hasParentId = state.remote.parent_id

    // Preparing data
    //-----------------------------------------
    const formData = new FormData()

    for (let key in state.local) {
      if (state.local[key] && state.local[key] != 'null') {
        // If value is array/object, stringify that
        formData.append(
          key,
          typeof state.local[key] === 'object'
            ? JSON.stringify(state.local[key])
            : state.local[key]
        )
      } else {
        formData.append(key, '')
      }
    }

    if (state.tile.file) formData.append('tile', state.tile.file)
    else formData.delete('tile')

    if (state.cover.file) formData.append('cover', state.cover.file)
    else formData.delete('cover')

    if (state.local.parent_id == null) formData.delete('parent_id')

    // If wasn't published and we want to save as draft
    if (wasPublished && !published && !hasParentId) {
      formData.append('parent_id', state.remote.id)
      formData.delete('published')
      formData.delete('id')
    }

    if (rootGetters.synonymsHaveChanges) {
      formData.append(
        'synonymsSelected',
        JSON.stringify(state.synonymsSelected)
      )
    }

    if (!formData.get('published')) {
      formData.delete('published')
    }

    let slug = ''

    // console.log([...formData])
    await this.$axios
      .post('/learning-products', formData)
      .then((response) => {
        // 'Cause if it's published we close the page
        Promise.resolve(response)
        if (!published) commit('SET_PRODUCT', response.data)
        slug = response.data.slug
      })
      .catch((error) => Promise.reject(error))

    return slug
  },

  async deleteProduct({ dispatch, state }, productId) {
    if (!productId) return

    try {
      // $nuxt.$loading.start();
      await this.$axios.delete(`/learning-products/${productId}`)
      await dispatch('pullProducts')

      $nuxt.$loading.finish()
      $nuxt.$notifier.showMessage({
        content: `Product deleted`,
        color: 'success',
        icon: 'mdi-delete',
      })
    } catch (error) {
      console.log('deleteProduct -> error', error)
      $nuxt.$loading.finish()
      $nuxt.$notifier.showMessage({
        content: error,
        color: 'error',
        icon: 'mdi-close',
      })
    }
  },

  async removeSynonym({ commit, state }, synonymId) {
    if (!synonymId) return

    const backup = [...state.synonymsSelected]

    const synonymsFiltered = backup.filter((s) => s !== synonymId)

    commit('SELECT_SYNONYM', synonymsFiltered)
  },
}

export const mutations = {
  STORE_PRODUCTS: (state, products) => {
    state.products = []
    state.products = [...products]
  },
  SORT_COLUMNS: (state, columns) => {
    state.columnsSorted = columns
  },
  SET_COLUMNS_SUBSET: (state, columns) => {
    state.columnsSortedSubset = null
    state.columnsSortedSubset = columns
  },
  SORT_FILTERS: (state, filters) => {
    // Workaround because Vuex doesn't recognize changes otherwise
    state.filters = []
    state.filters = [...filters]
  },
  SET_PRODUCT: (state, product) => {
    state.remote = {}
    state.local = {}
    state.remote = Object.assign({}, product)
    state.local = Object.assign({}, product)

    // console.log(JSON.stringify(state.remote))
    // console.log(JSON.stringify(state.local))
  },
  RESET_PRODUCT: (state) => {
    state.remote = {}
    state.local = {}
    state.versionsFiltersSelected = {}
  },
  RESET_VERSIONS_FILTERS: (state) => {
    state.versionsFiltersSelected = {}
  },
  RESET_ACCREDITATIONS_FILTERS: (state) => {
    state.accreditationsFiltersSelected = {}
  },
  UPDATE_FIELD: (state, payload) => {
    state.local[payload.field] = payload.value
  },
  UPDATE_FILTERS: async (state, payload) => {
    if (payload.target === 'versions') {
      return Vue.set(
        state.versionsFiltersSelected,
        payload.filterId,
        Array.isArray(payload.value) ? payload.value : [payload.value]
      )

      // Workaround because Vuex doesn't recognize changes otherwise
      // let tmp = Object.assign({}, state.versionsFiltersSelected)
      // state.versionsFiltersSelected = {}
      // state.versionsFiltersSelected = Object.assign({}, tmp)

      // return state.versionsFiltersSelected[payload.filterId] = Array.isArray(payload.value)
      //     ? payload.value
      //     : [payload.value]
    }

    if (payload.target === 'accreditations') {
      return Vue.set(
        state.accreditationsFiltersSelected,
        payload.filterId,
        Array.isArray(payload.value) ? payload.value : [payload.value]
      )

      // Workaround because Vuex doesn't recognize changes otherwise
      // let tmp = Object.assign({}, state.accreditationsFiltersSelected)
      // state.accreditationsFiltersSelected = {}
      // state.accreditationsFiltersSelected = Object.assign({}, tmp)

      // return state.accreditationsFiltersSelected[payload.filterId] = Array.isArray(payload.value)
      //     ? payload.value
      //     : [payload.value]
    }

    if (!state.local['filtersGrouped']) state.local['filtersGrouped'] = {}

    state.local['filtersGrouped'][payload.filterId] = Array.isArray(
      payload.value
    )
      ? payload.value
      : [payload.value]
    state.local['filterItemsSelected'] = Object.values(
      state.local.filtersGrouped
    ).flat()
  },

  ADD_VERSION_LOCAL: (state, payload) => {
    // Workaround because Vuex doesn't recognize changes otherwise
    const tmp = [...state.local.versions]
    tmp.push(payload)

    state.local.versions = []
    state.remote.versions = []
    state.local.versions = [...tmp]
    state.remote.versions = [...tmp]
  },
  EDIT_VERSION_LOCAL: (state, payload) => {
    // Workaround because Vuex doesn't recognize changes otherwise
    let tmp = [...state.local.versions]
    tmp[payload.index] = Object.assign({}, payload.version)

    state.local.versions = []
    state.remote.versions = []
    state.local.versions = [...tmp]
    state.remote.versions = [...tmp]
  },
  DELETE_VERSION_LOCAL: (state, payload) => {
    const indexLocal = state.local.versions.indexOf(payload)
    const indexRemote = state.remote.versions.indexOf(payload)
    state.local.versions.splice(indexLocal, 1)
    state.remote.versions.splice(indexRemote, 1)
  },

  ADD_ACCREDITATION_LOCAL: (state, payload) => {
    // Workaround because Vuex doesn't recognize changes otherwise
    const tmp = [...state.local.accreditations]
    tmp.push(payload)

    state.local.accreditations = []
    state.local.accreditations = [...tmp]
  },
  EDIT_ACCREDITATION_LOCAL: (state, payload) => {
    // Workaround because Vuex doesn't recognize changes otherwise
    let tmp = [...state.local.accreditations]
    tmp[payload.index] = Object.assign({}, payload.accreditation)

    state.local.accreditations = []
    state.local.accreditations = [...tmp]
  },
  DELETE_ACCREDITATION_LOCAL: (state, payload) => {
    const index = state.local.accreditations.indexOf(payload)
    state.local.accreditations.splice(index, 1)
  },
  ADD_COURSE_NOTIFICATION_LOCAL: (state, payload) => {
    // Workaround because Vuex doesn't recognize changes otherwise
    const tmp = [...state.local.notifications]
    tmp.push(payload)

    state.local.notifications = []
    state.local.notifications = [...tmp]
  },
  EDIT_COURSE_NOTIFICATION_LOCAL: (state, payload) => {
    // Workaround because Vuex doesn't recognize changes otherwise
    let tmp = [...state.local.notifications]
    tmp[payload.index] = Object.assign({}, payload.notification)

    state.local.notifications = []
    state.local.notifications = [...tmp]
  },
  DELETE_COURSE_NOTIFICATION_LOCAL: (state, payload) => {
    const index = state.local.notifications.indexOf(payload)
    state.local.notifications.splice(index, 1)
  },
  RESET_TILE: (state) => {
    state.tile = {
      name: '',
      url: '',
      file: null,
    }
  },
  UPDATE_TILE: (state, payload) => {
    state.tile = payload
  },
  RESET_COVER: (state) => {
    state.cover = {
      name: '',
      url: '',
      file: null,
    }
  },
  UPDATE_COVER: (state, payload) => {
    state.cover = payload
  },
  SELECT_FILTERS: (state, payload) => {
    state.filtersSelected = payload
    state.coursesTableOptions.page = 1
  },
  REMOVE_SELECTED_FILTER: (state, payload) => {
    state.filtersSelected = state.filtersSelected.filter(
      (item) => item !== payload
    )
    state.coursesTableOptions.page = 1
  },

  SET_CHECKLIST: (state, checklists) => {
    // Workaround because Vuex doesn't recognize changes otherwise
    let tmp = [...checklists]
    state.checklists = []
    state.checklists = [...tmp]
  },

  RESET_CHECKLIST_SELECTED: (state) => (state.checklistsSelected = []),

  SET_CHECKED_CHECKLISTS: (state, payload) => {
    state.checklistsSelected = [...payload]
  },

  SELECT_CHECKLIST: (state, payload) => {
    state.checklistsSelected = payload
  },

  SET_SYNONYMS_LIST: (state, payload) => {
    state.synonyms = [...payload]
  },

  SELECT_SYNONYM: (state, payload) => {
    state.synonymsSelected = payload
  },

  RESET_SELECTED_SYNONYMS: (state) => {
    state.synonymsSelected = []
  },

  SET_COURSES_TABLE_OPTIONS: (state, payload) => {
    state.coursesTableOptions = {}
    state.coursesTableOptions = payload
  },
}
