"use client";

import { useEffect, useRef } from "react";
import { usePathname, useRouter } from "@/i18n/routing";
import { getRoutePolicy } from "@/lib/rbac/route-policies";
import { canAll, canAny } from "@/lib/rbac/permissions";
import { useRbac } from "@/contexts/permissions-context";
import { useAuth } from "@/contexts/auth-context";

export function PermissionRouteGuard() {
  const pathname = usePathname();
  const router = useRouter();
  const { loading, guardReady, guardPermissionSet, catalogPermissionSet } = useRbac();
  const { user } = useAuth();
  const last403RedirectPathRef = useRef<string | null>(null);

  useEffect(() => {
    if (pathname && last403RedirectPathRef.current && pathname !== last403RedirectPathRef.current) {
      last403RedirectPathRef.current = null;
    }

    if (loading || !guardReady) {
      return;
    }

    if (!user) {
      return;
    }

    if (!pathname || pathname.endsWith("/403")) {
      return;
    }

    const policy = getRoutePolicy(
      pathname,
      {
        availablePermissions:
          catalogPermissionSet.size > 0 ? catalogPermissionSet : undefined,
        grantedPermissions: guardPermissionSet,
      },
    );
    if (!policy || policy.permissions.length === 0) {
      return;
    }

    const allowed = policy.require === "all"
      ? canAll(guardPermissionSet, policy.permissions)
      : canAny(guardPermissionSet, policy.permissions);

    if (!allowed) {
      if (last403RedirectPathRef.current === pathname) {
        return;
      }
      last403RedirectPathRef.current = pathname;
      router.replace("/403");
      return;
    }

    last403RedirectPathRef.current = null;
  }, [catalogPermissionSet, guardPermissionSet, guardReady, loading, pathname, router, user]);

  return null;
}
