import { reactive } from 'vue'
import { login as loginApi, logout as logoutApi, getInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { resolveResourceUrl } from '@/utils/resourceUrl'
import { hasPartnerRole, normalizeRoles, PARTNER_ROLE_DENIED_MSG, shouldDenyPartnerLogin } from '@/utils/partnerRole'

const state = reactive({
  token: getToken(),
  id: '',
  name: '',
  nickName: '',
  avatar: '',
  phonenumber: '',
  roles: [],
  permissions: []
})

function resolveAvatar(path) {
  return resolveResourceUrl(path)
}

function clearSessionState() {
  state.token = ''
  state.roles = []
  state.permissions = []
  state.id = ''
  state.name = ''
  state.nickName = ''
  state.avatar = ''
  state.phonenumber = ''
  removeToken()
}

export function useUserStore() {
  const login = (userInfo) => {
    const username = (userInfo.username || '').trim()
    const password = userInfo.password
    const code = userInfo.code
    const uuid = userInfo.uuid
    return loginApi(username, password, code, uuid).then((res) => {
      const token = res.token
      setToken(token)
      state.token = token
      return res
    })
  }

  const fetchUserInfo = () => {
    return getInfo().then((res) => {
      const user = res.user || {}
      const roles = normalizeRoles(res.roles)

      if (shouldDenyPartnerLogin(roles)) {
        clearSessionState()
        logoutApi().catch(() => {})
        return Promise.reject(new Error(PARTNER_ROLE_DENIED_MSG))
      }

      state.roles = roles
      state.permissions = res.permissions || []
      state.id = user.userId
      state.name = user.userName
      state.nickName = user.nickName
      state.avatar = resolveAvatar(user.avatar)
      state.phonenumber = user.phonenumber || ''
      return res
    })
  }

  const logOut = () => {
    return logoutApi()
      .catch(() => {})
      .finally(() => {
        clearSessionState()
      })
  }

  const fedLogOut = () => {
    clearSessionState()
    return Promise.resolve()
  }

  const displayName = () => {
    return state.nickName || state.name || ''
  }

  const isLoggedIn = () => !!state.token && hasPartnerRole(state.roles)

  return {
    state,
    login,
    fetchUserInfo,
    logOut,
    fedLogOut,
    displayName,
    isLoggedIn
  }
}
