import React, { ReactElement, SVGProps, useContext } from 'react';
import { ThemeContext, DefaultTheme } from 'styled-components';
import css from '../../utils/css';
import Icon from '../Icon';

import { CommonProps } from '../common';
import { Info, Wrapper } from './StyledProgressCircle';

interface ProgressCircleProps extends CommonProps {
  intent: 'primary' | 'danger' | 'success' | 'warning' | 'error';
  size: 'small' | 'medium';
  status: 'active' | 'exception' | 'custom';
  value: number;
  withInfo: boolean;
}

const FULL_CIRCLE = 295.31;

const SQUARE_SVG = '0 0 100 100';

const CIRCLE_PATH_PROPS = {
  d: `M 50,50 m 0,-47
  a 47,47 0 1 1 0,94
  a 47,47 0 1 1 0,-94`,
  fillOpacity: 0,
  strokeLinecap: 'round',
  strokeDashoffset: '0px',
} as SVGProps<SVGPathElement>;

const STROKE_ANIMATION = {
  transition:
    'stroke-dashoffset 0.4s ease 0s, stroke-dasharray 0.4s ease 0s, stroke 0.4s ease 0s, stroke-width 0.06s ease 0.3s, opacity 0.4s ease 0s',
};

export const mapColorFromIntent = (
  intent: ProgressCircleProps['intent'],
  theme: DefaultTheme
): string =>
  ({
    primary: theme.colors.progress.primary,
    danger: theme.colors.progress.danger,
    success: theme.colors.progress.success,
    warning: theme.colors.progress.warning,
    error: theme.colors.progress.error,
  }[intent]);

export const mapStrokeWidthFromSize = (
  size: ProgressCircleProps['size'],
  theme: DefaultTheme
): string =>
  ({
    small: theme.sizes.progress.circleSmallStroke,
    medium: theme.sizes.progress.circleMediumStroke,
  }[size]);

const ProgressCircle = ({
  intent,
  size,
  status,
  withInfo,
  value,
  id,
  className,
  style,
  sx = {},
  'data-test-id': dataTestId,
}: ProgressCircleProps): ReactElement => {
  const theme = useContext(ThemeContext);
  const stroke = ((value === undefined ? 0 : value) / 100) * FULL_CIRCLE;
  const strokeColor = mapColorFromIntent(intent, theme);
  const strokeWidth = mapStrokeWidthFromSize(size, theme);

  return (
    <Wrapper
      themeSize={size}
      id={id}
      className={className}
      style={{ ...style, ...css(sx) }}
      data-test-id={dataTestId}
    >
      <svg viewBox={SQUARE_SVG}>
        <path
          stroke={theme.colors.progress.circleStroke}
          strokeWidth={strokeWidth}
          strokeDasharray={`${FULL_CIRCLE}px, ${FULL_CIRCLE}px`}
          {...CIRCLE_PATH_PROPS}
        />
        <path
          stroke={strokeColor}
          strokeWidth={strokeWidth}
          strokeDasharray={`${stroke}px, ${FULL_CIRCLE}px`}
          style={STROKE_ANIMATION}
          {...CIRCLE_PATH_PROPS}
        />
      </svg>
      {withInfo === true && (
        <Info>
          {status === 'exception' && <Icon icon="cancel" intent={intent} />}
          {status === 'active' && value === 100 && (
            <Icon icon="checkmark" intent={intent} />
          )}
          {((status === 'active' && value < 100) || status === 'custom') &&
            `${value}%`}
        </Info>
      )}
    </Wrapper>
  );
};

export default ProgressCircle;
