/**
 * ProtectedRoute Component
 * Guards routes that require authentication with role-based access control
 * Based on gamilit implementation
 */

import { Navigate, useLocation } from 'react-router-dom';
import { useAuthStore } from '../../stores/authStore';
import { LoadingSpinner } from '../common/LoadingSpinner';

interface ProtectedRouteProps {
  children: React.ReactNode;
  /** Roles allowed to access this route */
  allowedRoles?: string[];
  /** Custom redirect path for unauthenticated users */
  redirectTo?: string;
}

export function ProtectedRoute({
  children,
  allowedRoles,
  redirectTo = '/auth/login',
}: ProtectedRouteProps) {
  const user = useAuthStore((state) => state.user);
  const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
  const isLoading = useAuthStore((state) => state.isLoading);
  const isInitialized = useAuthStore((state) => state.isInitialized);
  const checkSession = useAuthStore((state) => state.checkSession);
  const location = useLocation();

  // Show loading while checking auth state
  if (isLoading || !isInitialized) {
    return (
      <div className="min-h-screen flex items-center justify-center bg-background dark:bg-background">
        <div className="text-center">
          <LoadingSpinner size="lg" />
          <p className="mt-4 text-foreground-muted dark:text-foreground-muted">
            Verificando sesión...
          </p>
        </div>
      </div>
    );
  }

  // Check if session is still valid
  const sessionValid = checkSession();

  // Not authenticated - redirect to login
  if (!isAuthenticated || !sessionValid) {
    return (
      <Navigate
        to={redirectTo}
        state={{ from: location }}
        replace
      />
    );
  }

  // Check role-based access if roles are specified
  if (allowedRoles && allowedRoles.length > 0) {
    const userRole = user?.role || '';
    const hasRequiredRole = allowedRoles.includes(userRole);

    if (!hasRequiredRole) {
      // User doesn't have required role - redirect to unauthorized page
      return (
        <Navigate
          to="/unauthorized"
          state={{ from: location, requiredRoles: allowedRoles }}
          replace
        />
      );
    }
  }

  // User is authenticated and has required role
  return <>{children}</>;
}

/**
 * PublicRoute Component
 * Redirects authenticated users away from public pages (login, register)
 */
interface PublicRouteProps {
  children: React.ReactNode;
  /** Where to redirect authenticated users */
  redirectTo?: string;
}

export function PublicRoute({
  children,
  redirectTo = '/admin/dashboard',
}: PublicRouteProps) {
  const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
  const isLoading = useAuthStore((state) => state.isLoading);
  const isInitialized = useAuthStore((state) => state.isInitialized);
  const location = useLocation();

  // Show loading while checking auth state
  if (isLoading || !isInitialized) {
    return (
      <div className="min-h-screen flex items-center justify-center bg-background dark:bg-background">
        <LoadingSpinner size="lg" />
      </div>
    );
  }

  // If user is already authenticated, redirect to dashboard
  if (isAuthenticated) {
    // Check if there's a "from" location to redirect back to
    const from = (location.state as { from?: Location })?.from?.pathname || redirectTo;
    return <Navigate to={from} replace />;
  }

  return <>{children}</>;
}

export default ProtectedRoute;
