import type { AuthStore } from '../stores/auth'
import { AUTH_TOKEN_KEY } from './authConstants'

const AUTH_ACTIVITY_KEY = 'vtsa-last-activity-at'
const AUTH_CLEARED_EVENT = 'vtsa-auth-cleared'
const ACTIVITY_PERSIST_INTERVAL_MS = 30_000
const IDLE_CHECK_INTERVAL_MS = 60_000

export function notifyAuthCleared() {
  if (typeof window === 'undefined') return
  window.dispatchEvent(new Event(AUTH_CLEARED_EVENT))
}

export function installAuthSessionManager(authStore: AuthStore) {
  if (typeof window === 'undefined') {
    return () => {}
  }

  let lastActivityAt = readLastActivityAt()
  let lastPersistedAt = 0

  const syncActivity = (timestamp = Date.now(), forcePersist = false) => {
    lastActivityAt = timestamp

    if (!authStore.isLoggedIn) {
      return
    }

    if (forcePersist || timestamp - lastPersistedAt >= ACTIVITY_PERSIST_INTERVAL_MS) {
      window.localStorage.setItem(AUTH_ACTIVITY_KEY, String(timestamp))
      lastPersistedAt = timestamp
    }
  }

  const clearSessionLocally = () => {
    authStore.clearSession()
  }

  const checkIdleTimeout = async () => {
    const timeoutHours = authStore.session?.sessionIdleTimeoutHours
    if (!authStore.isLoggedIn || !timeoutHours) {
      return
    }

    if (Date.now() - lastActivityAt < timeoutHours * 60 * 60 * 1000) {
      return
    }

    await authStore.logout()
  }

  const onStorage = (event: StorageEvent) => {
    if (event.key === AUTH_ACTIVITY_KEY && event.newValue) {
      const timestamp = Number(event.newValue)
      if (Number.isFinite(timestamp) && timestamp > lastActivityAt) {
        lastActivityAt = timestamp
      }
      return
    }

    if (event.key === AUTH_TOKEN_KEY && !event.newValue) {
      clearSessionLocally()
    }
  }

  const onAuthCleared = () => {
    clearSessionLocally()
  }

  const activityListener = () => {
    syncActivity()
  }

  const activityEvents = ['pointerdown', 'keydown', 'scroll', 'touchstart']
  activityEvents.forEach((eventName) => {
    window.addEventListener(eventName, activityListener, { passive: true })
  })
  window.addEventListener('storage', onStorage)
  window.addEventListener(AUTH_CLEARED_EVENT, onAuthCleared)

  const intervalId = window.setInterval(() => {
    void checkIdleTimeout()
  }, IDLE_CHECK_INTERVAL_MS)

  syncActivity(Date.now(), true)

  return () => {
    activityEvents.forEach((eventName) => {
      window.removeEventListener(eventName, activityListener)
    })
    window.removeEventListener('storage', onStorage)
    window.removeEventListener(AUTH_CLEARED_EVENT, onAuthCleared)
    window.clearInterval(intervalId)
  }
}

function readLastActivityAt() {
  if (typeof window === 'undefined') {
    return Date.now()
  }

  const storedValue = Number(window.localStorage.getItem(AUTH_ACTIVITY_KEY))
  return Number.isFinite(storedValue) && storedValue > 0
    ? storedValue
    : Date.now()
}
