import React, { forwardRef } from 'react';
import { clsx } from 'clsx';

export interface LoadingSpinnerProps {
  /** Tamaño del spinner */
  size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
  /** Variante del spinner */
  variant?: 'spinner' | 'dots' | 'pulse' | 'skeleton';
  /** Color personalizado */
  color?: 'primary' | 'secondary' | 'white' | 'gray';
  /** Texto de carga opcional */
  text?: string;
  /** Mostrar como overlay de pantalla completa */
  overlay?: boolean;
  /** Centrar el spinner */
  centered?: boolean;
  /** Clase CSS adicional */
  className?: string;
  /** Props adicionales para accesibilidad */
  'aria-label'?: string;
}

const LoadingSpinner = forwardRef<HTMLDivElement, LoadingSpinnerProps>(({
  size = 'md',
  variant = 'spinner',
  color = 'primary',
  text,
  overlay = false,
  centered = false,
  className,
  'aria-label': ariaLabel = 'Cargando',
  ...props
}, ref) => {
  const sizeClasses = {
    xs: 'w-4 h-4',
    sm: 'w-6 h-6',
    md: 'w-8 h-8',
    lg: 'w-12 h-12',
    xl: 'w-16 h-16'
  };

  const colorClasses = {
    primary: 'text-[var(--color-primary)]',
    secondary: 'text-[var(--color-secondary)]',
    white: 'text-white',
    gray: 'text-[var(--text-tertiary)]'
  };

  const textSizeClasses = {
    xs: 'text-xs',
    sm: 'text-sm',
    md: 'text-base',
    lg: 'text-lg',
    xl: 'text-xl'
  };

  const SpinnerIcon = () => (
    <svg
      className={clsx(
        'animate-spin',
        sizeClasses[size],
        colorClasses[color]
      )}
      xmlns="http://www.w3.org/2000/svg"
      fill="none"
      viewBox="0 0 24 24"
      role="img"
      aria-label={ariaLabel}
    >
      <circle
        className="opacity-25"
        cx="12"
        cy="12"
        r="10"
        stroke="currentColor"
        strokeWidth="4"
      />
      <path
        className="opacity-75"
        fill="currentColor"
        d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
      />
    </svg>
  );

  const DotsSpinner = () => {
    const dotSize = size === 'xs' ? 'w-1 h-1' : size === 'sm' ? 'w-1.5 h-1.5' : size === 'md' ? 'w-2 h-2' : size === 'lg' ? 'w-3 h-3' : 'w-4 h-4';

    return (
      <div className="flex space-x-1" role="img" aria-label={ariaLabel}>
        {[0, 1, 2].map((i) => (
          <div
            key={i}
            className={clsx(
              'rounded-full animate-pulse',
              dotSize,
              color === 'white' ? 'bg-white' :
              color === 'primary' ? 'bg-[var(--color-primary)]' :
              color === 'secondary' ? 'bg-[var(--color-secondary)]' :
              'bg-[var(--text-tertiary)]'
            )}
            style={{
              animationDelay: `${i * 0.2}s`,
              animationDuration: '1.4s'
            }}
          />
        ))}
      </div>
    );
  };

  const PulseSpinner = () => (
    <div
      className={clsx(
        'animate-pulse rounded-full',
        sizeClasses[size],
        color === 'white' ? 'bg-white' :
        color === 'primary' ? 'bg-[var(--color-primary)]' :
        color === 'secondary' ? 'bg-[var(--color-secondary)]' :
        'bg-[var(--text-tertiary)]'
      )}
      role="img"
      aria-label={ariaLabel}
    />
  );

  const SkeletonSpinner = () => {
    const skeletonHeight = size === 'xs' ? 'h-3' : size === 'sm' ? 'h-4' : size === 'md' ? 'h-6' : size === 'lg' ? 'h-8' : 'h-12';

    return (
      <div className="space-y-2 animate-pulse" role="img" aria-label={ariaLabel}>
        <div className={clsx('bg-[var(--bg-quaternary)] rounded', skeletonHeight, 'w-full')} />
        <div className={clsx('bg-[var(--bg-quaternary)] rounded', skeletonHeight, 'w-3/4')} />
        <div className={clsx('bg-[var(--bg-quaternary)] rounded', skeletonHeight, 'w-1/2')} />
      </div>
    );
  };

  const renderSpinner = () => {
    switch (variant) {
      case 'dots':
        return <DotsSpinner />;
      case 'pulse':
        return <PulseSpinner />;
      case 'skeleton':
        return <SkeletonSpinner />;
      default:
        return <SpinnerIcon />;
    }
  };

  const containerClasses = clsx(
    'flex items-center',
    {
      'justify-center': centered,
      'flex-col': text && variant !== 'skeleton',
      'gap-3': text,
    },
    className
  );

  const content = (
    <div className={containerClasses} ref={ref} {...props}>
      {renderSpinner()}
      {text && variant !== 'skeleton' && (
        <span
          className={clsx(
            'font-medium mt-4',
            textSizeClasses[size],
            colorClasses[color],
            {
              'text-white': overlay && color !== 'white',
              'text-[var(--text-secondary)]': !overlay && color !== 'white'
            }
          )}
          role="status"
          aria-live="polite"
        >
          {text}
        </span>
      )}
    </div>
  );

  if (overlay) {
    return (
      <div className="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50">
        <div className="bg-[var(--bg-primary)] rounded-lg p-6">
          {content}
        </div>
      </div>
    );
  }

  return content;
});

LoadingSpinner.displayName = 'LoadingSpinner';

export { LoadingSpinner };