import type { ILoginRes } from '@/api/types/appointment'
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
import {
  loginByCode,
} from '@/api/appointment'
import { getWxCode } from '@/api/login'
import { useUserStore } from './user'

export const useTokenStore = defineStore(
  'token',
  () => {
    const token = ref<string>('')
    const tokenExpireTime = ref<number>(0)
    const nowTime = ref(Date.now())

    const updateNowTime = () => {
      nowTime.value = Date.now()
      return useTokenStore()
    }

    const setToken = (val: string, expiresIn: number = 86400) => {
      token.value = val
      tokenExpireTime.value = Date.now() + expiresIn * 1000
    }

    const isTokenExpired = computed(() => {
      if (!token.value) return true
      return nowTime.value >= tokenExpireTime.value
    })

    const hasLogin = computed(() => {
      return !!token.value && !isTokenExpired.value
    })

    const validToken = computed(() => {
      return hasLogin.value ? token.value : ''
    })

    /** 登录成功后处理 */
    async function _postLogin(res: ILoginRes) {
      setToken(res.token, 86400)
      const userStore = useUserStore()
      if (res.user_info) {
        userStore.setUserInfo(res.user_info)
      } else {
        await userStore.fetchUserInfo()
      }
    }

    /** 微信登录 */
    const wxLogin = async () => {
      try {
        const loginRes = await getWxCode()
        const res = await loginByCode(loginRes.code)
        await _postLogin(res)
        uni.showToast({ title: '登录成功', icon: 'success' })
        return res
      } catch (error) {
        console.error('微信登录失败:', error)
        uni.showToast({ title: '登录失败，请重试', icon: 'error' })
        throw error
      } finally {
        updateNowTime()
      }
    }

    /** 开发环境模拟登录 */
    const mockLogin = async (code: string) => {
      try {
        const res = await loginByCode(code)
        await _postLogin(res)
        uni.showToast({ title: '登录成功', icon: 'success' })
        return res
      } catch (error) {
        console.error('登录失败:', error)
        uni.showToast({ title: '登录失败，请重试', icon: 'error' })
        throw error
      } finally {
        updateNowTime()
      }
    }

    /** 退出登录 */
    const logout = async () => {
      updateNowTime()
      token.value = ''
      tokenExpireTime.value = 0
      const userStore = useUserStore()
      userStore.clearUserInfo()
    }

    return {
      token,
      tokenExpireTime,
      login: mockLogin,
      wxLogin,
      logout,
      hasLogin,
      validToken,
      setToken,
      updateNowTime,
    }
  },
  {
    persist: true,
  },
)