import { Loader2 } from 'lucide-react';
import { cn } from '@/lib/utils';

/**
 * LoadingSpinnerProps - Propriétés du composant LoadingSpinner
 *
 * @interface LoadingSpinnerProps
 */
interface LoadingSpinnerProps {
  /**
   * Taille du spinner
   *
   * - `sm`: Petit (h-4 w-4 en inline, h-4 w-4 en block)
   * - `md`: Moyen (h-5 w-5 en inline, h-8 w-8 en block) - par défaut
   * - `lg`: Grand (h-6 w-6 en inline, h-12 w-12 en block)
   *
   * @default 'md'
   */
  size?: 'sm' | 'md' | 'lg';

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

  /**
   * Texte à afficher sous le spinner (ignoré en mode inline)
   *
   * @example
   * ```tsx
   * <LoadingSpinner text="Chargement en cours..." />
   * ```
   */
  text?: string;

  /**
   * Mode inline pour boutons et éléments compacts.
   * Rend uniquement l'icône sans conteneur.
   */
  inline?: boolean;

  /**
   * Variant visuel (uniquement en mode inline)
   */
  variant?: 'default' | 'muted' | 'white' | 'current';

  /**
   * Label d'accessibilité
   */
  'aria-label'?: string;
}

/**
 * LoadingSpinner - Composant de spinner de chargement
 *
 * Composant de spinner animé pour indiquer un état de chargement.
 * Inclut un texte optionnel et supporte plusieurs tailles.
 *
 * @example
 * ```tsx
 * // Spinner simple
 * <LoadingSpinner />
 *
 * // Spinner avec texte
 * <LoadingSpinner text="Chargement..." />
 *
 * // Spinner de grande taille
 * <LoadingSpinner size="lg" text="Traitement en cours" />
 * ```
 *
 * @component
 * @param {LoadingSpinnerProps} props - Propriétés du composant
 * @returns {JSX.Element} Spinner animé avec texte optionnel
 */

const variantClasses = {
  default: 'text-primary',
  muted: 'text-muted-foreground',
  white: 'text-foreground',
  current: 'text-current',
} as const;

const blockSizeClasses = {
  sm: 'h-4 w-4',
  md: 'h-8 w-8',
  lg: 'h-12 w-12',
};

const inlineSizeClasses = {
  sm: 'h-4 w-4',
  md: 'h-5 w-5',
  lg: 'h-6 w-6',
};

export function LoadingSpinner({
  size = 'md',
  className,
  text,
  inline = false,
  variant = 'default',
  'aria-label': ariaLabel = 'Chargement en cours',
}: LoadingSpinnerProps) {
  if (inline) {
    return (
      <>
        <Loader2
          className={cn(
            'animate-spin',
            inlineSizeClasses[size],
            variantClasses[variant],
            className,
          )}
          aria-hidden="true"
        />
        <span className="sr-only">{ariaLabel}</span>
      </>
    );
  }

  return (
    <div
      className={cn(
        'flex flex-col items-center justify-center min-h-48',
        className,
      )}
    >
      <div
        className={cn(
          'animate-spin rounded-full border-2 border-muted border-t-primary',
          blockSizeClasses[size],
        )}
        role="status"
        aria-label={ariaLabel}
      >
        <span className="sr-only">Chargement...</span>
      </div>
      {text && (
        <p className="mt-2 text-sm text-muted-foreground dark:text-muted-foreground">{text}</p>
      )}
    </div>
  );
}
