import { useNavigate } from 'react-router'
import { create } from 'zustand'
import { createJSONStorage, persist } from 'zustand/middleware'
import type { UserInfo, UserToken } from '#/entity'
import { StorageEnum } from '#/enum'
import { loginByUsername } from '@/api/services/login'
import { getMenu } from '@/api/services/menu'
import { deepClone, encryption } from '@/utils/util'
import { isURL } from '@/utils/validate'
import type { ILoginForm } from '@/pages/sys/login/LoginForm'

// import { useMutation } from '@tanstack/react-query'
// import { toast } from 'sonner'
// import userService, { type SignInReq } from '@/api/services/userService'

// const { VITE_APP_HOMEPAGE: HOMEPAGE } = import.meta.env

function addPath(ele: API.MenuResultItem & Record<string, any>, first?: boolean) {
  const menu = {
    props: {
      label: 'name',
      path: 'path',
      icon: 'icon',
      children: 'children'
    }
  }
  const propsConfig = menu.props
  const propsDefault = {
    label: propsConfig.label || 'name',
    path: propsConfig.path || 'path',
    icon: propsConfig.icon || 'icon',
    children: propsConfig.children || 'children'
  }
  const isChild = ele[propsDefault.children] && ele[propsDefault.children].length !== 0
  if (!isChild) ele[propsDefault.children] = []
  if (!isChild && first && !isURL(ele[propsDefault.path])) {
    ele[propsDefault.path] = ele[propsDefault.path] + '/index'
  } else {
    ele[propsDefault.children].forEach((child: API.MenuChildrenItem) => {
      addPath(child)
    })
  }
}

type UserStore = {
  userInfo: Partial<UserInfo>
  tenantInfo: Partial<API.UserDetail>
  permissions: Record<string, boolean>
  menu: API.MenuResult

  userToken: UserToken
  expires_in: number | null
  tenant_id?: number
  access_token: string
  refresh_token: string
  // 使用 actions 命名空间来存放所有的 action
  actions: {
    setUserInfo: (userInfo: UserInfo) => void
    setTenantId: (tenant_id: number) => void
    setExpiresIn: (expires_in: number) => void
    setAccessToken: (access_token: string) => void
    setRefreshToken: (refresh_token: string) => void
    setMenu: (params: { menu?: UserStore['menu']; type?: boolean }) => void
    setPermissions: (permissions: string[]) => void
    setUserToken: (token: UserToken) => void
    clearUserInfoAndToken: () => void
  }
}

export const useUserSessionStore = create<UserStore>()(
  persist(
    (set) => ({
      userInfo: {},
      tenantInfo: {},
      permissions: {},
      menu: [],
      expires_in: null,
      tenant_id: undefined,
      access_token: '',
      refresh_token: '',
      userToken: {},
      actions: {
        setUserInfo: (userInfo) => {
          set({ userInfo })
        },
        setTenantId: (tenant_id) => {
          set({ tenant_id })
        },
        setExpiresIn: (expires_in) => {
          set({ expires_in })
        },
        setAccessToken: (access_token) => {
          set({ access_token })
        },
        setRefreshToken: (refresh_token) => {
          set({ refresh_token })
        },
        setMenu: (params = {}) => {
          const { menu, type } = params
          if (type !== false) set({ menu: menu as UserStore['menu'] })
        },
        setPermissions: (permissions) => {
          const list: Record<string, boolean> = {}
          for (let i = 0; i < permissions.length; i++) {
            list[permissions[i]] = true
          }
          set({ permissions: list })
        },

        setUserToken: (userToken) => {
          set({ userToken })
        },
        clearUserInfoAndToken() {
          set({ userInfo: {}, userToken: {} })
        }
      }
    }),
    {
      name: 'userSessionStore', // name of the item in the storage (must be unique)
      storage: createJSONStorage(() => sessionStorage), // (optional) by default, 'localStorage' is used
      partialize: (state) => ({
        [StorageEnum.TenantId]: state.tenant_id,
        [StorageEnum.AccessToken]: state.access_token,
        [StorageEnum.ExpiresIn]: state.expires_in,
        [StorageEnum.RefreshToken]: state.refresh_token,
        [StorageEnum.UserInfo]: state.userInfo,
        [StorageEnum.TenantInfo]: state.tenantInfo,
        [StorageEnum.Menu]: state.menu,
        [StorageEnum.Permissions]: state.permissions
      })
    }
  )
)
// 如果需要持久化到localStorage, 则使用下面的代码
// type UserLocalStore = {
//   actions: {}
// }
// const useUserLocalStore = create<UserLocalStore>()(
//   persist(
//     (_set) => ({
//       actions: {}
//     }),
//     {
//       name: 'userLocalStore', // name of the item in the storage (must be unique)
//       storage: createJSONStorage(() => localStorage), // (optional) by default, 'localStorage' is used
//       partialize: (_state) => ({})
//     }
//   )
// )

