import { defineStore } from 'pinia'
import { store } from '@/store'
import { CURRENT_USER, TENANT_ID, TOKEN_EXPIRATION_TIME, USER_ACCESS_TOKEN } from '@/store/mutation-types'
import { ResultEnum } from '@/enums/httpEnum'

import { getCaptchaToken, getInformation, getUserInfo as getUserInfoApi, login_new, refreshToken } from '@/api/system/user'
import { storage } from '@/utils/Storage'
import { generateUuid } from '@/utils/uuid'

let refreshIntervId: any
// 后台token有效期为30分钟
const TOKEN_EXPIRE_SECONDS = 30 * 60
// token刷新时间设置为20分钟
const TOKEN_REFRESH_SECONDS = 20 * 60

export interface UserInfoType {
  token: string
  tenantList: any[]
  userInfo: any
}

export interface IUserState {
  token: string
  username: string
  welcome: string
  avatar: string
  permissions: any[]
  uniqueKey: string
  info: any
  tenantId: string
  captchaToken: string
}

export const useUserStore = defineStore({
  id: 'app-user',
  state: (): IUserState => ({
    token: storage.get(USER_ACCESS_TOKEN, ''),
    username: '',
    welcome: '',
    avatar: '',
    permissions: [],
    captchaToken: '',
    uniqueKey: generateUuid(),
    info: storage.get(CURRENT_USER, {}),
    tenantId: storage.get(TENANT_ID, ''),
  }),
  getters: {
    getToken(): string {
      return this.token
    },
    getAvatar(): string {
      return this.avatar
    },
    getNickname(): string {
      return this.username
    },
    getPermissions(): [any][] {
      return this.permissions
    },
    getUserInfo(): any {
      return this.info
    },
    getUniqueKey(): string {
      return this.uniqueKey
    },
    // TODO:refactor
    getTenantId(): string {
      return this.tenantId
    },
    getCapToken(): string {
      return this.captchaToken
    },
  },
  actions: {
    setToken(token: string) {
      this.token = token
    },
    setAvatar(avatar: string) {
      this.avatar = avatar
    },
    setPermissions(permissions) {
      this.permissions = permissions
    },
    setUserInfo(info: any) {
      this.info = info
    },
    setCaptchaToken(token: string) {
      this.captchaToken = token
    },

    setTenantId(id: string) {
      this.tenantId = id
    },

    updateTenantId(id: string) {
      this.tenantId = id
      storage.set(TENANT_ID, id)
    },

    // 获取验证码token
    async getCaptchaToken(type: 'math' | 'char') {
      const result = await getCaptchaToken(type)
      const { data: token } = result
      this.setCaptchaToken(token)
      return token
    },

    // 登录
    async login(params: any) {
      const response = await login_new(params)
      const { data: token, code } = response
      if (code === ResultEnum.SUCCESS)
        this.setStorageToken(token)
        // this.startRefreshToken()

      return response
    },
    async getInformation() {
      const response = await getInformation()
      const { data, code } = response

      if (code === ResultEnum.SUCCESS) {
        const ex = 7 * 24 * 60 * 60
        // 默认设置为第一个租户
        const firstTenant = data.tenantList.length > 0 ? data.tenantList[0] : null
        const tenantId = firstTenant ? firstTenant.id : ''
        storage.set(CURRENT_USER, data, ex)
        storage.set(TENANT_ID, tenantId)
        this.setUserInfo(data)
        this.setTenantId(tenantId)
      }

      return response
    },
    // 刷新token
    async startRefreshToken() {
      if (!refreshIntervId)
        clearInterval(refreshIntervId)

      refreshIntervId = setInterval(async () => {
        const response = await refreshToken()
        const { data: token, code } = response
        if (code === ResultEnum.SUCCESS)
          this.setStorageToken(token)
      }, 25 * 60 * 1000)
    },
    // 刷新token
    async refreshToken() {
      // console.log('refresh token!')
      const response = await refreshToken()
      const { data: token, code } = response
      if (code === ResultEnum.SUCCESS)
        this.setStorageToken(token)

      return { token }
    },
    // 获取用户信息
    async getInfo() {
      const result = await getUserInfoApi()
      if (result.permissions && result.permissions.length) {
        const permissionsList = result.permissions
        this.setPermissions(permissionsList)
        this.setUserInfo(result)
      }
      else {
        throw new Error('getInfo: permissionsList must be a non-null array !')
      }
      this.setAvatar(result.avatar)
      return result
    },
    // 登出
    async logout() {
      this.setPermissions([])
      this.setUserInfo({ tenantList: [], userInfo: {}, token: '' })
      this.setTenantId('')
      storage.remove(USER_ACCESS_TOKEN)
      storage.remove(CURRENT_USER)
      clearInterval(refreshIntervId)
      refreshIntervId = null
    },
    setStorageToken(token) {
      storage.set(USER_ACCESS_TOKEN, token, TOKEN_EXPIRE_SECONDS)
      storage.set(TOKEN_EXPIRATION_TIME, Date.now() + TOKEN_REFRESH_SECONDS * 1000)
      this.setToken(token)
    },
  },
})

// Need to be used outside the setup
export function useUser() {
  return useUserStore(store)
}
