

import { Box } from './Box';
import { Stack } from './Stack';
import { LoadingWrapperProps } from './state-types';
import { Text } from './Text';

/**
 * LoadingWrapper Component
 * 
 * Provides consistent loading states with multiple variants:
 * - spinner: Traditional loading spinner (default)
 * - skeleton: Skeleton screens for better UX
 * - full-screen: Centered in viewport
 * - inline: Compact inline loading
 * - card: Loading card placeholders
 * 
 * All variants are fully accessible with ARIA labels and keyboard support.
 */
export function LoadingWrapper({
  variant = 'spinner',
  message = 'Loading...',
  className = '',
  size = 'md',
  skeletonCount = 3,
  cardConfig,
  ariaLabel = 'Loading content',
}: LoadingWrapperProps) {
  // Size mappings for different variants
  const sizeClasses = {
    sm: {
      spinner: 'w-4 h-4 border-2',
      inline: 'xs' as const,
      card: 'h-24',
    },
    md: {
      spinner: 'w-10 h-10 border-2',
      inline: 'sm' as const,
      card: 'h-32',
    },
    lg: {
      spinner: 'w-16 h-16 border-4',
      inline: 'base' as const,
      card: 'h-40',
    },
  };

  const spinnerSize = sizeClasses[size].spinner;
  const inlineSize = sizeClasses[size].inline;
  const cardHeight = cardConfig?.height || sizeClasses[size].card;

  // Render different variants
  switch (variant) {
    case 'spinner':
      return (
        <Box
          display="flex"
          alignItems="center"
          justifyContent="center"
          minHeight="200px"
          className={className}
          role="status"
          aria-label={ariaLabel}
          aria-live="polite"
        >
          <Stack align="center" gap={3}>
            <Box
              className={`${spinnerSize} border-primary-blue border-t-transparent rounded-full animate-spin`}
            />
            <Text color="text-gray-400" size="sm">{message}</Text>
          </Stack>
        </Box>
      );

    case 'skeleton':
      return (
        <Stack
          gap={3}
          className={className}
          role="status"
          aria-label={ariaLabel}
          aria-live="polite"
        >
          {Array.from({ length: skeletonCount }).map((_, index) => (
            <Box
              key={index}
              fullWidth
              bg="bg-iron-gray/40"
              rounded="lg"
              animate="pulse"
              style={{ height: cardHeight }}
            />
          ))}
        </Stack>
      );

    case 'full-screen':
      return (
        <Box
          position="fixed"
          inset="0"
          zIndex={50}
          bg="bg-deep-graphite/90"
          blur="sm"
          display="flex"
          alignItems="center"
          justifyContent="center"
          p={4}
          className={className}
          role="status"
          aria-label={ariaLabel}
          aria-live="polite"
        >
          <Box textAlign="center" maxWidth="md">
            <Stack align="center" gap={4}>
              <Box className="w-16 h-16 border-4 border-primary-blue border-t-transparent rounded-full animate-spin" />
              <Text color="text-white" size="lg" weight="medium">{message}</Text>
              <Text color="text-gray-400" size="sm">This may take a moment...</Text>
            </Stack>
          </Box>
        </Box>
      );

    case 'inline':
      return (
        <Box
          display="inline-flex"
          alignItems="center"
          gap={2}
          className={className}
          role="status"
          aria-label={ariaLabel}
          aria-live="polite"
        >
          <Box className="w-4 h-4 border-2 border-primary-blue border-t-transparent rounded-full animate-spin" />
          <Text color="text-gray-400" size={inlineSize}>{message}</Text>
        </Box>
      );

    case 'card':
      const cardCount = cardConfig?.count || 3;
      const cardClassName = cardConfig?.className || '';
      
      return (
        <Box
          display="grid"
          gap={4}
          className={className}
          role="status"
          aria-label={ariaLabel}
          aria-live="polite"
        >
          {Array.from({ length: cardCount }).map((_, index) => (
            <Box
              key={index}
              bg="bg-iron-gray/40"
              rounded="xl"
              overflow="hidden"
              border
              borderColor="border-charcoal-outline/50"
              className={cardClassName}
              style={{ height: cardHeight }}
            >
              <Box h="full" w="full" display="flex" alignItems="center" justifyContent="center">
                <Box className="w-8 h-8 border-2 border-primary-blue border-t-transparent rounded-full animate-spin" />
              </Box>
            </Box>
          ))}
        </Box>
      );

    default:
      return null;
  }
}

/**
 * Convenience component for full-screen loading
 */
export function FullScreenLoading({ message = 'Loading...', className = '' }: Pick<LoadingWrapperProps, 'message' | 'className'>) {
  return (
    <LoadingWrapper
      variant="full-screen"
      message={message}
      className={className}
    />
  );
}

/**
 * Convenience component for inline loading
 */
export function InlineLoading({ message = 'Loading...', size = 'sm', className = '' }: Pick<LoadingWrapperProps, 'message' | 'size' | 'className'>) {
  return (
    <LoadingWrapper
      variant="inline"
      message={message}
      size={size}
      className={className}
    />
  );
}

/**
 * Convenience component for skeleton loading
 */
export function SkeletonLoading({ skeletonCount = 3, className = '' }: Pick<LoadingWrapperProps, 'skeletonCount' | 'className'>) {
  return (
    <LoadingWrapper
      variant="skeleton"
      skeletonCount={skeletonCount}
      className={className}
    />
  );
}

/**
 * Convenience component for card loading
 */
export function CardLoading({ cardConfig, className = '' }: Pick<LoadingWrapperProps, 'cardConfig' | 'className'>) {
  return (
    <LoadingWrapper
      variant="card"
      cardConfig={cardConfig}
      className={className}
    />
  );
}
