import _extends from "@babel/runtime/helpers/esm/extends";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
var _excluded = ["allowDecimals", "allowNegativeValue", "id", "name", "className", "customInput", "decimalsLimit", "defaultValue", "disabled", "maxLength", "value", "onValueChange", "fixedDecimalLength", "placeholder", "decimalScale", "prefix", "suffix", "intlConfig", "step", "min", "max", "disableGroupSeparators", "disableAbbreviations", "decimalSeparator", "groupSeparator", "onChange", "onFocus", "onBlur", "onKeyDown", "onKeyUp", "transformRawValue", "formatValueOnBlur", "children"];
import React, { useState, useEffect, useRef, forwardRef, useMemo, useImperativeHandle } from 'react';
import { isNumber, cleanValue, fixedDecimalValue, formatValue, getLocaleConfig, padTrimValue, getSuffix, repositionCursor } from './utils';
import { useTheme } from '@helpdice/theme';
export var InputCurrency = /*#__PURE__*/forwardRef(function (_ref, ref) {
  var _ref$allowDecimals = _ref.allowDecimals,
    allowDecimals = _ref$allowDecimals === void 0 ? true : _ref$allowDecimals,
    _ref$allowNegativeVal = _ref.allowNegativeValue,
    allowNegativeValue = _ref$allowNegativeVal === void 0 ? true : _ref$allowNegativeVal,
    id = _ref.id,
    name = _ref.name,
    className = _ref.className,
    customInput = _ref.customInput,
    decimalsLimit = _ref.decimalsLimit,
    defaultValue = _ref.defaultValue,
    _ref$disabled = _ref.disabled,
    disabled = _ref$disabled === void 0 ? false : _ref$disabled,
    userMaxLength = _ref.maxLength,
    userValue = _ref.value,
    onValueChange = _ref.onValueChange,
    fixedDecimalLength = _ref.fixedDecimalLength,
    placeholder = _ref.placeholder,
    decimalScale = _ref.decimalScale,
    prefix = _ref.prefix,
    suffix = _ref.suffix,
    intlConfig = _ref.intlConfig,
    step = _ref.step,
    min = _ref.min,
    max = _ref.max,
    _ref$disableGroupSepa = _ref.disableGroupSeparators,
    disableGroupSeparators = _ref$disableGroupSepa === void 0 ? false : _ref$disableGroupSepa,
    _ref$disableAbbreviat = _ref.disableAbbreviations,
    disableAbbreviations = _ref$disableAbbreviat === void 0 ? false : _ref$disableAbbreviat,
    _decimalSeparator = _ref.decimalSeparator,
    _groupSeparator = _ref.groupSeparator,
    onChange = _ref.onChange,
    onFocus = _ref.onFocus,
    onBlur = _ref.onBlur,
    onKeyDown = _ref.onKeyDown,
    onKeyUp = _ref.onKeyUp,
    transformRawValue = _ref.transformRawValue,
    _ref$formatValueOnBlu = _ref.formatValueOnBlur,
    formatValueOnBlur = _ref$formatValueOnBlu === void 0 ? true : _ref$formatValueOnBlu,
    children = _ref.children,
    props = _objectWithoutProperties(_ref, _excluded);
  var theme = useTheme();
  if (_decimalSeparator && isNumber(_decimalSeparator)) {
    throw new Error('decimalSeparator cannot be a number');
  }
  if (_groupSeparator && isNumber(_groupSeparator)) {
    throw new Error('groupSeparator cannot be a number');
  }
  var localeConfig = useMemo(function () {
    return getLocaleConfig(intlConfig);
  }, [intlConfig]);
  var decimalSeparator = _decimalSeparator || localeConfig.decimalSeparator || '';
  var groupSeparator = _groupSeparator || localeConfig.groupSeparator || '';
  if (decimalSeparator && groupSeparator && decimalSeparator === groupSeparator && disableGroupSeparators === false) {
    throw new Error('decimalSeparator cannot be the same as groupSeparator');
  }
  var formatValueOptions = {
    decimalSeparator: decimalSeparator,
    groupSeparator: groupSeparator,
    disableGroupSeparators: disableGroupSeparators,
    intlConfig: intlConfig,
    prefix: prefix || localeConfig.prefix,
    suffix: suffix
  };
  var cleanValueOptions = {
    decimalSeparator: decimalSeparator,
    groupSeparator: groupSeparator,
    allowDecimals: allowDecimals,
    decimalsLimit: decimalsLimit || fixedDecimalLength || 2,
    allowNegativeValue: allowNegativeValue,
    disableAbbreviations: disableAbbreviations,
    prefix: prefix || localeConfig.prefix,
    transformRawValue: transformRawValue
  };
  var _useState = useState(function () {
      return defaultValue != null ? formatValue(_extends({}, formatValueOptions, {
        decimalScale: decimalScale,
        value: String(defaultValue)
      })) : userValue != null ? formatValue(_extends({}, formatValueOptions, {
        decimalScale: decimalScale,
        value: String(userValue)
      })) : '';
    }),
    _useState2 = _slicedToArray(_useState, 2),
    stateValue = _useState2[0],
    setStateValue = _useState2[1];
  var _useState3 = useState(false),
    _useState4 = _slicedToArray(_useState3, 2),
    dirty = _useState4[0],
    setDirty = _useState4[1];
  var _useState5 = useState(0),
    _useState6 = _slicedToArray(_useState5, 2),
    cursor = _useState6[0],
    setCursor = _useState6[1];
  var _useState7 = useState(0),
    _useState8 = _slicedToArray(_useState7, 2),
    changeCount = _useState8[0],
    setChangeCount = _useState8[1];
  var _useState9 = useState(null),
    _useState10 = _slicedToArray(_useState9, 2),
    lastKeyStroke = _useState10[0],
    setLastKeyStroke = _useState10[1];
  var inputRef = useRef(null);
  useImperativeHandle(ref, function () {
    return inputRef.current;
  });

  /**
   * Process change in value
   */
  var processChange = function processChange(value, selectionStart) {
    setDirty(true);
    var _repositionCursor = repositionCursor({
        selectionStart: selectionStart,
        value: value,
        lastKeyStroke: lastKeyStroke,
        stateValue: stateValue,
        groupSeparator: groupSeparator
      }),
      modifiedValue = _repositionCursor.modifiedValue,
      cursorPosition = _repositionCursor.cursorPosition;
    var stringValue = cleanValue(_extends({
      value: modifiedValue
    }, cleanValueOptions));
    if (userMaxLength && stringValue.replace(/-/g, '').length > userMaxLength) {
      return;
    }
    if (stringValue === '' || stringValue === '-' || stringValue === decimalSeparator) {
      onValueChange && onValueChange(undefined, name, {
        "float": null,
        formatted: '',
        value: ''
      });
      setStateValue(stringValue);
      // Always sets cursor after '-' or decimalSeparator input
      setCursor(1);
      return;
    }
    var stringValueWithoutSeparator = decimalSeparator ? stringValue.replace(decimalSeparator, '.') : stringValue;
    var numberValue = parseFloat(stringValueWithoutSeparator);
    var formattedValue = formatValue(_extends({
      value: stringValue
    }, formatValueOptions));
    if (cursorPosition != null) {
      // Prevent cursor jumping
      var newCursor = cursorPosition + (formattedValue.length - value.length);
      newCursor = newCursor <= 0 ? prefix ? prefix.length : 0 : newCursor;
      setCursor(newCursor);
      setChangeCount(changeCount + 1);
    }
    setStateValue(formattedValue);
    if (onValueChange) {
      var values = {
        "float": numberValue,
        formatted: formattedValue,
        value: stringValue
      };
      onValueChange(stringValue, name, values);
    }
  };

  /**
   * Handle change event
   */
  var handleOnChange = function handleOnChange(event) {
    var _event$target = event.target,
      value = _event$target.value,
      selectionStart = _event$target.selectionStart;
    processChange(value, selectionStart);
    onChange && onChange(event);
  };

  /**
   * Handle focus event
   */
  var handleOnFocus = function handleOnFocus(event) {
    onFocus && onFocus(event);
    return stateValue ? stateValue.length : 0;
  };

  /**
   * Handle blur event
   *
   * Format value by padding/trimming decimals if required by
   */
  var handleOnBlur = function handleOnBlur(event) {
    var value = event.target.value;
    var valueOnly = cleanValue(_extends({
      value: value
    }, cleanValueOptions));
    if (valueOnly === '-' || valueOnly === decimalSeparator || !valueOnly) {
      setStateValue('');
      onBlur && onBlur(event);
      return;
    }
    var fixedDecimals = fixedDecimalValue(valueOnly, decimalSeparator, fixedDecimalLength);
    var newValue = padTrimValue(fixedDecimals, decimalSeparator, decimalScale !== undefined ? decimalScale : fixedDecimalLength);
    var numberValue = parseFloat(newValue.replace(decimalSeparator, '.'));
    var formattedValue = formatValue(_extends({}, formatValueOptions, {
      value: newValue
    }));
    if (onValueChange && formatValueOnBlur) {
      onValueChange(newValue, name, {
        "float": numberValue,
        formatted: formattedValue,
        value: newValue
      });
    }
    setStateValue(formattedValue);
    onBlur && onBlur(event);
  };

  /**
   * Handle key down event
   *
   * Increase or decrease value by step
   */
  var handleOnKeyDown = function handleOnKeyDown(event) {
    var key = event.key;
    setLastKeyStroke(key);
    if (step && (key === 'ArrowUp' || key === 'ArrowDown')) {
      event.preventDefault();
      setCursor(stateValue.length);
      var currentValue = parseFloat(userValue != null ? String(userValue).replace(decimalSeparator, '.') : cleanValue(_extends({
        value: stateValue
      }, cleanValueOptions))) || 0;
      var newValue = key === 'ArrowUp' ? currentValue + step : currentValue - step;
      if (min !== undefined && newValue < Number(min)) {
        return;
      }
      if (max !== undefined && newValue > Number(max)) {
        return;
      }
      var fixedLength = String(step).includes('.') ? Number(String(step).split('.')[1].length) : undefined;
      processChange(String(fixedLength ? newValue.toFixed(fixedLength) : newValue).replace('.', decimalSeparator));
    }
    onKeyDown && onKeyDown(event);
  };

  /**
   * Handle key up event
   *
   * Move cursor if there is a suffix to prevent user typing past suffix
   */
  var handleOnKeyUp = function handleOnKeyUp(event) {
    var key = event.key,
      selectionStart = event.currentTarget.selectionStart;
    if (key !== 'ArrowUp' && key !== 'ArrowDown' && stateValue !== '-') {
      var _suffix = getSuffix(stateValue, {
        groupSeparator: groupSeparator,
        decimalSeparator: decimalSeparator
      });
      if (_suffix && selectionStart && selectionStart > stateValue.length - _suffix.length) {
        /* istanbul ignore else */
        if (inputRef.current) {
          var newCursor = stateValue.length - _suffix.length;
          inputRef.current.setSelectionRange(newCursor, newCursor);
        }
      }
    }
    onKeyUp && onKeyUp(event);
  };

  // Update state if userValue changes to undefined
  useEffect(function () {
    if (userValue == null && defaultValue == null) {
      setStateValue('');
    }
  }, [defaultValue, userValue]);
  useEffect(function () {
    // prevent cursor jumping if editing value
    if (dirty && stateValue !== '-' && inputRef.current && document.activeElement === inputRef.current) {
      inputRef.current.setSelectionRange(cursor, cursor);
    }
  }, [stateValue, cursor, inputRef, dirty, changeCount]);

  /**
   * If user has only entered "-" or decimal separator,
   * keep the char to allow them to enter next value
   */
  var getRenderValue = function getRenderValue() {
    if (userValue != null && stateValue !== '-' && (!decimalSeparator || stateValue !== decimalSeparator)) {
      return formatValue(_extends({}, formatValueOptions, {
        decimalScale: dirty ? undefined : decimalScale,
        value: String(userValue)
      }));
    }
    return stateValue;
  };
  var inputProps = _extends({
    type: 'text',
    inputMode: 'decimal',
    id: id,
    name: name,
    className: className,
    onChange: handleOnChange,
    onBlur: handleOnBlur,
    onFocus: handleOnFocus,
    onKeyDown: handleOnKeyDown,
    onKeyUp: handleOnKeyUp,
    placeholder: placeholder,
    disabled: disabled,
    value: getRenderValue(),
    ref: inputRef
  }, props);
  if (customInput) {
    var CustomInput = customInput;
    return /*#__PURE__*/React.createElement(CustomInput, inputProps);
  }
  return /*#__PURE__*/React.createElement("div", null, children && /*#__PURE__*/React.createElement("label", {
    style: {
      display: 'block',
      marginBottom: '0.7rem',
      fontSize: '14px',
      fontWeight: 'light'
    }
  }, children), /*#__PURE__*/React.createElement("input", _extends({}, inputProps, {
    style: {
      textAlign: 'right',
      border: "1px solid ".concat(theme.palette.border),
      fontSize: '14px',
      borderRadius: '5px',
      height: '35px',
      padding: '5px 10px',
      fontWeight: 'light',
      width: 'auto',
      background: 'transparent',
      minWidth: '200px'
    }
  })));
});

// CurrencyInput.displayName = 'CurrencyInput';

export default InputCurrency;