import React, { useMemo } from 'react';
import styled, { keyframes } from 'styled-components';
import type { LoadingProps, Size } from '../types';

const spin = keyframes`
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
`;

const getSizeValue = (size: Size): string => {
  const sizes = {
    small: '25px',
    medium: '50px',
    large: '75px'
  };
  return sizes[size] || sizes.medium;
};

const SpinnerContainer = styled.div<{ size: Size }>`
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: ${props => props.size === 'large' ? '100vh' : 'auto'};
  width: 100%;
  gap: 1rem;
`;

const Spinner = styled.div<{ size: Size; color: string }>`
  width: ${props => getSizeValue(props.size)};
  height: ${props => getSizeValue(props.size)};
  border: 5px solid #f3f3f3;
  border-top: 5px solid ${props => props.color};
  border-radius: 50%;
  animation: ${spin} 1s linear infinite;

  @media (prefers-reduced-motion: reduce) {
    animation: none;
    border: 5px solid ${props => props.color};
  }
`;

const LoadingMessage = styled.span`
  color: inherit;
  font-size: 1rem;
  text-align: center;
  margin-top: 0.5rem;
`;

const LoadingSpinner: React.FC<LoadingProps> = React.memo(({ 
  size = 'medium',
  color = '#3498db',
  className = '',
  'aria-label': ariaLabel = 'Loading...',
  testId = 'loading-spinner',
  message
}) => {
  const spinnerSize = useMemo(() => size, [size]);
  const spinnerColor = useMemo(() => color, [color]);

  return (
    <SpinnerContainer 
      size={spinnerSize}
      className={className}
      role="progressbar" 
      aria-label={ariaLabel}
      aria-busy="true"
      data-testid={testId}
    >
      <Spinner 
        size={spinnerSize} 
        color={spinnerColor} 
        aria-hidden="true"
      />
      {message && (
        <LoadingMessage 
          className="loading-message" 
          aria-live="polite"
          role="status"
        >
          {message}
        </LoadingMessage>
      )}
    </SpinnerContainer>
  );
});

LoadingSpinner.displayName = 'LoadingSpinner';

export default LoadingSpinner;