import { beforeEach, describe, expect, it, vi } from 'vitest'

const user = {
  id: 1,
  username: 'admin',
  email: 'admin@example.com',
  phone: '13800138000',
  nickname: 'Admin',
  avatar: '',
  status: 1 as const,
}

const roles = [
  {
    id: 1,
    name: 'Administrator',
    code: 'admin',
    description: 'System administrator',
    is_system: true,
    is_default: false,
    status: 1 as const,
  },
]

describe('auth-session', () => {
  beforeEach(() => {
    vi.resetModules()
    vi.clearAllMocks()
  })

  it('stores and clears the session state in memory', async () => {
    const session = await import('@/lib/http/auth-session')

    session.setAccessToken('access-token', 60)
    session.setCurrentUser(user)
    session.setCurrentRoles(roles)

    expect(session.getAccessToken()).toBe('access-token')
    expect(session.getCurrentUser()).toEqual(user)
    expect(session.getCurrentRoles()).toEqual(roles)
    expect(session.getRoleCodes()).toEqual(['admin'])
    expect(session.isAdmin()).toBe(true)
    expect(session.isAuthenticated()).toBe(true)

    session.clearSession()

    expect(session.getAccessToken()).toBeNull()
    expect(session.getCurrentUser()).toBeNull()
    expect(session.getCurrentRoles()).toEqual([])
    expect(session.isAuthenticated()).toBe(false)
  })

  it('starts empty after a module reload because the session is memory-only', async () => {
    let session = await import('@/lib/http/auth-session')
    session.setAccessToken('access-token', 60)
    session.setCurrentUser(user)
    session.setCurrentRoles(roles)

    vi.resetModules()
    session = await import('@/lib/http/auth-session')

    expect(session.getAccessToken()).toBeNull()
    expect(session.getCurrentUser()).toBeNull()
    expect(session.getCurrentRoles()).toEqual([])
    expect(session.isAuthenticated()).toBe(false)
  })

  it('marks the token as expired before the hard expiry time', async () => {
    vi.useFakeTimers()
    vi.setSystemTime(new Date('2026-03-21T00:00:00Z'))

    const session = await import('@/lib/http/auth-session')

    session.setAccessToken('access-token', 60)
    expect(session.isAccessTokenExpired()).toBe(false)

    vi.advanceTimersByTime(31_000)
    expect(session.isAccessTokenExpired()).toBe(true)

    session.clearSession()
    vi.useRealTimers()
  })
})
