import type { ICircularProgressProps } from "./CircularProgress.d"
import type { JSX } from "react"

import { FunctionComponent } from "react"

import cs from "classnames"

import styles from "./CircularProgress.module.scss"

const clampPercentage = (value: number): number => {
	if (Number.isNaN(value)) return 0
	return Math.min(100, Math.max(0, value))
}

export const CircularProgress: FunctionComponent<ICircularProgressProps> = ({
	percentage,
	className,
	bgClassName,
	valueClassName,
	color,
	size = 48,
	strokeWidth = 4,
	strokeLinecap = "round",
	ariaLabel,
}): JSX.Element => {
	const safePercentage = clampPercentage(percentage)
	const radius = (size - strokeWidth) / 2
	const circumference = radius * 2 * Math.PI
	const offset = circumference - (safePercentage / 100) * circumference

	const ariaProps = ariaLabel
		? { role: "img", "aria-label": ariaLabel }
		: { "aria-hidden": true }

	return (
		<svg
			width={size}
			height={size}
			viewBox={`0 0 ${size} ${size}`}
			className={cs(styles.root, className)}
			data-testid="CircularProgress"
			{...ariaProps}
		>
			<circle
				className={bgClassName}
				strokeWidth={strokeWidth}
				fill="transparent"
				r={radius}
				cx={size / 2}
				cy={size / 2}
			/>
			<circle
				className={valueClassName}
				stroke={color}
				strokeWidth={strokeWidth}
				fill="transparent"
				r={radius}
				cx={size / 2}
				cy={size / 2}
				strokeDasharray={circumference}
				strokeDashoffset={offset}
				strokeLinecap={strokeLinecap}
			/>
		</svg>
	)
}
