import { ref } from 'vue'
import router from '../router'

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 function useAuth() {
  const getToken = () => localStorage.getItem(TOKEN_KEY)

  const getTokenExpireAt = (): number => {
    const raw = localStorage.getItem(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 login = (token: string, user: unknown, expireUnixSeconds: number) => {
    localStorage.setItem(TOKEN_KEY, token)
    localStorage.setItem(USER_KEY, JSON.stringify(user))
    localStorage.setItem(EXPIRE_KEY, String(expireUnixSeconds * 1000))
    sessionExpiredHandled = false
    sessionExpired.value = false
    scheduleExpiryCheck()
  }

  const logout = (showToast?: (msg: string, type: 'success' | 'error') => void) => {
    clearExpiryTimer()
    localStorage.removeItem(TOKEN_KEY)
    localStorage.removeItem(USER_KEY)
    localStorage.removeItem(EXPIRE_KEY)
    sessionExpiredHandled = false
    sessionExpired.value = false

    if (router.currentRoute.value.path !== '/login') {
      router.push('/login')
    }

    if (showToast) {
      // noop by default for expiry flow
    }
  }

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

  const scheduleExpiryCheck = () => {
    clearExpiryTimer()
    const expireAt = getTokenExpireAt()
    if (!expireAt) return

    const delay = expireAt - Date.now()
    if (delay <= 0) {
      handleSessionExpired()
      return
    }

    expiryTimer = setTimeout(() => {
      handleSessionExpired()
    }, delay)
  }

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

  const confirmSessionExpired = () => {
    logout()
  }

  const getUser = () => {
    try {
      return JSON.parse(localStorage.getItem(USER_KEY) || '{}')
    } catch {
      return {}
    }
  }

  const setUser = (user: unknown) => {
    localStorage.setItem(USER_KEY, JSON.stringify(user))
  }

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