import { ComponentPropsWithRef, forwardRef, ReactNode } from 'react';
import { cx } from 'class-variance-authority';

import './spinner.css';

const realSize = 40;

type SpinnerProps = ComponentPropsWithRef<'div'> & {
  children?: ReactNode;
  className?: string;
  color?: string;
  size?: number;
  strokeSize?: number;
};

export const Spinner = forwardRef<HTMLDivElement, SpinnerProps>(
  ({ children, className, color = 'currentColor', size = 30, strokeSize, ...delegated }, ref) => {
    const viewSize = size || realSize;
    const sizeHalf = realSize / 2;

    return (
      <div ref={ref} className={cx('c-spinner', className)} data-testid="loading-spinner" {...delegated}>
        <svg viewBox={`0 0 ${realSize} ${realSize}`} x="0px" y="0px" style={{ width: viewSize, height: viewSize }}>
          <circle
            cx="20"
            cy="20"
            r="18"
            style={{
              stroke: color,
              strokeWidth: strokeSize ? strokeSize : viewSize / 10,
              strokeLinecap: 'round',
              strokeDasharray: size < 16 ? size * 6 : size * 3.5,
              transformOrigin: `${sizeHalf}px ${sizeHalf}px 0`,
            }}
            className="c-spinner-artifact"
          />
        </svg>
        {children && (
          <span className="c-spinner-children" style={{ fontSize: size ? `${size * 0.75}px` : '1em' }}>
            {children}
          </span>
        )}
      </div>
    );
  },
);

Spinner.displayName = 'Spinner';
