import type { LoginParams, GetUserInfoByUserIdModel } from '/@/api/sys/model/userModel'
import type { UserInfo } from '/@/store/types'

import store from '/@/store/index'
import { VuexModule, Module, getModule, Mutation, Action } from 'vuex-module-decorators'
import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper'

import { PageEnum } from '/@/enums/pageEnum'
import { RoleEnum } from '/@/enums/roleEnum'
import { ROLES_KEY, TOKEN_KEY, USER_INFO_KEY } from '/@/enums/cacheEnum'

import { useMessage } from '/@/hooks/web/useMessage'

import router from '/@/router'

import { loginApi, getUserInfoById } from '/@/api/sys/user'

import { useI18n } from '/@/hooks/web/useI18n'
import { ErrorMessageMode } from '/@/utils/http/axios/types'
import { getAuthCache, getToken, removeAuthCache, setAuthCache } from '/@/utils/auth/index'
import { mainOutRoutes } from '/@/router/routes/mainOut'
import { PreviewRoute } from '/@/router/routes'

const NAME = 'app-user'
hotModuleUnregisterModule(NAME)

@Module({ namespaced: true, name: NAME, dynamic: true, store })
class User extends VuexModule {
  // user info
  private userInfoState: UserInfo | null = null

  // token
  private tokenState = ''

  // roleList
  private roleListState: RoleEnum[] = []

  get getUserInfoState(): UserInfo {
    return this.userInfoState || getAuthCache<UserInfo>(USER_INFO_KEY) || {}
  }

  get getTokenState(): string {
    return this.tokenState || getAuthCache<string>(TOKEN_KEY)
  }

  get getRoleListState(): RoleEnum[] {
    return this.roleListState.length > 0 ? this.roleListState : getAuthCache<RoleEnum[]>(ROLES_KEY)
  }

  @Mutation
  commitResetState(): void {
    this.userInfoState = null
    this.tokenState = ''
    this.roleListState = []
  }

  @Mutation
  commitUserInfoState(info: UserInfo): void {
    this.userInfoState = info
    setAuthCache(USER_INFO_KEY, info)
  }

  @Mutation
  commitRoleListState(roleList: RoleEnum[]): void {
    this.roleListState = roleList
    setAuthCache(ROLES_KEY, roleList)
  }

  @Mutation
  commitTokenState(info: string): void {
    this.tokenState = info
    setAuthCache(TOKEN_KEY, info)
  }

  /**
   * @description: login
   */
  @Action
  async login(
    params: LoginParams & {
      goHome?: boolean
      mode?: ErrorMessageMode
    }
  ): Promise<GetUserInfoByUserIdModel | null> {
    try {
      const { goHome = true, mode, ...loginParams } = params

      const data = await loginApi(loginParams, mode)

      const { token } = data

      // save token
      this.commitTokenState(token)
      // get user info
      const userInfo = await this.getUserInfoAction()

      goHome && (await router.replace('/home'))
      return userInfo
    } catch (error) {
      return null
    }
  }

  @Action
  async getUserInfoAction() {
    const userInfo = await getUserInfoById()
    const roles = ['super']
    const roleList = roles.map(item => item) as RoleEnum[]
    this.commitUserInfoState(userInfo)
    this.commitRoleListState(roleList)
    return userInfo
  }

  /**
   * @description: logout
   */
  @Action
  async logout(goLogin = false) {
    goLogin && router.push(PageEnum.BASE_LOGIN)
    // if (!goLogin && !router.hasRoute('Preview')) {
    //   router.addRoute('', PreviewRoute)
    // }
    !goLogin && router.push(PageEnum.BASE_HOME)
  }

  /**
   * @description: Confirm before logging out
   */
  @Action
  async confirmLoginOut() {
    const { createConfirm } = useMessage()
    const { t } = useI18n()
    createConfirm({
      iconType: 'warning',
      title: t('sys.app.logoutTip'),
      content: t('sys.app.logoutMessage'),
      onOk: async () => {
        removeAuthCache(ROLES_KEY)
        removeAuthCache(TOKEN_KEY)
        removeAuthCache(USER_INFO_KEY)
        await this.logout(false)
      }
    })
  }
}
export const userStore = getModule<User>(User)
