import { type ReactNode, Suspense, useState, useLayoutEffect } from 'react'
import { Navigate, useLocation } from 'react-router-dom'
import { useAuth } from '../contexts/AuthContext'
import { PageLoader } from './PageLoader'

// Mounts only once Suspense has resolved (chunk is ready).
// useLayoutEffect fires before the browser paints, so setState here causes a
// synchronous re-render — content becomes visible in the same paint with no
// intermediate loader flash for cached chunks.
function ContentReady({ onReady }: { onReady: () => void }) {
  useLayoutEffect(() => {
    onReady()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])
  return null
}

type Props = { children: ReactNode }

export function ProtectedRoute({ children }: Props) {
  const { user, loading } = useAuth()
  const location = useLocation()

  // Always start false so the loader covers any intermediate render state.
  // For cached chunks, ContentReady's useLayoutEffect fires before the first
  // paint and flips this synchronously — no visible flash.
  const [contentReady, setContentReady] = useState(false)

  if (!loading && !user) {
    return <Navigate to="/" state={{ from: location }} replace />
  }

  const showLoader = loading || !contentReady

  return (
    <>
      {showLoader && <PageLoader />}
      {!loading && user && (
        <div style={{ display: contentReady ? 'contents' : 'none' }}>
          <Suspense fallback={null}>
            <ContentReady onReady={() => setContentReady(true)} />
            {children}
          </Suspense>
        </div>
      )}
    </>
  )
}
