import { ReactNode } from 'react';
import { Skeleton } from '@/components/ui/skeleton';
import { Card, CardContent } from '@/components/ui/card';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Loader2, AlertCircle } from 'lucide-react';

interface LoadingGateProps {
  /** Whether data is still loading */
  isLoading: boolean;
  
  /** Optional error to display */
  error?: Error | null;
  
  /** Content to render when loaded */
  children: ReactNode;
  
  /** Loading variant */
  variant?: 'skeleton' | 'spinner' | 'card';
  
  /** Number of skeleton items (for skeleton variant) */
  skeletonCount?: number;
  
  /** Custom loading message */
  loadingMessage?: string;
  
  /** Custom error message */
  errorMessage?: string;
}

/**
 * Reusable loading and error state wrapper
 * 
 * Handles common loading patterns:
 * - Skeleton loaders
 * - Spinner with message
 * - Card-based loading states
 * - Error display
 * 
 * @example
 * ```tsx
 * <LoadingGate isLoading={loading} error={error} variant="skeleton" skeletonCount={3}>
 *   <YourContent />
 * </LoadingGate>
 * ```
 */
export function LoadingGate({
  isLoading,
  error,
  children,
  variant = 'skeleton',
  skeletonCount = 3,
  loadingMessage = 'Loading...',
  errorMessage,
}: LoadingGateProps) {
  // Error state
  if (error) {
    return (
      <Alert variant="destructive">
        <AlertCircle className="h-4 w-4" />
        <AlertTitle>Error</AlertTitle>
        <AlertDescription>
          {errorMessage || error.message || 'An unexpected error occurred'}
        </AlertDescription>
      </Alert>
    );
  }

  // Loading state
  if (isLoading) {
    switch (variant) {
      case 'spinner':
        return (
          <div className="flex flex-col items-center justify-center py-12 gap-4">
            <Loader2 className="h-8 w-8 animate-spin text-primary" />
            <p className="text-sm text-muted-foreground">{loadingMessage}</p>
          </div>
        );

      case 'card':
        return (
          <Card>
            <CardContent className="p-6 space-y-3">
              {Array.from({ length: skeletonCount }).map((_, i) => (
                <div key={i} className="flex items-center gap-4 p-3 border rounded-lg">
                  <Skeleton className="h-10 w-10 rounded-full" />
                  <div className="flex-1 space-y-2">
                    <Skeleton className="h-4 w-2/3" />
                    <Skeleton className="h-3 w-1/2" />
                  </div>
                  <Skeleton className="h-8 w-24" />
                </div>
              ))}
            </CardContent>
          </Card>
        );

      case 'skeleton':
      default:
        return (
          <div className="space-y-3">
            {Array.from({ length: skeletonCount }).map((_, i) => (
              <div key={i} className="space-y-2">
                <Skeleton className="h-4 w-3/4" />
                <Skeleton className="h-3 w-1/2" />
              </div>
            ))}
          </div>
        );
    }
  }

  // Loaded state
  return <>{children}</>;
}
