import Vue from 'vue'
import { resetRouter } from '@/router'
import { getTenantsByQuery } from '@/api/user'
import {
  Role,
  RoleAccess,
  Access
} from '@/constant'

const state = {
  token: '',
  tenantKey: '',
  tenantId: '',
  orgKey: '',
  id: '',
  name: '',
  avatar: '',
  roles: new Set(),
  accesses: new Set()
}

const mutations = {
  SET_TOKEN (state, token) {
    state.token = token
  },
  SET_TENANT_KEY (state, tenantKey) {
    console.log('tenant', tenantKey)
    state.tenantKey = tenantKey
  },
  SET_TENANT_ID (state, tenantId) {
    state.tenantId = tenantId
  },
  SET_ORG_KEY (state, orgKey) {
    console.log('org', orgKey)
    state.orgKey = orgKey
  },
  SET_ID (state, id) {
    console.log('user', id)
    state.id = id
  },
  SET_NAME (state, name) {
    state.name = name
  },
  SET_AVATAR (state, avatar) {
    state.avatar = avatar
  },
  SET_ROLES (state, roles) {
    console.log('roles', roles)
    state.roles = roles
  },
  SET_ACCESSES (state, accesses) {
    console.log('accesses', accesses)
    state.accesses = accesses
  }
}

function parseAccess (realmAccess, resourceAccess) {
  const roleSet = new Set([Role.VISITOR])
  const accessSet = new Set()
  if (realmAccess) {
    const roles = new Set(Object.values(Role))
    realmAccess.roles.forEach(role => {
      if (roles.has(role)) {
        roleSet.add(role)
      }
    })
  }
  roleSet.forEach(role => {
    RoleAccess[role].forEach(access => {
      accessSet.add(access)
    })
  })
  if (resourceAccess?.[process.env.VUE_APP_BACKEND_CLIENT]) {
    resourceAccess[process.env.VUE_APP_BACKEND_CLIENT].roles.forEach(role => {
      accessSet.add(role)
    })
  }
  return { roleSet, accessSet }
}

const actions = {
  async login ({ commit }, keycloak) {
    if (keycloak.authenticated) {
      const { tenant, sub, preferred_username, family_name, given_name, avatar } = keycloak.tokenParsed
      const { roleSet, accessSet } = parseAccess(keycloak.realmAccess, keycloak.resourceAccess)
      commit('SET_TOKEN', keycloak.token)
      if (tenant?.length) {
        tenant.sort((a, b) => a.length - b.length)
        commit('SET_TENANT_KEY', tenant[0])
        commit('SET_ORG_KEY', tenant[tenant.length - 1])
      } else if (accessSet.has(Access.MANAGE_TENANTS)) {
        try {
          const { data } = await getTenantsByQuery({ pageSize: 1, pageNum: 1 }, true)
          if (data.length) {
            commit('SET_TENANT_KEY', data[0].path)
            commit('SET_ORG_KEY', data[0].path)
          }
        } catch (e) {
          console.log(e)
        }
      }
      commit('SET_ID', sub)
      commit('SET_NAME', family_name && given_name ? `${family_name}${/[a-zA-z]/.test(family_name) ? ' ' : ''}${given_name}` : preferred_username)
      commit('SET_AVATAR', avatar)
      commit('SET_ROLES', roleSet)
      commit('SET_ACCESSES', accessSet)
    }
  },

  logout () {
    // 登出将跳转页面，所以不需其他操作
    Vue.prototype.$keycloak.logout()
  },

  clearToken ({ commit }) {
    commit('SET_TOKEN', '')
    commit('SET_TENANT_ID', '')
    Vue.prototype.$keycloak.refreshToken = null
    resetRouter()
  }
}

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