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

import {
  getRefreshToken,
  setRefreshToken,
  clearRefreshToken,
  hasRefreshToken,
  hasSessionPresenceCookie,
} from './token-storage'

describe('lib/storage/token-storage', () => {
  beforeEach(() => {
    clearRefreshToken()
    vi.clearAllMocks()
  })

  afterEach(() => {
    clearRefreshToken()
  })

  describe('getRefreshToken', () => {
    it('should return null initially', () => {
      expect(getRefreshToken()).toBeNull()
    })

    it('should return the token after setting', () => {
      setRefreshToken('test-token')
      expect(getRefreshToken()).toBe('test-token')
    })

    it('should return null after clearing', () => {
      setRefreshToken('test-token')
      clearRefreshToken()
      expect(getRefreshToken()).toBeNull()
    })
  })

  describe('setRefreshToken', () => {
    it('should set a valid token', () => {
      setRefreshToken('valid-token')
      expect(getRefreshToken()).toBe('valid-token')
    })

    it('should handle null input', () => {
      setRefreshToken('existing-token')
      setRefreshToken(null)
      expect(getRefreshToken()).toBeNull()
    })

    it('should handle undefined input', () => {
      setRefreshToken('existing-token')
      setRefreshToken(undefined)
      expect(getRefreshToken()).toBeNull()
    })

    it('should handle empty string', () => {
      setRefreshToken('existing-token')
      setRefreshToken('')
      expect(getRefreshToken()).toBeNull()
    })

    it('should handle whitespace-only string', () => {
      setRefreshToken('existing-token')
      setRefreshToken('   ')
      expect(getRefreshToken()).toBeNull()
    })

    it('should trim whitespace from token', () => {
      setRefreshToken('  trimmed-token  ')
      expect(getRefreshToken()).toBe('trimmed-token')
    })
  })

  describe('clearRefreshToken', () => {
    it('should clear the token', () => {
      setRefreshToken('test-token')
      clearRefreshToken()
      expect(getRefreshToken()).toBeNull()
    })

    it('should be safe to call multiple times', () => {
      clearRefreshToken()
      clearRefreshToken()
      clearRefreshToken()
      expect(getRefreshToken()).toBeNull()
    })
  })

  describe('hasRefreshToken', () => {
    it('should return false initially', () => {
      expect(hasRefreshToken()).toBe(false)
    })

    it('should return true after setting token', () => {
      setRefreshToken('test-token')
      expect(hasRefreshToken()).toBe(true)
    })

    it('should return false after clearing token', () => {
      setRefreshToken('test-token')
      clearRefreshToken()
      expect(hasRefreshToken()).toBe(false)
    })

    it('should return false for empty token', () => {
      setRefreshToken('')
      expect(hasRefreshToken()).toBe(false)
    })
  })

  describe('hasSessionPresenceCookie', () => {
    it('should return false when cookie is not set', () => {
      // In test environment, document.cookie may be empty
      const result = hasSessionPresenceCookie()
      expect(typeof result).toBe('boolean')
    })

    it('should detect session presence cookie', () => {
      // Set the cookie
      document.cookie = 'ums_session_present=1'

      expect(hasSessionPresenceCookie()).toBe(true)

      // Clean up
      document.cookie = 'ums_session_present=; expires=Thu, 01 Jan 1970 00:00:00 GMT'
    })

    it('should return false when other cookies exist but not session cookie', () => {
      document.cookie = 'other_cookie=value'

      expect(hasSessionPresenceCookie()).toBe(false)

      // Clean up
      document.cookie = 'other_cookie=; expires=Thu, 01 Jan 1970 00:00:00 GMT'
    })

    it('should handle multiple cookies', () => {
      document.cookie = 'cookie1=value1'
      document.cookie = 'ums_session_present=1'
      document.cookie = 'cookie2=value2'

      expect(hasSessionPresenceCookie()).toBe(true)

      // Clean up
      document.cookie = 'cookie1=; expires=Thu, 01 Jan 1970 00:00:00 GMT'
      document.cookie = 'ums_session_present=; expires=Thu, 01 Jan 1970 00:00:00 GMT'
      document.cookie = 'cookie2=; expires=Thu, 01 Jan 1970 00:00:00 GMT'
    })
  })

  describe('security considerations', () => {
    it('should not store token in localStorage', () => {
      setRefreshToken('test-token')

      // Token should not be in localStorage
      expect(localStorage.getItem('refreshToken')).toBeFalsy()
      expect(localStorage.getItem('refresh_token')).toBeFalsy()
    })

    it('should not store token in sessionStorage', () => {
      setRefreshToken('test-token')

      // Token should not be in sessionStorage
      expect(sessionStorage.getItem('refreshToken')).toBeFalsy()
      expect(sessionStorage.getItem('refresh_token')).toBeFalsy()
    })
  })
})
