import * as React from 'react';
import { clsx } from 'clsx';

export interface LoadingDotsProps {
  /** Tailwind-style size scale. */
  size?: 'sm' | 'md' | 'lg';
  /** Override the dot colour. Defaults to `var(--bl-accent)`. */
  color?: string;
  /** Accessible label for screen readers. */
  label?: string;
  className?: string;
}

/**
 * `<LoadingDots>` — three-dot pulsing indicator. Tiny, inline-friendly
 * alternative to `<LoadingSpinner>`. Honours `prefers-reduced-motion`
 * via Tailwind's `motion-safe:` (the dots stop pulsing but remain
 * visible).
 *
 * Composable inside chat bubbles, button labels, inline status chips.
 */
export function LoadingDots({
  size = 'md',
  color,
  label = 'Loading',
  className,
}: LoadingDotsProps) {
  const dotSize: Record<NonNullable<LoadingDotsProps['size']>, string> = {
    sm: 'h-1 w-1',
    md: 'h-1.5 w-1.5',
    lg: 'h-2 w-2',
  };
  const gap: Record<NonNullable<LoadingDotsProps['size']>, string> = {
    sm: 'gap-1',
    md: 'gap-1.5',
    lg: 'gap-2',
  };
  return (
    <span
      role="status"
      aria-label={label}
      aria-busy="true"
      data-testid="bl-loading-dots"
      className={clsx('inline-flex items-center', gap[size], className)}
    >
      {[0, 1, 2].map(i => (
        <span
          key={i}
          aria-hidden="true"
          className={clsx(dotSize[size], 'inline-block rounded-full motion-safe:animate-bounce')}
          style={{
            background: color ?? 'var(--bl-accent, #6366f1)',
            animationDelay: `${i * 120}ms`,
          }}
        />
      ))}
      <span className="sr-only">{label}</span>
    </span>
  );
}

LoadingDots.displayName = 'LoadingDots';
