import * as React from 'react';
import { useAuth } from './AuthProvider';

export interface ProtectedRouteProps {
  children: React.ReactNode;
  /** Component to render while loading */
  fallback?: React.ReactNode;
  /** Component to render if not authenticated */
  unauthorized?: React.ReactNode;
  /** Required role(s) - user must have at least one */
  roles?: string[];
  /** Required scope(s) - user must have at least one */
  scopes?: string[];
  /** Redirect path for unauthorized access (alternative to unauthorized component) */
  redirectTo?: string;
  /** Custom redirect function (e.g., router.push). Falls back to window.location.href. */
  onRedirect?: (path: string) => void;
}

/**
 * ProtectedRoute guards routes that require authentication.
 *
 * @example
 * // Basic protection
 * <Route path="/dashboard" element={
 *   <ProtectedRoute>
 *     <Dashboard />
 *   </ProtectedRoute>
 * } />
 *
 * @example
 * // With role requirement
 * <Route path="/admin" element={
 *   <ProtectedRoute roles={['admin']}>
 *     <AdminPanel />
 *   </ProtectedRoute>
 * } />
 *
 * @example
 * // With custom unauthorized view
 * <ProtectedRoute
 *   unauthorized={<AccessDenied />}
 *   fallback={<LoadingSpinner />}
 * >
 *   <SecureContent />
 * </ProtectedRoute>
 */
export function ProtectedRoute({
  children,
  fallback = <DefaultLoading />,
  unauthorized = <DefaultUnauthorized />,
  roles,
  scopes,
  redirectTo,
  onRedirect,
}: ProtectedRouteProps) {
  const { isLoading, isAuthenticated, user } = useAuth();

  // Show loading state
  if (isLoading) {
    return <>{fallback}</>;
  }

  // Not authenticated
  if (!isAuthenticated) {
    if (redirectTo) {
      if (onRedirect) {
        onRedirect(redirectTo);
      } else {
        window.location.href = redirectTo;
      }
      return null;
    }
    return <>{unauthorized}</>;
  }

  // Check role requirements
  if (roles && roles.length > 0) {
    const hasRequiredRole = roles.some((role) => user?.roles?.includes(role));
    if (!hasRequiredRole) {
      return <>{unauthorized}</>;
    }
  }

  // Check scope requirements
  if (scopes && scopes.length > 0) {
    const hasRequiredScope = scopes.some((scope) => user?.scopes?.includes(scope));
    if (!hasRequiredScope) {
      return <>{unauthorized}</>;
    }
  }

  return <>{children}</>;
}

// Default loading component
function DefaultLoading() {
  return (
    <div
      style={{
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        minHeight: '100vh',
        color: 'var(--text-muted)',
      }}
    >
      Loading...
    </div>
  );
}

// Default unauthorized component
function DefaultUnauthorized() {
  return (
    <div
      style={{
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'center',
        minHeight: '100vh',
        gap: '1rem',
        color: 'var(--text-primary)',
      }}
    >
      <h1 style={{ fontSize: '1.5rem', fontWeight: 'bold' }}>Access Denied</h1>
      <p style={{ color: 'var(--text-muted)' }}>You don't have permission to view this page.</p>
    </div>
  );
}
