import type { UserInfo } from '/#/store'
import type { ErrorMessageMode } from '/@/utils/http/axios/types'
import { defineStore } from 'pinia'
import { store } from '/@/store'

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

import { getAuthCache, setAuthCache, getToken, removeAuthCache } from '/@/utils/auth'
import {
  GetUserInfoByUserIdModel,
  GetUserInfoModel,
  // GetUserInfoByUserIdParams,
  LoginParams
} from '/@/api/sys/model/userModel'

import { loginApi, getXsrfToken, logoutApi, getAccountGroupList, getUserInfo } from '/@/api/sys/user'

import { useI18n } from '/@/hooks/web/useI18n'
import { useMessage } from '/@/hooks/web/useMessage'
import { router } from '/@/router'
import { PermGroupItem } from '/@/api/sys/model/managerModel'
import { getPermGroupList } from '/@/api/sys/manager'

interface UserState {
  userInfo: Nullable<GetUserInfoModel>
  token?: string
  roleList: RoleEnum[]
  accountGroups: string[]
  permGroups: PermGroupItem[]
}

export const useUserStore = defineStore({
  id: 'app-user',
  state: (): UserState => ({
    // user info
    userInfo: null,
    // token
    token: undefined,
    // roleList
    rolesList: [],
    accountGroups: [],
    permGroups: [],
    // Whether the login expired
    sessionTimeout: false
  }),
  getters: {
    getUserInfo(): GetUserInfoModel {
      return this.userInfo || getAuthCache<GetUserInfoModel>(USER_INFO_KEY) || {}
    },
    getToken(): string {
      return this.token || getAuthCache<string>(TOKEN_KEY)
    },
    getRoleList(): RoleEnum[] {
      return this.rolesList.length ? this.rolesList : getAuthCache<RoleEnum[]>(ROLES_KEY)
    },
    getGroupList(): string[] {
      return this.accountGroups
    },
    getPermGroupList(): PermGroupItem[] {
      return this.permGroups
    },
    getSessionTimeout(): boolean {
      return !!this.sessionTimeout
    }
  },
  actions: {
    setToken(info: string) {
      this.token = info
      setAuthCache(TOKEN_KEY, info)
    },
    setRoleList(roleList: RoleEnum[]) {
      console.log('roleList', roleList)

      this.rolesList = roleList
      setAuthCache(ROLES_KEY, roleList)
    },
    setUserInfo(info: UserInfo) {
      this.userInfo = info
      setAuthCache(USER_INFO_KEY, info)
    },
    setGroupList(groupList: string[]) {
      this.accountGroups = groupList
    },
    setPermGroupList(permList: PermGroupItem[]) {
      this.permGroups = permList
    },
    setSessionTimeout(flag: boolean) {
      this.sessionTimeout = flag
    },
    resetState() {
      this.userInfo = null
      this.token = ''
      this.rolesList = []
      this.sessionTimeout = false
    },
    /**
     * @description: login
     */
    async login(
      params: LoginParams & {
        goHome?: boolean
        mode?: ErrorMessageMode
      }
    ): Promise<GetUserInfoByUserIdModel | null> {
      try {
        const { goHome = true, mode, ...loginParams } = params

        await loginApi(loginParams, mode)
        // get user info
        const userInfo = await this.getUserInfoAction()
        // const roleList = roles.map(item => item.value) as RoleEnum[]
        const sessionTimeout = this.sessionTimeout
        sessionTimeout && this.setSessionTimeout(false)
        !sessionTimeout && goHome && (await router.replace(PageEnum.BASE_HOME))
        return userInfo
        return true
      } catch (error) {
        return Promise.reject(error)
      }
    },

    async getUserInfoAction() {
      const userInfo = await getUserInfo()
      this.setUserInfo({ ...userInfo })
      if (userInfo?.isAdmin) {
        this.setRoleList([RoleEnum.ADMIN])
      } else {
        this.setRoleList(userInfo.roles)
      }

      return userInfo
    },
    async fetchGroupList() {
      try {
        const data = await getAccountGroupList()
        const accountGroups: any[] = []
        for (const key in data) {
          if (Object.prototype.hasOwnProperty.call(data, key)) {
            const item = data[key]
            if (item) {
              accountGroups.push({ label: item, value: parseInt(key) })
            }
          }
        }
        this.setGroupList(accountGroups)
      } catch (error) {
        return null
      }
    },

    async fetchPermGroupList() {
      try {
        const { items } = await getPermGroupList({ page: 1, pageSize: 100 })
        this.setPermGroupList(items)
      } catch (error) {
        return null
      }
    },

    async getToken() {
      await getXsrfToken('gs01')
      const token = getToken() as string
      this.setToken(token)
    },

    /**
     * @description: logout
     */
    async logout(goLogin = false) {
      await logoutApi()
      removeAuthCache(TOKEN_KEY)
      goLogin && router.push(PageEnum.BASE_LOGIN)
    },

    /**
     * @description: Confirm before logging out
     */
    confirmLoginOut() {
      const { createConfirm } = useMessage()
      const { t } = useI18n()
      createConfirm({
        iconType: 'warning',
        title: t('sys.app.logoutTip'),
        content: t('sys.app.logoutMessage'),
        onOk: async () => {
          await this.logout(true)
        }
      })
    }
  }
})

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