import { REST } from 'vuejs/api/rest-axios'
// import { JSONAPI } from 'vuejs/api/json-axios'
import { MA } from 'vuejs/api/ma-axios'
import qs from 'querystring-es3'

import materiauGQL from 'vuejs/api/gql/materiauflaglist.fragment.gql'

// import router from 'vuejs/route' // this is not working

export default {
  namespaced: true,
  // router,

  // initial state
  state: {
    uid: null,
    // username: '',
    mail: '',
    csrf_token: null,
    logout_token: null,
    loginMessage: '',
    registerMessage: '',
    isloggedin: false,
    isAdmin: false,
    isAdherent: false,
    canSearch: false,
    roles: [],
    flagcolls: false,
    flagcollsLoadedItems: {},
    openedCollid: null
  },

  // getters
  getters: {},

  // mutations
  mutations: {
    SetCsrftoken (state, token) {
      console.log('SetCsrftoken', token)
      state.csrf_token = token
    },
    setToken (state, data) {
      console.log('setToken', data)
      state.uid = data.current_user.uid
      // state.username = data.username;
      state.mail = data.current_user.mail
      state.csrf_token = data.csrf_token
      state.isloggedin = true
      state.logout_token = data.logout_token
    },
    setLoginMessage (state, message) {
      console.log('setLoginMessage', message);
      state.loginMessage = message
    },
    setRegisterMessage (state, message) {
      console.log('setRegisterMessage', message);
      state.registerMessage = message
    },
    setUid (state, uid) {
      state.uid = uid
      state.isloggedin = true
    },
    setUser (state, data) {
      state.mail = data.mail[0].value
      state.uuid = data.uuid[0].value
    },
    setRoles (state, roles) {
      console.log('User setRoles', roles)
      state.roles = []
      for (let i = 0; i < roles.length; i++) {
        state.roles.push(roles[i].target_id)
      }
      // check if admin
      if (
        state.roles.indexOf('admin') !== -1 ||
        state.roles.indexOf('root') !== -1
      ) {
        // console.log('is admin');
        state.isAdmin = true
      }
      // check if has access to search
      if (state.roles.indexOf('adherent') !== -1) {
        // console.log('is admin');
        state.canSearch = true
        state.isAdherent = true
      }
    },
    setLoggedOut (state) {
      console.log('setLoggedOut state', state)
      state.uid = null
      state.mail = ''
      state.csrf_token = null
      state.isloggedin = false
      state.logout_token = null
      state.asAdmin = false
      state.canSearch = false
      // if (state.isAdmin) {
      //   // TODO: what if on a page where login is needed (as commerce checkout and cart)
      //   window.location.reload(true)
      // } else {
      //
      //   // return systematically to home page
      //   this.$router.push({
      //     name:`home`
      //     // params: { alias:this.alias }
      //     // query: { nid: this.item.nid }
      //     // meta: { uuid:this.item.uuid },
      //   })
      // }

      // redirect to home page in every case
      window.location = window.location.origin
    },
    setFlagColls (state, flagcolls) {
      console.log('User pre setFlagColls', state.flagcolls)
      state.flagcolls = flagcolls
      // console.log('User post setFlagColls', state.flagcolls)
    },
    openFlagColl (state, collid) {
      state.openedCollid = collid
    },
    closeFlagColl (state) {
      state.openedCollid = null
    },
    setLoadedCollItems (state, data) {
      console.log('setLoadedCollItems', data)
      // if no data, we are just calling the mutation to trigger the component update
      if (data) {
        state.flagcollsLoadedItems[data.collid] = data.items
      }
    }
  },

  // actions
  actions: {
    userRegister ({ dispatch, commit, state }, credentials) {
      return new Promise((resolve) => {
        REST.get('/session/token').then(({ token }) => {
          commit('SetCsrftoken', token)
          REST.post('/user/register?_format=json', credentials, {
            'X-CSRF-Token': state.csrftoken,
            validateStatus: function (status) {
                return status >= 200 && status < 500;
            }
          })
            .then((response) => {
              console.log('user REST registered', response)
              if(response.status === 200){
                dispatch('userLogin', credentials).then(() => {
                  resolve()
                })
              }else{
                let message = ''
                switch (response.status) {
                  case 422:
                    message = "email is already registered"
                    break;
                  default:
                    message = response.data.message
                }
                commit('setRegisterMessage', message)
              }
            })
            .catch(error => {
              console.warn('Issue with register', error)
              Promise.reject(error)
            })
        })
      })
    },
    userLogin ({ dispatch, state }, credentials) {
      return new Promise((resolve, reject) => {
        dispatch('getToken', credentials)
          // TODO: catch failed login
          .then(() => {
            // there no response here, check the original getToken method
            // console.log('dispatch getToken response', response);
            // check if getToken (login) went well
            if(state.isloggedin){
              dispatch('getUser').then(userdata => {
                console.log('User Loggedin')
                if (state.isAdmin) {
                  window.location.reload(true)
                }
                resolve()
              })
            }else{
              console.log('user loggein failed')
              Promise.reject('user loggein failed')
            }
          })
          .catch(error => {
            console.warn('Issue with Dispatch getToken', error)
            Promise.reject(error)
          })
      })
    },
    getToken ({ dispatch, commit, state }, credentials) {
      return REST.post('/user/login?_format=json',
        credentials,
        {
          validateStatus: function (status) {
              return status >= 200 && status < 500;
          }
        })
        .then((response) => {
          console.log('user REST getToken response', response)
          if(response.status === 200){
            commit('setToken', response.data)
          }else if(response.data.message){
            commit('setLoginMessage', response.data.message)
          }else{
            console.warn('Issue with getToken', response)
          }
        })
        .catch(error => {
          console.warn('Issue with getToken', error)
          Promise.reject(error)
        })
    },
    getUser ({ dispatch, commit, state }) {
      return new Promise((resolve, reject) => {
        REST.get('/session/token').then(({ data }) => {
          console.log('csrftoken', data)
          commit('SetCsrftoken', data)
          console.log('state.csrf_token', state.csrf_token)
          const params = {
            token: state.csrf_token
          }
          REST.get(`/user/${state.uid}?_format=json`, params)
            .then(({ data }) => {
              console.log('user REST getUser data', data)
              console.log('roles', data.roles)
              commit('setUser', data)
              if (data.roles) {
                commit('setRoles', data.roles)
              }
              dispatch('getUserFlagColls')
              resolve()
            })
            .catch(error => {
              console.warn('Issue with getUser', error)
              Promise.reject(error)
            })
        })
      })
    },
    getUserFlagColls ({ dispatch, commit, state }) {
      // flags
      // REST.get('/flagging_collection/1?_format=json')
      //   .then(( data ) => {
      //     console.log('TEST FLAG REST data', data)
      //   })
      //   .catch(error => {
      //       console.warn('Issue USER TEST FLAG REST', error)
      //       Promise.reject(error)
      //   })

      return MA.get('materio_flag/user_flagging_collections')
        .then(({ data }) => {
          console.log('user MA getFlags data', data)
          commit('setFlagColls', data)
        })
        .catch(error => {
          console.warn('Issue USER MA getFlags', error)
          Promise.reject(error)
        })
    },
    // https://drupal.stackexchange.com/questions/248539/cant-get-flagging-api-to-accept-post-request
    createFlagColl ({ dispatch, commit, state }, new_collection_name) {
      console.log('user createFlagColl', new_collection_name)
      return new Promise((resolve, reject) => {
        const params = {
          name: new_collection_name
        }
        MA.post('materio_flag/create_user_flagging_collection', params)
          .then(({ data }) => {
            console.log('user MA createFlagColl data', data)
            if (data.status) {
              dispatch('getUserFlagColls').then(() => {
                resolve(data)
              })
            }
          })
          .catch(error => {
            console.warn('Issue USER MA createFlag', error)
            reject(error)
          })
      })
    },
    deleteFlagColl ({ dispatch, commit, state }, flagcollid) {
      console.log('user deleteFlagColl', flagcollid)
      return new Promise((resolve, reject) => {
        const params = {
          flagcollid: flagcollid
        }
        MA.post('materio_flag/delete_user_flagging_collection', params)
          .then(({ data }) => {
            console.log('user MA deleteFlagColl data', data)
            dispatch('getUserFlagColls').then(() => {
              resolve()
            })
          })
          .catch(error => {
            console.warn('Issue USER MA createFlag', error)
            reject(error)
          })
      })
    },
    flagUnflag ({ dispatch, commit, state }, { action, id, collid }) {
      console.log('user flagUnflag', action, id, collid)
      return new Promise((resolve, reject) => {
        const params = {
          flagid: state.flagcolls[collid].flag_id,
          id: id,
          flagcollid: collid
        }
        return MA.post(`materio_flag/${action}`, params)
          .then(({ data }) => {
            console.log('user MA flag', data)
            // reload the fulllist of flagcolleciton
            dispatch('getUserFlagColls').then(() => {
              if (state.flagcolls[collid].items.length) {

                dispatch('loadMaterialsGQL', {
                  ids: state.flagcolls[collid].items,
                  gqlfragment: materiauGQL,
                  callBack: 'loadMaterialsCallBack',
                  callBackArgs: { collid: collid }
                }).then(() => {
                  resolve()
                })

                // dispatch('loadMaterials', {
                //   uuids: state.flagcolls[collid].items_uuids,
                //   imgStyle: ['card_medium_half'],
                //   callBack: 'loadMaterialsCallBack',
                //   callBackArgs: { collid: collid }
                // }).then(() => {
                //   resolve()
                // })
              } else {
                commit('setLoadedCollItems', { collid: collid, items: [] })
                resolve()
              }
            })
          })
          .catch(error => {
            console.warn('Issue USER MA flagUnflag', error)
          })
      })
    },
    openFlagColl ({ commit, dispatch, state }, collid) {
      console.log('user openFlagColl', collid)
      commit('openFlagColl', collid)
      if (state.flagcolls[collid].items.length) {
        if (typeof state.flagcollsLoadedItems[collid] === 'undefined') {
          console.log('loading flagcoll items', state.flagcolls[collid])
          // if no loadedItems, load them
          // loadMaterials is on mixins
          // https://github.com/huybuidac/vuex-extensions

          dispatch('loadMaterialsGQL', {
            ids: state.flagcolls[collid].items,
            gqlfragment: materiauGQL,
            callBack: 'loadMaterialsCallBack',
            callBackArgs: { collid: collid }
          })

          // dispatch('loadMaterials', {
          //   uuids: state.flagcolls[collid].items_uuids,
          //   imgStyle: ['card_medium_half'],
          //   callBack: 'loadMaterialsCallBack',
          //   callBackArgs: { collid: collid }
          // })

        } else {
          // call the mutation without data to only trigger the FlagCollection component update
          console.log('committing setLoadedCollItems without args')
          commit('setLoadedCollItems')
        }
      } else {
        commit('setLoadedCollItems', { collid: collid, items: [] })
      }
    },
    loadMaterialsCallBack ({ commit }, { items, callBackArgs }) {
      console.log('user loadMaterialsCallBack', items, callBackArgs)
      commit('setLoadedCollItems', { collid: callBackArgs.collid, items: items })
    },
    closeFlagColl ({ commit, dispatch }) {
      console.log('user closeFlagColl')
      commit('closeFlagColl')
    },
    userLogout ({ commit, state }) {
      const credentials = qs.stringify({
        token: state.csrf_token
      })
      REST.post('/user/logout', credentials)
        .then(resp => {
          console.log('userLogout resp', resp)
          commit('setLoggedOut')
        })
        .catch(error => {
          console.warn('Issue with logout', error)
          Promise.reject(error)
        })
    }
  }
}
