'use client'

import { useEffect, useRef, useState } from 'react'
import { usePathname } from 'next/navigation'
import { LogoIcon } from '@/app/assets/svg/icon'
import { cn } from '@/lib/utils'

const EXIT_DURATION = 1000

export function SiteLoader() {
  const pathname = usePathname()
  const prevPathname = useRef<string | null>(null)
  const [isLeaving, setIsLeaving] = useState(false)
  const [isVisible, setIsVisible] = useState(true)
  const fallbackRef = useRef<ReturnType<typeof setTimeout> | null>(null)
  const hideTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)

  const clearTimers = () => {
    if (fallbackRef.current) clearTimeout(fallbackRef.current)
    if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current)
    fallbackRef.current = null
    hideTimeoutRef.current = null
  }

  const hide = () => {
    if (fallbackRef.current) {
      clearTimeout(fallbackRef.current)
      fallbackRef.current = null
    }

    setIsLeaving(true)
    hideTimeoutRef.current = setTimeout(() => {
      setIsVisible(false)
      document.documentElement.style.overflow = ''
      document.body.style.overflow = ''
    }, EXIT_DURATION)
  }

  const show = () => {
    clearTimers()
    setIsLeaving(false)
    setIsVisible(true)
    document.documentElement.style.overflow = 'hidden'
    document.body.style.overflow = 'hidden'
    window.addEventListener('app:ready', hide, { once: true })
    fallbackRef.current = setTimeout(hide, 5000)
  }

  // On first load
  useEffect(() => {
    prevPathname.current = pathname
    document.documentElement.style.overflow = 'hidden'
    document.body.style.overflow = 'hidden'
    window.addEventListener('app:ready', hide, { once: true })
    fallbackRef.current = setTimeout(hide, 5000)

    return () => {
      window.removeEventListener('app:ready', hide)
      clearTimers()
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  useEffect(() => {
    window.addEventListener('app:loading', show)

    return () => {
      window.removeEventListener('app:loading', show)
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  // On route change — show loader again
  useEffect(() => {
    if (prevPathname.current === null) return
    if (prevPathname.current === pathname) return

    prevPathname.current = pathname

    show()

    return () => {
      window.removeEventListener('app:ready', hide)
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [pathname])

  if (!isVisible) return null

  return (
    <div
      className={cn('site-loader', isLeaving && 'site-loader--leaving')}
      role='status'
      aria-live='polite'
      aria-label='Loading PayseyPay'
    >
      <div className='site-loader__glow' aria-hidden='true' />
      <div className='site-loader__content'>
        <div className='site-loader__logo'>
          <LogoIcon />
        </div>
        <div className='site-loader__track' aria-hidden='true'>
          <span className='site-loader__progress' />
        </div>
      </div>
    </div>
  )
}
