/**
 * Component: RouteGuard
 * 
 * Higher-order component that protects routes using Gateways and Blockers.
 * Follows clean architecture by separating concerns:
 * - Gateway handles access logic
 * - Blocker handles prevention logic
 * - Component handles UI rendering
 */

'use client';

import { ReactNode, useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import { useAuth } from '@/lib/auth/AuthContext';
import { AuthGateway, AuthGatewayConfig } from './AuthGateway';
import { LoadingState } from '@/components/shared/LoadingState';

interface RouteGuardProps {
  children: ReactNode;
  config?: AuthGatewayConfig;
  /**
   * Custom loading component (optional)
   */
  loadingComponent?: ReactNode;
  /**
   * Custom unauthorized component (optional)
   */
  unauthorizedComponent?: ReactNode;
}

/**
 * RouteGuard Component
 * 
 * Protects child components based on authentication and authorization rules.
 * Uses Gateway pattern for access control.
 * 
 * Usage:
 * ```tsx
 * <RouteGuard config={{ requiredRoles: ['owner', 'admin'] }}>
 *   <AdminDashboard />
 * </RouteGuard>
 * ```
 */
export function RouteGuard({
  children,
  config = {},
  loadingComponent,
  unauthorizedComponent,
}: RouteGuardProps) {
  const router = useRouter();
  const authContext = useAuth();
  const [gateway] = useState(() => new AuthGateway(authContext, config));
  const [accessState, setAccessState] = useState(gateway.getAccessState());

  // Update gateway when auth context changes
  useEffect(() => {
    gateway.refresh();
    setAccessState(gateway.getAccessState());
  }, [authContext.session, authContext.loading, gateway]);

  // Handle redirects
  useEffect(() => {
    if (!accessState.canAccess && !accessState.isLoading) {
      if (config.redirectOnUnauthorized !== false) {
        const redirectPath = gateway.getUnauthorizedRedirectPath();
        
        // Use a small delay to show unauthorized message briefly
        const timer = setTimeout(() => {
          router.push(redirectPath);
        }, 500);
        
        return () => clearTimeout(timer);
      }
    }
  }, [accessState, gateway, router, config.redirectOnUnauthorized]);

  // Show loading state
  if (accessState.isLoading) {
    return loadingComponent || (
      <div className="flex items-center justify-center min-h-screen">
        <LoadingState message="Loading..." className="min-h-screen" />
      </div>
    );
  }

  // Show unauthorized state
  if (!accessState.canAccess) {
    return unauthorizedComponent || (
      <div className="flex items-center justify-center min-h-screen">
        <div className="bg-iron-gray p-8 rounded-lg border border-charcoal-outline max-w-md text-center">
          <h2 className="text-xl font-bold text-racing-red mb-4">Access Denied</h2>
          <p className="text-gray-300 mb-6">{accessState.reason}</p>
          <button
            onClick={() => router.push('/auth/login')}
            className="px-4 py-2 bg-primary-blue text-white rounded hover:bg-blue-600 transition-colors"
          >
            Go to Login
          </button>
        </div>
      </div>
    );
  }

  // Render protected content
  return <>{children}</>;
}

/**
 * useRouteGuard Hook
 * 
 * Hook for programmatic access control within components.
 * 
 * Usage:
 * ```tsx
 * const { canAccess, reason, isLoading } = useRouteGuard({ requiredRoles: ['admin'] });
 * ```
 */
export function useRouteGuard(config: AuthGatewayConfig = {}) {
  const authContext = useAuth();
  const [gateway] = useState(() => new AuthGateway(authContext, config));
  const [state, setState] = useState(gateway.getAccessState());

  useEffect(() => {
    gateway.refresh();
    setState(gateway.getAccessState());
  }, [authContext.session, authContext.loading, gateway]);

  return {
    canAccess: state.canAccess,
    reason: state.reason,
    isLoading: state.isLoading,
    isAuthenticated: state.isAuthenticated,
    enforceAccess: () => gateway.enforceAccess(),
    redirectIfUnauthorized: () => gateway.redirectIfUnauthorized(),
  };
}