
import { getPublicKey, login, getMe } from '@/api/backbone/user'
import { getGrantPermissions } from '@/api/permission'
import { getToken, setToken, removeToken, getPubKey, setPubKey, removePubKey } from '@/utils/auth'
import { resetRouter } from '@/router'
import AuthService from '@/utils/authService'

const state = {
  authService: process.env.VUE_APP_ONLY_SSO === 'true' ? new AuthService() : null,
  accessToken: getToken(),
  id: '',
  userName: '',
  name: '',
  email: '',
  phoneNumber: '',
  roles: [],
  avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
  permissions: [],
  publicKey: getPubKey()
}

const mutations = {
  SET_ACCESS_TOKEN: (state, accessToken) => {
    state.accessToken = accessToken
  },
  SET_ID: (state, id) => {
    state.id = id
  },
  SET_NAME: (state, name) => {
    state.name = name
  },
  SET_USER_NAME: (state, userName) => {
    state.userName = userName
  },
  SET_EMAIL: (state, email) => {
    state.email = email
  },
  SET_PHONE_NUMBER: (state, phoneNumber) => {
    state.phoneNumber = phoneNumber
  },
  SET_PERMISSIONS: (state, permissions) => {
    state.permissions = permissions
  },
  SET_ROLES: (state, roles) => {
    state.roles = roles
  },
  SET_PUBLIC_KEY: (state, key) => {
    state.publicKey = key
  }
}

const actions = {
  async preparePublicKey({ commit }) {
    var publicKeyRes = await getPublicKey()
    commit('SET_PUBLIC_KEY', publicKeyRes.publicKey)
    setPubKey(publicKeyRes.publicKey)
  },
  // user login
  async login({ commit }, userInfo) {
    const { username, password } = userInfo
    var publicKeyRes = await getPublicKey()
    commit('SET_PUBLIC_KEY', publicKeyRes.publicKey)
    setPubKey(publicKeyRes.publicKey)
    var res = await login(username, password, publicKeyRes.publicKey)
    commit('SET_ACCESS_TOKEN', res.access_token)
    setToken(res.access_token)
  },
  async loginOidc({ state }) {
    await state.authService.signIn()
  },
  async logoutOidc({ state }) {
    await state.authService.signOut()
  },
  async loginCallbackOidc({ commit }) {
    var publicKeyRes = await getPublicKey()
    commit('SET_PUBLIC_KEY', publicKeyRes.publicKey)
    setPubKey(publicKeyRes.publicKey)

    var user = await state.authService.signinRedirectCallback()
    commit('SET_ACCESS_TOKEN', user.access_token)
    setToken(user.access_token)
  },
  // get user info
  async getInfo({ commit }) {
    var user = await getMe()
    const { id, name, userName, emial, phoneNumber, roleNames } = user

    commit('SET_ID', id)
    commit('SET_NAME', name)
    commit('SET_USER_NAME', userName)
    commit('SET_EMAIL', emial)
    commit('SET_PHONE_NUMBER', phoneNumber)
    commit('SET_ROLES', roleNames)

    var permissions = await getGrantPermissions(user.id)
    commit('SET_PERMISSIONS', permissions)
    user.permissions = permissions
    return user
  },
  // user logout
  async logout({ commit, state, dispatch }) {
    commit('SET_ACCESS_TOKEN', '')
    commit('SET_ROLES', [])
    commit('SET_PERMISSIONS', [])
    commit('SET_PUBLIC_KEY', '')
    removeToken()
    removePubKey()
    resetRouter()

    // reset visited views and cached views
    // to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2485
    await dispatch('tagsView/delAllViews', null, { root: true })
  },
  // remove token
  resetToken({ commit }) {
    return new Promise(resolve => {
      commit('SET_ACCESS_TOKEN', '')
      removeToken()
      removePubKey()
      resolve()
    })
  }
}

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