/**
 * LoadingSpinner - Animated loading spinner for web
 *
 * Features:
 * - Multiple sizes (sm, md, lg, xl)
 * - Optional loading message
 * - Full-screen mode option
 * - Tailwind CSS styling
 *
 * @example
 * ```tsx
 * <LoadingSpinner size="md" />
 * <LoadingSpinner size="lg" message="Loading data..." />
 * <LoadingSpinner fullScreen message="Please wait..." />
 * ```
 */

import { cn } from '@/lib/utils';

interface LoadingSpinnerProps {
  size?: 'sm' | 'md' | 'lg' | 'xl';
  color?: 'primary' | 'white' | 'gray';
  message?: string;
  fullScreen?: boolean;
  className?: string;
}

// Size mapping for spinner
const sizeClasses = {
  sm: 'h-4 w-4 border-2',
  md: 'h-8 w-8 border-2',
  lg: 'h-12 w-12 border-3',
  xl: 'h-16 w-16 border-4',
};

// Color mapping for spinner
const colorClasses = {
  primary: 'border-blue-600 border-t-transparent',
  white: 'border-white border-t-transparent',
  gray: 'border-gray-400 border-t-transparent',
};

// Text size mapping
const textSizeClasses = {
  sm: 'text-sm',
  md: 'text-base',
  lg: 'text-lg',
  xl: 'text-xl',
};

export function LoadingSpinner({
  size = 'md',
  color = 'primary',
  message,
  fullScreen = false,
  className,
}: LoadingSpinnerProps) {
  const spinner = (
    <div
      className={cn(
        'animate-spin rounded-full',
        sizeClasses[size],
        colorClasses[color],
        className
      )}
      role="status"
      aria-label={message || 'Loading'}
    />
  );

  if (fullScreen) {
    return (
      <div className="fixed inset-0 z-50 flex flex-col items-center justify-center bg-white">
        {spinner}
        {message && (
          <p className={cn('mt-4 text-slate-600', textSizeClasses[size])}>
            {message}
          </p>
        )}
      </div>
    );
  }

  if (message) {
    return (
      <div className="flex flex-col items-center justify-center gap-3 p-6">
        {spinner}
        <p className={cn('text-slate-600', textSizeClasses[size])}>
          {message}
        </p>
      </div>
    );
  }

  return spinner;
}

/**
 * LoadingOverlay - Full-screen loading overlay with backdrop
 *
 * @example
 * ```tsx
 * {isLoading && (
 *   <LoadingOverlay message="Saving changes..." />
 * )}
 * ```
 */
interface LoadingOverlayProps {
  message?: string;
  backdrop?: 'light' | 'dark' | 'blur';
}

export function LoadingOverlay({
  message = 'Loading...',
  backdrop = 'blur'
}: LoadingOverlayProps) {
  const backdropClasses = {
    light: 'bg-white/80',
    dark: 'bg-slate-900/80',
    blur: 'bg-white/80 backdrop-blur-sm',
  };

  return (
    <div className={cn(
      'fixed inset-0 z-50 flex flex-col items-center justify-center',
      backdropClasses[backdrop]
    )}>
      <LoadingSpinner size="lg" />
      <p className="mt-4 text-lg font-medium text-slate-700">
        {message}
      </p>
    </div>
  );
}

/**
 * InlineLoader - Small inline loading indicator
 *
 * @example
 * ```tsx
 * <button disabled={isLoading}>
 *   {isLoading ? <InlineLoader /> : 'Save'}
 * </button>
 * ```
 */
interface InlineLoaderProps {
  className?: string;
}

export function InlineLoader({ className }: InlineLoaderProps) {
  return (
    <LoadingSpinner
      size="sm"
      className={cn('inline-block', className)}
    />
  );
}

/**
 * PageLoader - Full page loading state with centered spinner
 *
 * @example
 * ```tsx
 * if (isLoading) return <PageLoader message="Loading dashboard..." />;
 * ```
 */
interface PageLoaderProps {
  message?: string;
}

export function PageLoader({ message }: PageLoaderProps) {
  return (
    <div className="flex min-h-[400px] flex-col items-center justify-center">
      <LoadingSpinner size="lg" />
      {message && (
        <p className="mt-4 text-lg text-slate-600">{message}</p>
      )}
    </div>
  );
}
