import React from 'react';
import { cn } from '@/lib/utils';
import { LoadingSpinner } from './loading-spinner';
import { Loader2 } from 'lucide-react';

/**
 * CRITIQUE FIX #20: Composant LoadingState standardisé pour uniformiser les états de chargement
 *
 * Ce composant fournit une interface cohérente pour afficher les états de chargement
 * à travers toute l'application, améliorant l'UX et la cohérence visuelle.
 */

export interface LoadingStateProps {
  /**
   * Si true, affiche l'état de chargement
   */
  isLoading?: boolean;

  /**
   * Type de chargement à afficher
   * - 'spinner': Spinner centré avec texte optionnel (par défaut)
   * - 'inline': Spinner inline avec texte à côté
   * - 'skeleton': Skeleton loader pour le contenu
   * - 'minimal': Spinner minimal sans conteneur
   */
  variant?: 'spinner' | 'inline' | 'skeleton' | 'minimal';

  /**
   * Taille du spinner
   */
  size?: 'sm' | 'md' | 'lg';

  /**
   * Texte à afficher pendant le chargement
   */
  text?: string;

  /**
   * Message à afficher si aucun texte n'est fourni
   */
  defaultText?: string;

  /**
   * Classes CSS personnalisées
   */
  className?: string;

  /**
   * Contenu à afficher quand isLoading est false
   */
  children?: React.ReactNode;

  /**
   * Si true, affiche un skeleton loader au lieu d'un spinner
   * (utilisé avec variant='skeleton')
   */
  showSkeleton?: boolean;
}

/**
 * LoadingState - Composant standardisé pour les états de chargement
 *
 * CRITIQUE FIX #20: Standardise tous les états de chargement dans l'application
 *
 * @example
 * ```tsx
 * // Spinner centré (par défaut)
 * <LoadingState isLoading={isLoading} text="Chargement des données..." />
 *
 * // Spinner inline
 * <LoadingState isLoading={isLoading} variant="inline" text="Sauvegarde..." />
 *
 * // Skeleton loader
 * <LoadingState isLoading={isLoading} variant="skeleton">
 *   <div>Contenu à charger</div>
 * </LoadingState>
 *
 * // Avec contenu conditionnel
 * <LoadingState isLoading={isLoading} text="Chargement...">
 *   <div>Contenu chargé</div>
 * </LoadingState>
 * ```
 */
export function LoadingState({
  isLoading = false,
  variant = 'spinner',
  size = 'md',
  text,
  defaultText = 'Chargement...',
  className,
  children,
  showSkeleton = false,
}: LoadingStateProps) {
  // Si pas de chargement, afficher le contenu
  if (!isLoading && !showSkeleton) {
    return <>{children}</>;
  }

  const displayText = text || defaultText;

  // Variant: spinner (par défaut) - Spinner centré avec texte
  if (variant === 'spinner') {
    return (
      <div
        className={cn('flex flex-col items-center justify-center', className)}
      >
        <LoadingSpinner size={size} text={displayText} />
      </div>
    );
  }

  // Variant: inline - Spinner avec texte à côté
  if (variant === 'inline') {
    const sizeClasses = {
      sm: 'h-4 w-4',
      md: 'h-5 w-5',
      lg: 'h-6 w-6',
    };

    return (
      <div className={cn('flex items-center gap-2', className)}>
        <Loader2
          className={cn('animate-spin text-gray-400', sizeClasses[size])}
          aria-hidden="true"
        />
        {displayText && (
          <span className="text-sm text-gray-600 dark:text-gray-400">
            {displayText}
          </span>
        )}
      </div>
    );
  }

  // Variant: skeleton - Skeleton loader pour le contenu
  if (variant === 'skeleton' || showSkeleton) {
    return (
      <div className={cn('animate-pulse space-y-4', className)}>
        {children || (
          <>
            <div className="h-4 bg-gray-200 dark:bg-gray-700 rounded w-3/4"></div>
            <div className="h-4 bg-gray-200 dark:bg-gray-700 rounded w-1/2"></div>
            <div className="h-4 bg-gray-200 dark:bg-gray-700 rounded w-5/6"></div>
          </>
        )}
      </div>
    );
  }

  // Variant: minimal - Spinner minimal sans conteneur
  const sizeClasses = {
    sm: 'h-4 w-4',
    md: 'h-5 w-5',
    lg: 'h-6 w-6',
  };

  return (
    <Loader2
      className={cn('animate-spin text-gray-400', sizeClasses[size], className)}
      aria-label={displayText}
      role="status"
    />
  );
}

/**
 * LoadingStateWrapper - Wrapper pour afficher un état de chargement autour du contenu
 *
 * CRITIQUE FIX #20: Wrapper pratique pour les composants qui chargent des données
 *
 * @example
 * ```tsx
 * <LoadingStateWrapper isLoading={isLoading} text="Chargement des utilisateurs...">
 *   <UserList users={users} />
 * </LoadingStateWrapper>
 * ```
 */
export interface LoadingStateWrapperProps
  extends Omit<LoadingStateProps, 'children'> {
  /**
   * Contenu à afficher quand isLoading est false
   */
  children: React.ReactNode;

  /**
   * Variant à utiliser pour l'état de chargement
   */
  loadingVariant?: LoadingStateProps['variant'];
}

export function LoadingStateWrapper({
  isLoading,
  children,
  loadingVariant = 'spinner',
  text,
  defaultText,
  className,
  size,
}: LoadingStateWrapperProps) {
  if (isLoading) {
    return (
      <LoadingState
        isLoading={true}
        variant={loadingVariant}
        text={text}
        defaultText={defaultText}
        className={className}
        size={size}
      />
    );
  }

  return <>{children}</>;
}
