import { Navigate, useLocation } from 'react-router-dom'
import { useAuthStore } from '@/store/authStore'
import { usePermissions, type EffectiveRole } from '@/hooks/usePermissions'
import { Spinner } from '@/components/common/Spinner'

interface ProtectedRouteProps {
  requiredRole?: EffectiveRole
  children: React.ReactNode
}

export function ProtectedRoute({ requiredRole, children }: ProtectedRouteProps) {
  const { isAuthenticated, isLoading, user } = useAuthStore()
  const location = useLocation()
  const { effectiveRole } = usePermissions()

  if (isLoading) {
    return (
      <div className="flex h-screen items-center justify-center">
        <Spinner className="border-t-foreground" />
      </div>
    )
  }

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

  // Enforce must_change_password — redirect unless already on /change-password
  if (user?.must_change_password && location.pathname !== '/change-password') {
    return <Navigate to="/change-password" replace />
  }

  // L1 techs are confined to their focused surface. The sidebar only exposes
  // /l1*, /guides, and /account for them, so any other authed path (the engineer
  // dashboard at /home, /pilot, /trees/*, /escalations, …) bounces to /l1. This
  // also covers post-login landing: auth sends users to /home, which is not in
  // the allowlist, so l1_tech users end up on /l1. Engineer-only AI surfaces
  // (/pilot, /assistant) would 403 at POST /api/v1/ai-sessions anyway — this
  // turns that backend error into a clean redirect. Runs before the requiredRole
  // check so L1 users never trip the engineer-route role logic.
  if (effectiveRole === 'l1_tech') {
    const L1_ALLOWED_PREFIXES = ['/l1', '/guides', '/account', '/change-password']
    const allowed = L1_ALLOWED_PREFIXES.some(
      (p) => location.pathname === p || location.pathname.startsWith(p + '/'),
    )
    if (!allowed) {
      return <Navigate to="/l1" replace />
    }
  }

  if (requiredRole) {
    const ROLE_HIERARCHY: Record<EffectiveRole, number> = {
      super_admin: 5,
      owner: 4,
      engineer: 3,
      l1_tech: 2,
      viewer: 1,
    }
    if (ROLE_HIERARCHY[effectiveRole] < ROLE_HIERARCHY[requiredRole]) {
      return <Navigate to="/trees" replace />
    }
  }

  return <>{children}</>
}

export default ProtectedRoute
