import cx from "classnames";
import React, { ForwardedRef } from "react";

const getMaxValue = (radius: number): number =>
  Math.PI * (radius + radius * 0.22) * 2;

const getStrokeDasharray = (max: number, percentage: number): string => {
  const fullCircleLength = max;
  const strokeLength = (max / 2) * (percentage / 100);
  return `${strokeLength}, ${fullCircleLength}`;
};

const clamp = (num: number, min = 0, max = 100): number => {
  return Math.min(Math.max(num, min), max);
};

const CLASS_ROOT = "gauge";

export interface GaugeProps {
  /** Text inside the gauge */
  children?: React.ReactNode;
  /** Value filling the gauge */
  percentage?: number;
  className?: string;
  [key: string]: any;
}

const Gauge = React.forwardRef(
  (
    { children, className, percentage = 0, ...other }: GaugeProps,
    ref: ForwardedRef<HTMLElement>,
  ) => {
    const radius = 100;
    const maxValue = getMaxValue(radius);

    const circleAttrs = {
      r: radius,
      cx: 110,
      cy: 110,
      strokeWidth: 15,
      fill: "none",
      transform: "rotate(160, 110, 110)",
    } as const;

    return (
      <figure ref={ref} className={cx(`${CLASS_ROOT}`, className)} {...other}>
        <svg
          width="220"
          height="150"
          viewBox="0 0 220 150"
          className={`${CLASS_ROOT}__dial`}
        >
          <circle
            className={`${CLASS_ROOT}__display`}
            strokeDasharray={getStrokeDasharray(maxValue, 100)}
            {...circleAttrs}
          />
          <circle
            className={`${CLASS_ROOT}__indicator`}
            strokeDasharray={getStrokeDasharray(maxValue, clamp(percentage))}
            {...circleAttrs}
          />
        </svg>
        <figcaption className={`${CLASS_ROOT}__text`}>{children}</figcaption>
      </figure>
    );
  },
);

Gauge.displayName = "Gauge";

export { Gauge };
