import _extends from "@babel/runtime/helpers/extends";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import React from 'react';
import { createBEM } from '@zarm-design/bem';
import { Minus as MinusIcon, Plus as PlusIcon } from '@zarm-design/icons';
import Button from '../button';
import { ConfigContext } from '../config-provider';
import CustomInput from '../custom-input';
import Input from '../input';

var compareValue = function compareValue(value, max, min) {
  if (typeof max === 'number') {
    value = value > max ? max : value;
  }

  if (typeof min === 'number') {
    value = value < min ? min : value;
  }

  return value;
};

var getPrecision = function getPrecision(value) {
  var valueStr = value === null || value === void 0 ? void 0 : value.toString();

  if (valueStr && valueStr.indexOf('e-') >= 0) {
    return parseInt(valueStr.slice(valueStr.indexOf('-e')), 10);
  }

  var precision = 0;

  if (valueStr && valueStr.indexOf('.') >= 0) {
    precision = valueStr.length - valueStr.indexOf('.') - 1;
  }

  return precision;
};

var getMaxPrecision = function getMaxPrecision(currentValue, step) {
  var stepPrecision = getPrecision(step);
  var currentValuePrecision = getPrecision(currentValue);
  return Math.max(currentValuePrecision, stepPrecision);
};

var getPrecisionFactor = function getPrecisionFactor(currentValue, step) {
  var precision = getMaxPrecision(currentValue, step);
  return Math.pow(10, precision);
};

var formatValue = function formatValue(currentValue, step) {
  var precision = getMaxPrecision(currentValue, step); // 小数当字符串处理，因为1.00在jstoFixed(2)返回的是字符串

  if (precision > 0) {
    return Number(currentValue).toFixed(precision);
  }

  return Number(Number(currentValue).toFixed(precision));
};

var getValue = function getValue(props, defaultValue) {
  var value = props.value,
      max = props.max,
      min = props.min,
      step = props.step;
  var tempValue = props.defaultValue === undefined ? defaultValue : props.defaultValue;
  tempValue = value === undefined ? tempValue : value;
  return formatValue(compareValue(tempValue, max, min), step);
};

var Stepper = /*#__PURE__*/React.forwardRef(function (props, ref) {
  var _ref;

  var className = props.className,
      style = props.style,
      shape = props.shape,
      disabled = props.disabled,
      size = props.size,
      type = props.type,
      disableInput = props.disableInput,
      step = props.step,
      max = props.max,
      min = props.min,
      value = props.value,
      defaultValue = props.defaultValue,
      onChange = props.onChange,
      onInputChange = props.onInputChange;
  var stepperRef = ref || /*#__PURE__*/React.createRef();

  var _React$useState = React.useState(getValue({
    value: value,
    defaultValue: defaultValue,
    min: min,
    max: max
  }, 0)),
      _React$useState2 = _slicedToArray(_React$useState, 2),
      currentValue = _React$useState2[0],
      setCurrentValue = _React$useState2[1];

  var _React$useState3 = React.useState(getValue({
    value: value,
    defaultValue: defaultValue,
    min: min,
    max: max,
    step: step
  }, 0)),
      _React$useState4 = _slicedToArray(_React$useState3, 2),
      lastValue = _React$useState4[0],
      setLastValue = _React$useState4[1];

  var _React$useContext = React.useContext(ConfigContext),
      prefixCls = _React$useContext.prefixCls;

  var bem = createBEM('stepper', {
    prefixCls: prefixCls
  });

  var onInputChangeCallback = function onInputChangeCallback(newValue) {
    setCurrentValue(newValue);
    onInputChange === null || onInputChange === void 0 ? void 0 : onInputChange(newValue);
  };

  var onInputBlur = function onInputBlur(newValue) {
    var newCurrentValue = newValue;

    if (Number.isNaN(Number(newValue))) {
      newCurrentValue = lastValue;
    }

    newCurrentValue = formatValue(compareValue(newCurrentValue, max, min), step);
    setCurrentValue(newCurrentValue);
    setLastValue(newCurrentValue);
    onChange === null || onChange === void 0 ? void 0 : onChange(newCurrentValue);
  };

  var isSubDisabled = function isSubDisabled() {
    if (min === null) {
      return false;
    }

    return currentValue <= min || disabled;
  };

  var isPlusDisabled = function isPlusDisabled() {
    if (max === null) {
      return false;
    }

    return currentValue >= max || disabled;
  };

  var onSubClick = function onSubClick() {
    if (isSubDisabled()) {
      return;
    }

    var precisionFactor = getPrecisionFactor(currentValue, step);
    var precision = getMaxPrecision(currentValue, step);
    var newValue = (precisionFactor * Number(currentValue) - precisionFactor * step) / precisionFactor;
    onInputBlur(newValue.toFixed(precision));
  };

  var onPlusClick = function onPlusClick() {
    if (isPlusDisabled()) {
      return;
    }

    var precisionFactor = getPrecisionFactor(currentValue, step);
    var precision = getMaxPrecision(currentValue, step);
    var newValue = (precisionFactor * Number(currentValue) + precisionFactor * step) / precisionFactor;
    onInputBlur(newValue.toFixed(precision));
  };

  React.useEffect(function () {
    var newValue = getValue({
      value: value,
      defaultValue: defaultValue,
      min: min,
      max: max,
      step: step
    }, 0);
    setCurrentValue(newValue);
    setLastValue(newValue);
  }, [value, defaultValue, min, max, step]);
  var cls = bem([(_ref = {}, _defineProperty(_ref, "".concat(shape), !!shape), _defineProperty(_ref, "".concat(size), !!size), _defineProperty(_ref, "disabled", disabled), _ref), className]);
  var inputCls = bem('input', [{
    disabled: disableInput
  }]);
  var buttonSize = size === 'lg' ? 'sm' : 'xs';
  var inputProps = {
    className: inputCls,
    type: type,
    value: currentValue,
    disabled: disabled || disableInput,
    clearable: false,
    onChange: function onChange() {
      return !disabled && onInputChangeCallback(currentValue);
    },
    onBlur: function onBlur() {
      return !disabled && onInputBlur(currentValue);
    }
  };
  return /*#__PURE__*/React.createElement("span", {
    ref: stepperRef,
    className: cls,
    style: style
  }, /*#__PURE__*/React.createElement(Button, {
    className: bem('sub'),
    size: buttonSize,
    disabled: isSubDisabled(),
    shape: shape,
    onClick: onSubClick
  }, /*#__PURE__*/React.createElement(MinusIcon, null)), ['price'].indexOf(type) > -1 ? /*#__PURE__*/React.createElement(CustomInput, _extends({}, inputProps, {
    onChange: function onChange(v) {
      return !disabled && onInputChangeCallback(v);
    }
  })) : /*#__PURE__*/React.createElement(Input, _extends({}, inputProps, {
    onChange: function onChange(e) {
      return !disabled && onInputChangeCallback(e.target.value);
    }
  })), /*#__PURE__*/React.createElement(Button, {
    className: bem('plus'),
    size: buttonSize,
    disabled: isPlusDisabled(),
    shape: shape,
    onClick: onPlusClick
  }, /*#__PURE__*/React.createElement(PlusIcon, null)));
});
Stepper.displayName = 'Stepper';
Stepper.defaultProps = {
  shape: 'radius',
  disabled: false,
  step: 1,
  type: 'number',
  disableInput: false
};
export default Stepper;