import type { HTMLAttributes, ReactNode } from 'react';
import { useId, useMemo } from 'react';
import type { ProgressColor } from '../types';
import './progress.css';

export type CircularProgressProps = {
  value: number;
  max?: number;
  color?: ProgressColor;
  size?: number; // px
  thickness?: number; // stroke width
  showLabel?: boolean;
  label?: ReactNode;
  ariaLabel?: string;
} & Omit<HTMLAttributes<HTMLDivElement>, 'children'>;

function clamp(n: number, min: number, max: number) {
  return Math.min(max, Math.max(min, n));
}

export function CircularProgress({
  value,
  max = 100,
  color = 'primary',
  size = 56,
  thickness = 6,
  showLabel = true,
  label,
  ariaLabel,
  className,
  ...rest
}: CircularProgressProps) {
  const id = useId().replace(/:/g, '');
  const percent = useMemo(() => {
    if (!Number.isFinite(value) || !Number.isFinite(max) || max <= 0) return 0;
    return clamp((value / max) * 100, 0, 100);
  }, [max, value]);

  const r = useMemo(() => (size - thickness) / 2, [size, thickness]);
  const c = useMemo(() => 2 * Math.PI * r, [r]);
  const dash = useMemo(() => (percent / 100) * c, [c, percent]);

  const text = useMemo(() => {
    if (label != null) return label;
    if (!showLabel) return null;
    return `${Math.round(percent)}%`;
  }, [label, percent, showLabel]);

  return (
    <div
      id={`ccl-circular-progress-${id}`}
      className={['ccl-circular-progress', className ?? ''].filter(Boolean).join(' ')}
      role="progressbar"
      aria-label={ariaLabel}
      aria-valuemin={0}
      aria-valuemax={max}
      aria-valuenow={value}
      style={
        {
          width: size,
          height: size,
          ['--ccl-progress-accent' as never]: `var(--ccl-progress-${color})`,
        } as React.CSSProperties
      }
      {...rest}
    >
      <svg className="ccl-circular-progress__svg" width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
        <circle
          className="ccl-circular-progress__track"
          cx={size / 2}
          cy={size / 2}
          r={r}
          strokeWidth={thickness}
        />
        <circle
          className="ccl-circular-progress__bar"
          cx={size / 2}
          cy={size / 2}
          r={r}
          strokeWidth={thickness}
          strokeDasharray={`${dash} ${c - dash}`}
        />
      </svg>
      {text ? <div className="ccl-circular-progress__label">{text}</div> : null}
    </div>
  );
}

