import type { SessionUser, Role } from '@/types'

interface SessionState {
  accessToken: string | null
  expiresAt: number | null
  user: SessionUser | null
  roles: Role[]
  isRefreshing: boolean
  refreshPromise: Promise<void> | null
}

const sessionState: SessionState = {
  accessToken: null,
  expiresAt: null,
  user: null,
  roles: [],
  isRefreshing: false,
  refreshPromise: null,
}

export function getAccessToken(): string | null {
  return sessionState.accessToken
}

export function setAccessToken(token: string, expiresIn: number): void {
  sessionState.accessToken = token
  sessionState.expiresAt = Date.now() + expiresIn * 1000
}

export function clearAccessToken(): void {
  sessionState.accessToken = null
  sessionState.expiresAt = null
}

export function isAccessTokenExpired(): boolean {
  if (!sessionState.expiresAt) {
    return true
  }
  return Date.now() > sessionState.expiresAt - 30_000
}

export function getCurrentUser(): SessionUser | null {
  return sessionState.user
}

export function setCurrentUser(user: SessionUser): void {
  sessionState.user = user
}

export function getCurrentRoles(): Role[] {
  return sessionState.roles
}

export function setCurrentRoles(roles: Role[]): void {
  sessionState.roles = roles
}

export function isAdmin(): boolean {
  return sessionState.roles.some((role) => role.code === 'admin')
}

export function getRoleCodes(): string[] {
  return sessionState.roles.map((role) => role.code)
}

export function isAuthenticated(): boolean {
  return sessionState.accessToken !== null && sessionState.user !== null
}

export function clearSession(): void {
  sessionState.accessToken = null
  sessionState.expiresAt = null
  sessionState.user = null
  sessionState.roles = []
  sessionState.isRefreshing = false
  sessionState.refreshPromise = null
}

export function isRefreshing(): boolean {
  return sessionState.isRefreshing
}

export function startRefreshing(): void {
  sessionState.isRefreshing = true
}

export function endRefreshing(): void {
  sessionState.isRefreshing = false
}

export function getRefreshPromise(): Promise<void> | null {
  return sessionState.refreshPromise
}

export function setRefreshPromise(promise: Promise<void>): void {
  sessionState.refreshPromise = promise
}

export function clearRefreshPromise(): void {
  sessionState.refreshPromise = null
}
