'use strict';

exports.__esModule = true;

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } // require PrototypeMath.js, 用于解决加减法精度丢失的问题


var NumBox = (0, _react.forwardRef)(function (_ref, ref) {
  var disabled = _ref.disabled,
      _ref$plusAttribute = _ref.plusAttribute,
      plusAttribute = _ref$plusAttribute === undefined ? {} : _ref$plusAttribute,
      _ref$minusAttribute = _ref.minusAttribute,
      minusAttribute = _ref$minusAttribute === undefined ? {} : _ref$minusAttribute,
      _ref$inputAttribute = _ref.inputAttribute,
      inputAttribute = _ref$inputAttribute === undefined ? {} : _ref$inputAttribute,
      defaultValue = _ref.defaultValue,
      value = _ref.value,
      digits = _ref.digits,
      max = _ref.max,
      min = _ref.min,
      placeholder = _ref.placeholder,
      _ref$maxLength = _ref.maxLength,
      maxLength = _ref$maxLength === undefined ? '16' : _ref$maxLength,
      readOnly = _ref.readOnly,
      required = _ref.required,
      autoFocus = _ref.autoFocus,
      autoSelect = _ref.autoSelect,
      clickButtonFocus = _ref.clickButtonFocus,
      licon = _ref.licon,
      liconAttribute = _ref.liconAttribute,
      ricon = _ref.ricon,
      riconAttribute = _ref.riconAttribute,
      onClick = _ref.onClick,
      onChange = _ref.onChange,
      onBlur = _ref.onBlur,
      onFocus = _ref.onFocus,
      others = _objectWithoutProperties(_ref, ['disabled', 'plusAttribute', 'minusAttribute', 'inputAttribute', 'defaultValue', 'value', 'digits', 'max', 'min', 'placeholder', 'maxLength', 'readOnly', 'required', 'autoFocus', 'autoSelect', 'clickButtonFocus', 'licon', 'liconAttribute', 'ricon', 'riconAttribute', 'onClick', 'onChange', 'onBlur', 'onFocus']);

  var refEl = (0, _react.useRef)(null);
  var refElInput = (0, _react.useRef)(null);
  (0, _react.useImperativeHandle)(ref, function () {
    return refEl.current;
  });

  (0, _react.useEffect)(function () {
    if (autoFocus) {
      focus();
    }
  }, []); // eslint-disable-line

  var _useState = (0, _react.useState)(false),
      minDisabled = _useState[0],
      setMinDisabled = _useState[1];

  var _useState2 = (0, _react.useState)(false),
      maxDisabled = _useState2[0],
      setMaxDisabled = _useState2[1];

  (0, _react.useEffect)(function () {
    var val = refElInput.current.value || '';
    updateState(val);
  }, []); // eslint-disable-line

  // 更新禁用状态
  function updateState(val) {
    if (!isNaN(min) && !isNaN(val) && val <= min) {
      setMinDisabled(true);
    } else {
      setMinDisabled(false);
    }
    if (!isNaN(max) && !isNaN(val) && val >= max) {
      setMaxDisabled(true);
    } else {
      setMaxDisabled(false);
    }
  }

  function correctNumber(originVal) {
    var val = originVal;
    if (typeof val === 'number') val = String(val);
    // 最大长度
    if (maxLength && val && val.length > maxLength) {
      val = val.substring(0, maxLength);
    }
    // 小数位截取
    if (!isNaN(digits)) {
      if (val.indexOf('.') !== -1) {
        val = val.substring(0, val.indexOf('.') + Number(digits) + 1);
      }
    }
    // 输入时只校验最大值、小数点、最大长度、返回错误
    if (!isNaN(max) && !isNaN(val)) {
      if (val > max) val = max;
    }
    if (!isNaN(min) && !isNaN(val)) {
      if (val < min) val = min;
    }
    return val;
  }

  // 获取焦点时, 如果readOnly或者disabled时, 需要立即失去焦点, 解决ios会出现底栏的问题
  function focusHandler(e) {
    if (readOnly || disabled) {
      e.target.blur();
      return;
    }
    if (onFocus) onFocus(e);
  };
  // 失去焦点需要校验值是否正确
  function blurHandler(e) {
    if (readOnly || disabled) {
      return;
    }
    // 如果value和框内值不等, 设置为相等
    // if (refElInput.current && refElInput.current.value !== value) {
    //   refElInput.current.value = value;
    // }
    // 失去焦点时只校验非空、最小值
    var val = correctNumber(e.target.value);
    if (val !== '' + e.target.value) {
      change(e, val);
    }
    if (onBlur) onBlur(e);
  }
  // 点击加减号清除时获取焦点
  function focus() {
    if (disabled || readOnly || !refElInput.current) return;
    refElInput.current.focus();
    if (autoSelect) refElInput.current.select();
  }
  // 修改值回调
  function change(e, val) {
    if (defaultValue || defaultValue === '') {
      e.target.value = val;
    }
    updateState(val);
    if (onChange) onChange(e, val);
  }

  // 修改值
  function changeHandler(e) {
    var val = e.target.value;
    if (e.target.validity.badInput) {
      val = '';
    } else {
      if (val !== '') {
        val = correctNumber(val);
      }
    }
    // Callback
    change(e, val);
  };
  // 点击文本框, 逢0清空
  function clickInput(e) {
    if (inputAttribute.onClick) inputAttribute.onClick(e, value);
  }
  // 点击减
  function clickMinus(e) {
    var event = { target: refElInput.current };
    var val = correctNumber(Math.Calc.subtract(refElInput.current.value, 1));
    // Callback
    change(event, val);
    if (minusAttribute.onClick) minusAttribute.onClick(e, val);
    if (clickButtonFocus) {
      focus();
    }
  };
  // 点击加
  function clickPlus(e) {
    var event = { target: refElInput.current };
    var val = correctNumber(Math.Calc.add(refElInput.current.value, 1));
    // Callback
    change(event, val);
    if (plusAttribute.onClick) plusAttribute.onClick(e, val);
    if (clickButtonFocus) {
      focus();
    }
  };
  // 点击容器
  function click(e) {
    e.stopPropagation();
    if (disabled) return;
    var target = e.target;
    if (liconAttribute && liconAttribute.onClick && target.classList.contains('licon')) {
      liconAttribute.onClick(e, refElInput.current.value);
      return;
    }
    if (riconAttribute && riconAttribute.onClick && target.classList.contains('ricon')) {
      riconAttribute.onClick(e, refElInput.current.value);
      return;
    }
    if (target.classList.contains('numbox-input')) {
      clickInput(e);
      return;
    }
    if (target.classList.contains('numbox-button-plus')) {
      clickPlus(e);
      return;
    }
    if (target.classList.contains('numbox-button-minus')) {
      clickMinus(e);
      return;
    }
    if (onClick) onClick(e, refElInput.current.value);
  }
  // render
  function getInputDOM() {
    return _react2.default.createElement('input', _extends({
      ref: refElInput,
      type: 'number'
    }, inputAttribute, {
      className: 'numbox-input' + (inputAttribute.className ? ' ' + inputAttribute.className : ''),
      defaultValue: defaultValue,
      value: value,
      min: min,
      max: max,
      maxLength: maxLength,
      disabled: disabled,
      readOnly: readOnly,
      placeholder: placeholder,
      onChange: changeHandler,
      onFocus: focusHandler,
      onBlur: blurHandler
    }));
  }

  // 过滤已经回调的属性
  function filterProps(props) {
    if (!props) return {};

    var onClick = props.onClick,
        otherProps = _objectWithoutProperties(props, ['onClick']);

    return _extends({}, otherProps);
  }
  // 剔除掉onClick事件, 因为在容器onClick已经回调了
  var otherLiconAttribute = filterProps(liconAttribute);
  var otherRiconAttribute = filterProps(riconAttribute);
  return _react2.default.createElement(
    'div',
    _extends({ ref: refEl }, others, { disabled: min >= max || disabled, className: 'numbox' + (others.className ? ' ' + others.className : ''), onClick: click }),
    _react2.default.createElement('input', _extends({
      value: '-',
      disabled: minDisabled
    }, plusAttribute, {
      type: 'button',
      className: 'numbox-button numbox-button-minus' + (plusAttribute.className ? ' ' + plusAttribute.className : '')
    })),
    licon && licon,
    otherLiconAttribute && !Object.isEmptyObject(otherLiconAttribute) && _react2.default.createElement('i', _extends({}, otherLiconAttribute, { className: 'licon icon' + (otherLiconAttribute.className ? ' ' + liconAttribute.className : '') })),
    getInputDOM(),
    otherRiconAttribute && !Object.isEmptyObject(otherRiconAttribute) && _react2.default.createElement('i', _extends({}, otherRiconAttribute, { className: 'ricon icon' + (otherRiconAttribute.className ? ' ' + otherRiconAttribute.className : '') })),
    ricon && ricon,
    _react2.default.createElement('input', _extends({
      value: '+',
      disabled: maxDisabled
    }, minusAttribute, {
      type: 'button',
      className: 'numbox-button numbox-button-plus' + (minusAttribute.className ? ' ' + minusAttribute.className : '')
    }))
  );
});

exports.default = NumBox;
module.exports = exports['default'];