import React from "react";
import classNames from "classnames";
import { injectValue } from "../_util/inject-value";
import { useConfig } from "../_util/config-context";
import { StyledProps } from "../_type";

export interface ProgressProps extends StyledProps {
  /**
   * 进度条类型
   *
   * @default "line"
   */
  type?: "line" | "circle";

  /**
   * 百分比，取值 \[0, 100\]
   *
   * @default 0
   */
  percent?: number;

  /**
   * 描述内容
   *
   * **环形进度条中默认展示当前进度百分比**
   *
   * @docType React.ReactNode | ((percent: number) => React.ReactNode);
   */
  text?: React.ReactNode | ((percent: number) => React.ReactNode);

  /**
   * 进度条下提示内容
   *
   * 仅在 `type = "circle"` 时有效
   */
  tips?: React.ReactNode;

  /**
   * 进度条样式
   *
   * **默认将在 `percent` 小于 100 时使用 `default`，等于 100 时使用 `success`**
   */
  theme?: "default" | "success" | "danger";

  /**
   * 自定义进度条线的颜色
   * @since 2.6.10
   */
  strokeColor?: string;

  /**
   * 自定义进度条线的宽度
   * @since 2.6.10
   */
  strokeWidth?: number;

  /**
   * 自定义进度条画布的宽度
   * @since 2.6.10
   */
  width?: number;

  /**
   * 自定义图形内边距
   * @since 2.7.0
   */
  padding?: number;
}

export const Progress = React.forwardRef(function Progress(
  {
    type = "line",
    percent = 0,
    text,
    tips,
    theme = +percent === 100 ? "success" : "default",
    className,
    style = {},
    strokeColor,
    strokeWidth = type === "circle" ? 2 : 6,
    width = type === "circle" ? 160 : undefined,
    padding,
    ...restProps
  }: ProgressProps,
  ref: React.Ref<HTMLDivElement>
) {
  const { classPrefix } = useConfig();
  // Circle
  if (type === "circle") {
    if (typeof padding === "undefined") {
      // eslint-disable-next-line no-param-reassign
      padding = width - strokeWidth < 20 ? 0 : 10;
    }

    const c = width / 2;
    const r = c - strokeWidth / 2 - padding;
    const C = Math.ceil(2 * r * Math.PI);
    const numFontSize = Math.round((width / 160) * 48);
    const fontSize = Math.round(numFontSize * 0.5);
    const symFontSize = Math.round(numFontSize * 0.3);
    return (
      <div
        ref={ref}
        className={classNames(`${classPrefix}-progress-circle`, className, {
          "is-error": theme === "danger",
          "is-success": theme === "success",
        })}
        style={style}
        {...restProps}
      >
        <div
          className={`${classPrefix}-progress-circle__area`}
          style={{ width, height: width }}
        >
          <div className={`${classPrefix}-progress-circle__svg-path`}>
            <svg
              version="1.1"
              xmlns="http://www.w3.org/2000/svg"
              xmlnsXlink="http://www.w3.org/1999/xlink"
              x={width}
              y={width}
              width={width}
              height={width}
              viewBox={`0 0 ${width} ${width}`}
              xmlSpace="preserve"
            >
              <circle
                className={`${classPrefix}-progress-circle__base-ring`}
                fill="none"
                strokeWidth={strokeWidth}
                cx={c}
                cy={c}
                r={r}
              />
              <circle
                className={`${classPrefix}-progress-circle__current-ring`}
                fill="none"
                strokeWidth={strokeWidth}
                cx={c}
                cy={c}
                r={r}
                style={{
                  stroke: strokeColor,
                  strokeDasharray: `${(C * percent) / 100}px ${C}px`,
                  transition: "stroke-dasharray .2s",
                }}
              />
            </svg>
          </div>
          <div
            className={`${classPrefix}-progress-circle__current-text`}
            style={{ fontSize: numFontSize }}
          >
            {text ? (
              <span className="text--chinese" style={{ fontSize }}>
                {injectValue(text)(percent)}
              </span>
            ) : (
              <>
                {percent}
                <i className="text--symbol" style={{ fontSize: symFontSize }}>
                  %
                </i>
              </>
            )}
          </div>
        </div>
        <div className={`${classPrefix}-progress-circle__tips`}>{tips}</div>
      </div>
    );
  }

  return (
    <div
      className={classNames(`${classPrefix}-progress`, className, {
        [`${classPrefix}-progress--error`]: theme === "danger",
        [`${classPrefix}-progress--succeed`]: theme === "success",
      })}
      style={{
        height: strokeWidth,
        width,
        marginTop: padding,
        marginLeft: padding,
        marginRight: padding,
        ...style,
      }}
      {...restProps}
    >
      <div
        className={`${classPrefix}-progress__value`}
        style={{
          width: `${percent}%`,
          transition: "width .2s",
          height: strokeWidth,
          background: strokeColor,
        }}
      >
        {text && (
          <span
            className={`${classPrefix}-progress__text`}
            style={{ top: strokeWidth + 2 }}
          >
            {injectValue(text)(percent)}
          </span>
        )}
      </div>
    </div>
  );
});

Progress.displayName = "Progress";
