"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));

var _classnames = _interopRequireDefault(require("classnames"));

var _react = _interopRequireWildcard(require("react"));

var _utils = require("../utils");

var _Input = _interopRequireDefault(require("../Input"));

var _Button = _interopRequireDefault(require("../Button"));

var _constants = require("../../constants");

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

// Copyright 1999-2020. Plesk International GmbH. All rights reserved.
const fitToMinMax = (value, min = Number.MIN_SAFE_INTEGER || -(Math.pow(2, 53) - 1), max = Number.MAX_SAFE_INTEGER || Math.pow(2, 53) - 1) => {
  if (max !== undefined && value > max) {
    return max;
  }

  if (min !== undefined && value < min) {
    return min;
  }

  return value;
};

const isLikeNumber = value => {
  if (String(value).trim() === '') {
    return false;
  }

  const number = parseFloat(String(value));
  return typeof number === 'number' && !isNaN(number);
};

const toNumber = value => {
  if (typeof value === 'string') {
    const number = parseFloat(value);

    if (!isLikeNumber(number)) {
      return 0;
    }

    return number;
  }

  return value;
};

const isMinDisabled = (value, min) => min !== undefined && value !== '' && value <= min;

const isMaxDisabled = (value, max) => max !== undefined && value !== '' && value >= max;
/**
 * `InputNumber` component is used for entering integer numbers.
 * @since 2.2.0
 */


const InputNumber = ({
  baseClassName = `${_constants.CLS_PREFIX}input-number`,
  className,
  defaultValue,
  value: propValue,
  disabled,
  onChange,
  min,
  max,
  step = 1,
  decrementIcon = 'minus',
  incrementIcon = 'plus',
  ...props
}) => {
  const inputRef = (0, _react.useRef)(null);
  const isControlled = propValue !== undefined;
  const safeDefaultValue = typeof defaultValue === 'number' ? defaultValue : '';
  const safePropValue = typeof propValue === 'number' ? propValue : '';
  const [value, setValue] = (0, _react.useState)(isControlled ? safePropValue : safeDefaultValue);
  const firedRef = (0, _react.useRef)(Number(isControlled ? safePropValue : safeDefaultValue));
  (0, _react.useLayoutEffect)(() => {
    if (isControlled) {
      setValue(safePropValue);
    }
  }, [isControlled, safePropValue]);

  const fireChange = nextValue => {
    if (firedRef.current !== nextValue) {
      firedRef.current = nextValue;
      (0, _utils.safeInvoke)(onChange, nextValue);
    }
  };

  const createIncDec = diff => () => {
    const nextValue = fitToMinMax(toNumber(value) + diff, min, max);

    if (!isControlled || nextValue === safePropValue) {
      setValue(nextValue);
    }

    fireChange(nextValue);
  };

  const handleInc = createIncDec(+step);
  const handleDec = createIncDec(-step);

  const handleChange = e => {
    const currValue = e.target.value;
    let nextValue = currValue;

    if (String(currValue).trim() === '') {
      nextValue = '';
    }

    setValue(nextValue);
  };

  const handleKeyDown = e => {
    switch (e.key) {
      case 'ArrowUp':
        handleInc();
        break;

      case 'ArrowDown':
        handleDec();
        break;

      case 'Enter':
        handleBlur();
        break;
    }
  };

  const handleBlur = () => {
    let nextValue;

    if (isLikeNumber(value)) {
      nextValue = fitToMinMax(toNumber(value), min, max);
      fireChange(nextValue);
    } else {
      nextValue = '';
    }

    if (isControlled) {
      setValue(safePropValue);
    } else {
      setValue(nextValue);
    }
  };

  const handleMouseDown = e => {
    e.preventDefault();

    if (e.currentTarget.hasAttribute('disabled')) {
      return;
    }

    if (inputRef.current && document.activeElement !== inputRef.current) {
      inputRef.current.focus();
    }
  };

  const minDisabled = disabled || isMinDisabled(value, min);
  const maxDisabled = disabled || isMaxDisabled(value, max);
  return /*#__PURE__*/_react.default.createElement(_Input.default, (0, _extends2.default)({
    textAlign: "center",
    size: "sm"
  }, props, {
    value: value,
    disabled: disabled,
    onChange: handleChange,
    onKeyDown: handleKeyDown,
    onBlur: handleBlur,
    className: (0, _classnames.default)(baseClassName, className),
    innerRef: inputRef,
    prefix: /*#__PURE__*/_react.default.createElement(_Button.default, {
      icon: decrementIcon,
      ghost: true,
      disabled: minDisabled,
      onClick: handleDec,
      onMouseDown: handleMouseDown,
      className: `${baseClassName}__dec`
    }),
    suffix: /*#__PURE__*/_react.default.createElement(_Button.default, {
      icon: incrementIcon,
      ghost: true,
      disabled: maxDisabled,
      onClick: handleInc,
      onMouseDown: handleMouseDown,
      className: `${baseClassName}__inc`
    })
  }));
};

var _default = InputNumber;
exports.default = _default;