// 如果需要在一个store中分别持久化到localStorage和sessionStorage, 则使用下面的代码合并sessionStore和localStore. 否则直接导出一个store即可.
const useUserStore = () => {
  const userSessionStore = useUserSessionStore()
  // const userLocalStore = useUserLocalStore();

  return {
    ...userSessionStore,
    // ...userLocalStore,
    actions: {
      ...userSessionStore.actions
      // ...userLocalStore.actions,
    }
  }
}

export const useUserInfo = () => useUserSessionStore((state) => state.userInfo)
export const useTenantId = () => useUserSessionStore((state) => state.tenant_id)
export const useExpiresIn = () => useUserSessionStore((state) => state.expires_in)
export const useAccessToken = () => useUserSessionStore((state) => state.access_token)
export const useRefreshToken = () => useUserSessionStore((state) => state.refresh_token)
export const useUserToken = () => useUserSessionStore((state) => state.userToken)
export const useUserMenu = () => useUserSessionStore((state) => state.menu)
export const useUserPermission = () => useUserSessionStore((state) => state.userInfo.permissions)
export const useUserActions = () => useUserSessionStore((state) => state.actions)

// export const useSignIn = () => {
//   const navigatge = useNavigate()
//   const { setUserToken, setUserInfo } = useUserActions()

//   const signInMutation = useMutation({
//     mutationFn: userService.signin
//   })

//   const signIn = async (data: SignInReq) => {
//     try {
//       const res = await signInMutation.mutateAsync(data)
//       const { user, accessToken, refreshToken } = res
//       setUserToken({ accessToken, refreshToken })
//       setUserInfo(user)
//       navigatge(HOMEPAGE, { replace: true })
//       toast.success('Sign in success!')
//     } catch (err) {
//       toast.error(err.message, {
//         position: 'top-center'
//       })
//     }
//   }

//   return signIn
// }

// 根据用户名登录
export const useLoginByUsername = () => {
  const navigate = useNavigate()
  const getMenuFn = useGetMenu()
  const { setAccessToken, setRefreshToken, setExpiresIn } = useUserActions()
  const loginFn = (userInfo: Omit<ILoginForm, 'tenant_name'>) => {
    console.log(userInfo)
    const user = encryption({
      data: userInfo,
      key: 'REmAZJQfbiDpdXCf',
      param: ['password']
    })
    console.log(user)
    return new Promise<void>((resolve, reject) => {
      loginByUsername(user.username, user.password, user.code, user.randomStr)
        .then(async (res) => {
          if (res) {
            const data = res
            setAccessToken(data.access_token)
            setRefreshToken(data.refresh_token)
            setExpiresIn(data.expires_in)
            // await loadRoutes(router)
            await getMenuFn()
            // 跳转到首页
            navigate('/system/auth/user/index')
            resolve()
          } else {
            reject('获取用户信息失败')
          }
        })
        .catch((err) => {
          reject(err)
        })
    })
  }
  return loginFn
}

export const useGetMenu = () => {
  const { setMenu } = useUserActions()
  return (obj?: { id?: number; type?: boolean }) => {
    return new Promise((resolve) => {
      getMenu(obj?.id as number).then((res) => {
        if (res) {
          console.log(res)
          const data = res.data
          const menu: API.MenuResult = deepClone(data)
          menu.forEach((ele) => {
            addPath(ele)
          })
          const type = obj?.type
          setMenu({
            type,
            menu
          })
          resolve(menu)
        }
      })
    })
  }
}

export default useUserStore
