import React, { FC, useState, useCallback, useMemo } from "react";
import Input from "./BaseInput";
import { NumberInputProps } from "./interface";
import clsx from "clsx";
import { filterNumAndLimit, toDefaultNumber, getDecimalNumber } from "@utils/FormatNumber";
import { last, dropLast, compose, concat } from "ramda";

// 最小值
export const _NORMALIZED_MIN_ = 0;
// 最大值
export const _NORMALIZED_MAX_ = 9999999999;

const NumberInput: FC<NumberInputProps> = props => {
  const [isFocus, setIsFocus] = useState(false);

  const {
    scale,
    value,
    min,
    max,
    error,
    proOnBlur,
    proOnFocus,
    limitInputStep,
    step,
    onChange,
    allowNegative,

    ...otherProps
  } = props;

  const onBlur = useCallback(
    (v: any) => {
      proOnBlur?.(v);
      setIsFocus(false);
    },
    [proOnBlur]
  );
  const onFocus = useCallback(
    (v: any) => {
      proOnFocus?.(v);
      setIsFocus(true);
    },
    [proOnFocus]
  );

  const onRootInputChange = useCallback(
    (e: any) => {
      let val = e?.target?.value;

      const numScale = toDefaultNumber(scale) ?? 8;
      //  输入精度验证
      const iptEnterLimit = filterNumAndLimit(val, numScale);
      if (!iptEnterLimit) return;

      // 输入max验证
      const numValue = toDefaultNumber(val);
      const numMax = toDefaultNumber(max);

      if (numMax && numValue > numMax) {
        return;
      }

      /**
       * 末尾修正: 比如价格BTC/USDT的为0.5
       * 1.0 - 1.4 =>  1.0
       * 1.5 - 1.9 => 1.5
       */
      const stepVal = toDefaultNumber(step);

      if (limitInputStep && stepVal > 1) {
        const iptScale = getDecimalNumber(val);

        if (iptScale >= numScale) {
          const lastVal = toDefaultNumber(last(val));
          const stepValNum = toDefaultNumber(last(stepVal.toString()));
          const lastNum = (lastVal >= stepValNum ? stepValNum : 0).toString();

          val = compose((_v: string) => {
            return concat(_v, lastNum);
          }, dropLast(1))(val);
        }
      }

      onChange?.(val);
    },
    [onChange, scale, max, step]
  );

  const statusClassName = useMemo(() => {
    return error ? "error" : isFocus ? "focus" : "";
  }, [error, isFocus]);

  return (
    <Input
      {...otherProps}
      className={clsx(statusClassName, props.className)}
      onFocus={onFocus}
      onBlur={onBlur}
      onChange={onRootInputChange}
      value={value}
    />
  );
};

NumberInput.defaultProps = {
  scale: 8,
  value: "",
  min: _NORMALIZED_MIN_,
  max: _NORMALIZED_MAX_,
  step: 1
};
export { NumberInputProps } from "./interface";

export default NumberInput;
