import { Box } from '@/ui/Box';
import { LoadingWrapperProps } from '@/ui/state-types';
import { Text } from '@/ui/Text';

export function LoadingWrapper({
  variant = 'spinner',
  message = 'Loading...',
  size = 'md',
  skeletonCount = 3,
  cardConfig,
  ariaLabel = 'Loading content',
}: LoadingWrapperProps) {
  const sizeMap = {
    sm: { spinner: '1rem', inline: 'xs' as const, card: '6rem' },
    md: { spinner: '2.5rem', inline: 'sm' as const, card: '8rem' },
    lg: { spinner: '4rem', inline: 'base' as const, card: '10rem' },
  };

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

  const Spinner = ({ size: s }: { size: string }) => (
    <Box 
      style={{ 
        width: s, 
        height: s, 
        border: '2px solid var(--ui-color-intent-primary)', 
        borderTopColor: 'transparent', 
        borderRadius: '9999px' 
      }} 
      className="animate-spin" 
    />
  );

  switch (variant) {
    case 'spinner':
      return (
        <Box display="flex" flexDirection="col" alignItems="center" justifyContent="center" minHeight="12rem" role="status" aria-label={ariaLabel}>
          <Spinner size={spinnerSize} />
          <Box marginTop={3}>
            <Text variant="low" size="sm">{message}</Text>
          </Box>
        </Box>
      );

    case 'skeleton':
      return (
        <Box display="flex" flexDirection="col" gap={3} role="status" aria-label={ariaLabel}>
          {Array.from({ length: skeletonCount }).map((_, index) => (
            <Box
              key={index}
              fullWidth
              bg="var(--ui-color-bg-surface-muted)"
              rounded="lg"
              style={{ height: cardHeight, opacity: 0.5 }}
              className="animate-pulse"
            />
          ))}
        </Box>
      );

    case 'full-screen':
      return (
        <Box position="fixed" inset={0} zIndex={100} bg="var(--ui-color-bg-base)" display="flex" alignItems="center" justifyContent="center" padding={6} role="status" aria-label={ariaLabel}>
          <Box textAlign="center">
            <Box display="flex" justifyContent="center" marginBottom={4}>
              <Spinner size="4rem" />
            </Box>
            <Text variant="high" size="lg" weight="medium" block>{message}</Text>
            <Text variant="low" size="sm" block marginTop={1}>This may take a moment...</Text>
          </Box>
        </Box>
      );

    case 'inline':
      return (
        <Box display="inline-flex" alignItems="center" gap={2} role="status" aria-label={ariaLabel}>
          <Spinner size="1rem" />
          <Text variant="low" size={inlineSize}>{message}</Text>
        </Box>
      );

    case 'card':
      const cardCount = cardConfig?.count || 3;
      return (
        <Box display="grid" gap={4} role="status" aria-label={ariaLabel}>
          {Array.from({ length: cardCount }).map((_, index) => (
            <Box
              key={index}
              bg="var(--ui-color-bg-surface-muted)"
              rounded="xl"
              style={{ height: cardHeight, border: '1px solid var(--ui-color-border-default)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}
            >
              <Spinner size="2rem" />
            </Box>
          ))}
        </Box>
      );

    default:
      return null;
  }
}

export function FullScreenLoading({ message = 'Loading...' }: Pick<LoadingWrapperProps, 'message'>) {
  return <LoadingWrapper variant="full-screen" message={message} />;
}

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

export function SkeletonLoading({ skeletonCount = 3 }: Pick<LoadingWrapperProps, 'skeletonCount'>) {
  return <LoadingWrapper variant="skeleton" skeletonCount={skeletonCount} />;
}

export function CardLoading({ cardConfig }: Pick<LoadingWrapperProps, 'cardConfig'>) {
  return <LoadingWrapper variant="card" cardConfig={cardConfig} />;
}
