import { useEffect } from 'react';
import { Navigate, Outlet, useLocation } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { useAuth } from '@/hooks/useAuth';
import { useToast } from '@/hooks/useToast';
import type { Role } from '@/api/types';
import { LoadingState } from './LoadingState';

interface ProtectedRouteProps {
  /** Allowed roles. If omitted, any authenticated user passes. */
  roles?: Role[];
  /** Where to send users who lack the required role. */
  redirectOnRoleDenied?: string;
}

/**
 * Gate component: handles auth + role checks before rendering nested routes.
 * - No token / no user → /login
 * - Wrong role → redirect + "Accès refusé" toast (AC-3.7)
 */
export function ProtectedRoute({
  roles,
  redirectOnRoleDenied = '/engagements',
}: ProtectedRouteProps): JSX.Element {
  const { user, status } = useAuth();
  const { push } = useToast();
  const { t } = useTranslation();
  const location = useLocation();

  const roleDenied = Boolean(
    status === 'authenticated' && user && roles && !roles.includes(user.role),
  );

  useEffect(() => {
    if (roleDenied) {
      push(t('auth.forbidden'), 'error');
    }
  }, [roleDenied, push, t]);

  if (status === 'loading') {
    return <LoadingState label={t('auth.loadingSession')} />;
  }

  if (status === 'unauthenticated' || !user) {
    return <Navigate to="/login" replace state={{ from: location.pathname }} />;
  }

  if (roleDenied) {
    return <Navigate to={redirectOnRoleDenied} replace />;
  }

  return <Outlet />;
}
