// Copyright 1999-2023. Plesk International GmbH. All rights reserved.

import classNames from 'classnames';
import { useState, useRef, useLayoutEffect } from 'react';
import { safeInvoke } from '../utils';
import Input from '../Input';
import Button from '../Button';
import { CLS_PREFIX } from '../../constants';
import { jsx as _jsx } from "react/jsx-runtime";
const fitToMinMax = function (value) {
  let min = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Number.MIN_SAFE_INTEGER || -(Math.pow(2, 53) - 1);
  let max = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 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 = _ref => {
  let {
    baseClassName = `${CLS_PREFIX}input-number`,
    className,
    defaultValue,
    value: propValue,
    disabled,
    onChange,
    min,
    max,
    step = 1,
    decrementIcon = 'minus',
    incrementIcon = 'plus',
    ...props
  } = _ref;
  const inputRef = useRef(null);
  const isControlled = propValue !== undefined;
  const safeDefaultValue = typeof defaultValue === 'number' ? defaultValue : '';
  const safePropValue = typeof propValue === 'number' ? propValue : '';
  const [value, setValue] = useState(isControlled ? safePropValue : safeDefaultValue);
  const firedRef = useRef(Number(isControlled ? safePropValue : safeDefaultValue));
  useLayoutEffect(() => {
    if (isControlled) {
      setValue(safePropValue);
    }
  }, [isControlled, safePropValue]);
  const fireChange = nextValue => {
    if (firedRef.current !== nextValue) {
      firedRef.current = nextValue;
      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__*/_jsx(Input, {
    textAlign: "center",
    size: "sm",
    ...props,
    value: value,
    disabled: disabled,
    onChange: handleChange,
    onKeyDown: handleKeyDown,
    onBlur: handleBlur,
    className: classNames(baseClassName, className),
    innerRef: inputRef,
    prefix: /*#__PURE__*/_jsx(Button, {
      icon: decrementIcon,
      ghost: true,
      disabled: minDisabled,
      onClick: handleDec,
      onMouseDown: handleMouseDown,
      className: `${baseClassName}__dec`
    }),
    suffix: /*#__PURE__*/_jsx(Button, {
      icon: incrementIcon,
      ghost: true,
      disabled: maxDisabled,
      onClick: handleInc,
      onMouseDown: handleMouseDown,
      className: `${baseClassName}__inc`
    })
  });
};
export default InputNumber;