import React, { useContext, cloneElement, Fragment } from 'react';
import './index.less';
import classNames from 'classnames';
import { ConfigContext } from '../../config/globalConfig';
import Bar from './bar';

type typeProps = 'quota' | 'degree' | 'ratio'; // quota指标 degree 度量 比例

export type ProgressDotRender = (
  iconDot: any,
  index: number,
) => React.ReactNode;

interface ScaleBarProps {
  className?: string;
  title?: string | React.ReactNode;
  heightLightColor?: string; // 当前高亮的颜色（自定义数组时候失效）
  current?: number; //当前高亮的位置
  height?: string | number; // 高度
  textarea: string[] | React.ReactNode[];
  textareaColor?: string;
  textareaPosition?: 'bottom' | 'top';
  intervalColor?: string[];
  animation?: boolean;
  trailColor?: string; // 未完成分段颜色
  type?: typeProps;
  //===degree========
  percent?: number; // 百分比
  strokeColor?: { [percentage: string]: string } | string; // 进度条线的色彩，传入 object 时为渐变
  //===ratio========

  //todo:
  activeColor?: string; // 激活颜色

  //=======新的调用方式======
  progressDot?: ProgressDotRender | boolean;
}

const ScaleBar: React.FC<ScaleBarProps> = (props): React.ReactElement => {
  let uuid = 0;
  const getPrefixCls = useContext(ConfigContext);
  const prefixCls = getPrefixCls('scale-bar');

  const {
    type = 'quota',
    textareaPosition = 'bottom',
    heightLightColor,
    height,
    animation,
    current = 0,
    textarea = ['一般', '正常', '良好', '极佳'],
    intervalColor = [],
    textareaColor,
    strokeColor,
    trailColor,
    percent,
    className = 'test',
    title,
    progressDot,
    children,
  } = props;

  const spanClassname = (index: number) => {
    return classNames({
      [`${prefixCls}-item-span`]: true,
      [`${prefixCls}-item-span-first`]: index === 0,
      [`${prefixCls}-item-span-last`]: index === textarea.length - 1,
      [`${prefixCls}-item-span-background`]: index === current,
      [`${prefixCls}-item-span-active`]: !!animation && index === current,
    });
  };

  const heightLightColorSty = (index: number): string | undefined => {
    let diffTrailColor = index !== current && trailColor ? trailColor : null;
    return intervalColor.length > 0
      ? intervalColor[index]
      : index === current
      ? heightLightColor
      : diffTrailColor
      ? diffTrailColor
      : '';
  };

  const arrowClassname = (index: number) => {
    return classNames({
      [`${prefixCls}-item-arrow`]:
        intervalColor.length > 0 ? index === current : false,
    });
  };

  const wrapClassname = classNames(prefixCls, className);

  const textClassname = (index: number) => {
    return classNames(`${prefixCls}-item-text`, {
      [`${prefixCls}-item-text-color`]:
        intervalColor.length > 0 ? true : index === current,
    });
  };

  const renderQuotaType = (): React.ReactNode => {
    return textarea.map((item, index) => {
      const text = <div className={textClassname(index)}>{item}</div>;
      return (
        <div
          className={`${prefixCls}-item`}
          key={item + `${index}`}
          style={{
            [heightLightColorSty(index) ? `color` : '']:
              heightLightColorSty(index),
          }}
        >
          {textareaPosition === 'top' && text}
          <span
            className={arrowClassname(index)}
            style={{ borderTopColor: intervalColor[index] }}
          />
          <span
            className={spanClassname(index)}
            style={{ height, backgroundColor: heightLightColorSty(index) }}
          />
          {textareaPosition === 'bottom' && text}
        </div>
      );
    });
  };

  // translate color
  type StringGradients = { [percentage: string]: string };
  const sortGradient = (gradients: StringGradients) => {
    let tempArr: any[] = [];
    Object.keys(gradients).forEach((key) => {
      const formattedKey = parseFloat(key.replace(/%/g, ''));
      if (!isNaN(formattedKey)) {
        tempArr.push({
          key: formattedKey,
          value: gradients[key],
        });
      }
    });
    tempArr = tempArr.sort((a, b) => a.key - b.key);
    return tempArr.map(({ key, value }) => `${value} ${key}%`).join(', ');
  };

  const strokeSty = (): any => {
    if (!strokeColor) return {};
    const bcColor = typeof strokeColor === 'string';
    if (bcColor) {
      return {
        ['backgroundColor']: strokeColor,
      };
    } else if (typeof strokeColor === 'object') {
      return {
        ['backgroundImage']: `linear-gradient(to right, ${sortGradient(
          strokeColor,
        )})`,
      };
    }
  };

  const getKey = () => {
    return uuid++;
  };

  const strokeClassname = classNames([`${prefixCls}-degree-stroke`], {
    [`${prefixCls}-degree-stroke-active`]: type === 'degree' || !!animation,
  });

  const renderDegreeType = (): React.ReactNode => {
    const text: React.ReactNode = (
      <div className={`${prefixCls}-content`}>
        {textarea.map((item) => {
          return (
            <div
              className={`${prefixCls}-degree-text`}
              style={{ color: textareaColor }}
              key={getKey()}
            >
              {item}
            </div>
          );
        })}
      </div>
    );
    return (
      <React.Fragment>
        {textareaPosition === 'top' && text}
        <div className={`${prefixCls}-degree`} style={{ height }}>
          <div className={`${prefixCls}-degree-placeholder`}>
            {textarea.map((i, idx) => {
              return <span key={idx} />;
            })}
          </div>
          <div
            className={strokeClassname}
            style={{ width: `${percent}%`, ...strokeSty() }}
          />
          <div
            className={`${prefixCls}-degree-background`}
            style={{ backgroundColor: trailColor }}
          />
        </div>
        {textareaPosition === 'bottom' && text}
      </React.Fragment>
    );
  };

  const renderNode: React.ReactNode =
    type === 'quota'
      ? renderQuotaType()
      : type === 'degree'
      ? renderDegreeType()
      : null;

  const titleNode: React.ReactNode = title && (
    <div className={`${prefixCls}-title`}>{title}</div>
  );

  return (
    <div className={wrapClassname}>
      {titleNode}
      <div className={type === 'quota' ? `${prefixCls}-flex` : ''}>
        {renderNode}
      </div>
    </div>
  );
};

export default ScaleBar;
