import { Slot } from '@radix-ui/react-slot';
import { type VariantProps, cva } from 'class-variance-authority';
import * as React from 'react';
import { cn } from '../..';
import styles from './CircularProgress.module.css';

export const circularProgressVariants = cva(styles.CircularProgress, {
  variants: {
    variant: {
      default: styles.default,
    },
  },
  defaultVariants: {
    variant: 'default',
  },
});

export interface CircularProgressProps
  extends React.HTMLAttributes<HTMLDivElement>,
    VariantProps<typeof circularProgressVariants> {
  asChild?: boolean;
  value: number;
  size?: number;
}

const BaseCircularProgress = React.forwardRef<
  HTMLDivElement,
  CircularProgressProps
>(({ className, variant, asChild = false, ...props }, ref) => {
  const Comp = asChild ? Slot : 'div';
  return (
    <Comp
      className={cn(
        styles.CircularProgress,
        circularProgressVariants({ variant, className }),
      )}
      ref={ref}
      {...props}
    />
  );
});

export const CircularProgress: React.FC<CircularProgressProps> = ({
  value,
  size = 24,
}) => {
  const strokeWidth = size * 0.2;
  const radius = (size - strokeWidth) / 2;
  const circumference = radius * 2 * Math.PI;
  const strokeDashoffset = circumference - (value / 100) * circumference;

  return (
    <BaseCircularProgress value={size} className={cn(circularProgressVariants)}>
      <svg
        className={cn(styles.CircularProgressSVG)}
        width={size}
        height={size}
      >
        <circle
          className={cn(styles.CircularProgressTrack)}
          strokeWidth={strokeWidth}
          stroke="currentColor"
          fill="transparent"
          r={radius}
          cx={size / 2}
          cy={size / 2}
        />
        <circle
          className={cn(styles.CircularProgressIndicator)}
          strokeWidth={strokeWidth}
          strokeDasharray={circumference}
          strokeDashoffset={strokeDashoffset}
          strokeLinecap="round"
          stroke="currentColor"
          fill="transparent"
          r={radius}
          cx={size / 2}
          cy={size / 2}
        />
      </svg>
    </BaseCircularProgress>
  );
};
