import { ref } from 'vue'
import { isStaffRole } from '@/config/menus'

const TOKEN_KEY = 'token'
const USER_KEY = 'user'
const EXPIRE_KEY = 'tokenExpireAt'

const sessionExpired = ref(false)
let sessionExpiredHandled = false
let expiryTimer: ReturnType<typeof setTimeout> | null = null

export interface AuthUser {
  id: number
  username: string
  email?: string
  avatar?: string
  role?: string
  [key: string]: unknown
}

export function useAuth() {
  const getToken = () => uni.getStorageSync(TOKEN_KEY) as string || ''

  const getTokenExpireAt = (): number => {
    const raw = uni.getStorageSync(EXPIRE_KEY)
    return raw ? Number(raw) : 0
  }

  const isAuthenticated = (): boolean => {
    const token = getToken()
    if (!token) return false
    const expireAt = getTokenExpireAt()
    if (expireAt > 0 && Date.now() >= expireAt) return false
    return true
  }

  const getUser = (): AuthUser => {
    try {
      const raw = uni.getStorageSync(USER_KEY)
      if (!raw) return {} as AuthUser
      return typeof raw === 'string' ? JSON.parse(raw) : raw
    }
    catch {
      return {} as AuthUser
    }
  }

  const setUser = (user: AuthUser) => {
    uni.setStorageSync(USER_KEY, JSON.stringify(user))
  }

  const clearExpiryTimer = () => {
    if (expiryTimer) {
      clearTimeout(expiryTimer)
      expiryTimer = null
    }
  }

  const handleSessionExpired = () => {
    if (sessionExpiredHandled) return
    sessionExpiredHandled = true
    sessionExpired.value = true
  }

  const scheduleExpiryCheck = () => {
    clearExpiryTimer()
    const expireAt = getTokenExpireAt()
    if (!expireAt) return
    const delay = expireAt - Date.now()
    if (delay <= 0) {
      handleSessionExpired()
      return
    }
    expiryTimer = setTimeout(() => handleSessionExpired(), delay)
  }

  const login = (token: string, user: AuthUser, expireUnixSeconds: number) => {
    uni.setStorageSync(TOKEN_KEY, token)
    uni.setStorageSync(USER_KEY, JSON.stringify(user))
    uni.setStorageSync(EXPIRE_KEY, String(expireUnixSeconds * 1000))
    sessionExpiredHandled = false
    sessionExpired.value = false
    scheduleExpiryCheck()

    // sync loginType
    uni.setStorageSync('loginType', isStaffRole(user.role) ? 'staff' : 'guest')
  }

  const logout = () => {
    clearExpiryTimer()
    uni.removeStorageSync(TOKEN_KEY)
    uni.removeStorageSync(USER_KEY)
    uni.removeStorageSync(EXPIRE_KEY)
    uni.setStorageSync('loginType', 'guest')
    uni.setStorageSync('appMode', 'user')
    sessionExpiredHandled = false
    sessionExpired.value = false
  }

  const confirmSessionExpired = () => {
    logout()
    uni.reLaunch({ url: '/pages/mine/index' })
  }

  return {
    sessionExpired,
    getToken,
    getUser,
    setUser,
    isAuthenticated,
    login,
    logout,
    handleSessionExpired,
    confirmSessionExpired,
    scheduleExpiryCheck,
  }
}
