// Per-route capability guard. Wrap the page body — if the active
// session doesn't hold the route's capability, render a 403 instead of
// the page. Server-side authz is still the real gate; this is UX so a
// deep link doesn't 500 inside a route loader that assumes access.

import { useLocation } from "react-router"
import { ShieldAlert } from "lucide-react"

import {
  capabilityForPath,
  useCapabilities,
  type Capability,
} from "~/lib/capabilities"
import { Card, CardContent } from "~/components/ui/card"

type RouteGuardProps = {
  children: React.ReactNode
  /** Override the capability derived from the current path. Useful for
   *  nested routes where you want to check a specific cap. */
  capability?: Capability
}

export function RouteGuard({ children, capability }: RouteGuardProps) {
  const caps = useCapabilities()
  const location = useLocation()
  const required = capability ?? capabilityForPath(location.pathname)
  // No mapping = route is intentionally unguarded (e.g. login flows
  // never reach AppShell anyway).
  if (!required) return <>{children}</>
  if (caps.has(required)) return <>{children}</>
  return <Forbidden capability={required} />
}

function Forbidden({ capability }: { capability: Capability }) {
  return (
    <div className="flex min-h-[60vh] items-center justify-center">
      <Card className="max-w-md">
        <CardContent className="flex flex-col items-center gap-3 py-10 text-center">
          <ShieldAlert className="size-10 text-muted-foreground" />
          <h2 className="text-lg font-semibold">You can't access this page</h2>
          <p className="text-sm text-muted-foreground">
            This view needs the{" "}
            <code className="font-mono text-xs">{capability}</code> capability,
            which your account doesn't hold on the current tenant. Ask a platform
            administrator to grant it.
          </p>
        </CardContent>
      </Card>
    </div>
  )
}
