import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
var _excluded = ["inputRef"];
import React, { useEffect, useImperativeHandle, useRef } from 'react';
import { IMaskInput } from '@skbkontur/react-imask';
import { forwardRefAndName } from "../../../lib/forwardRefAndName";
import { isKeyArrow, isKeyArrowHorizontal, isKeyArrowLeft, isKeyArrowUp, isKeyEnd, isKeyHome, isModShift, isShortcutJumpCaret, isShortcutSelectAll, someKeys } from "../../../lib/events/keyboard/identifiers";
import { MouseDrag } from "../../../lib/events/MouseDrag";
export var FixedIMaskInput = forwardRefAndName('FixedIMaskInput', function FixedIMaskInput(props, ref) {
  var inputRef = props.inputRef,
    restProps = _objectWithoutPropertiesLoose(props, _excluded);
  var imaskRef = useRef(null);
  var focused = useRef(false);
  useEffect(function () {
    var _imaskRef$current;
    if ((_imaskRef$current = imaskRef.current) != null && _imaskRef$current.element) {
      fillTypedValue();
      var mouseDrag = MouseDrag.listen(imaskRef.current.element).onMouseDragEnd(function (e) {
        var _imaskRef$current2, _imaskRef$current3;
        var direction = 'none';
        if (mouseDrag.mouseDragStartEvent && ((_imaskRef$current2 = imaskRef.current) == null ? void 0 : _imaskRef$current2.element.selectionStart) !== ((_imaskRef$current3 = imaskRef.current) == null ? void 0 : _imaskRef$current3.element.selectionEnd)) {
          direction = mouseDrag.mouseDragStartEvent.pageX > e.pageX ? 'backward' : 'forward';
        }
        var _getSelection = getSelection(),
          start = _getSelection[0],
          end = _getSelection[1];
        setSelection(start, end, direction);
      });
    }
  }, []);
  useImperativeHandle(ref, function () {
    return imaskRef.current;
  }, []);
  return /*#__PURE__*/(
    React.createElement(IMaskInput, _extends({}, restProps, {
      ref: imaskRef,
      inputRef: inputRef,
      onKeyDown: handleKeyDown,
      onFocus: handleFocus,
      onBlur: handleBlur,
      onMouseUp: handleMouseUp,
      onAccept: handleAccept,
      onInput: handleInput
    }))
  );
  function getTypedValue() {
    var _imaskRef$current4;
    var _ref = ((_imaskRef$current4 = imaskRef.current) == null ? void 0 : _imaskRef$current4.maskRef.masked) || {},
      _ref$_value = _ref._value,
      _value = _ref$_value === void 0 ? '' : _ref$_value,
      _ref$displayValue = _ref.displayValue,
      displayValue = _ref$displayValue === void 0 ? '' : _ref$displayValue;
    var end = getMaxCaretPosition();
    var value = _value !== '' || focused.current === true ? displayValue : '';
    return value.slice(0, end);
  }
  function fillTypedValue() {
    var _imaskRef$current5, _imaskRef$current6, _imaskRef$current7;
    (_imaskRef$current5 = imaskRef.current) == null || _imaskRef$current5.element.setAttribute('data-typed-value', getTypedValue());
    (_imaskRef$current6 = imaskRef.current) == null || _imaskRef$current6.element.setAttribute('data-unmasked-value', (_imaskRef$current7 = imaskRef.current) == null ? void 0 : _imaskRef$current7.maskRef.unmaskedValue);
  }
  function getMaxCaretPosition() {
    var maskChars = [];
    if (imaskRef.current) {
      maskChars.push(imaskRef.current.maskRef.masked.placeholderChar);
      if (imaskRef.current.maskRef.masked.blocks) {
        Object.values(imaskRef.current.maskRef.masked.blocks).forEach(function (_ref2) {
          var placeholderChar = _ref2.placeholderChar;
          return placeholderChar && maskChars.push(placeholderChar);
        });
      }
      return imaskRef.current.element.value.split(new RegExp(maskChars.join('|')))[0].length;
    }
    return Infinity;
  }
  function normalizeSelection() {
    var _getSelection2 = getSelection(),
      start = _getSelection2[0],
      end = _getSelection2[1];
    var max = getMaxCaretPosition();
    if (end > max) {
      setSelection(start, max);
    }
  }
  function getNormalizedRange(calc) {
    return typeof calc === 'number' ? Math.min(getMaxCaretPosition(), Math.max(0, calc)) : 0;
  }
  function getSelection() {
    if (imaskRef.current) {
      return [imaskRef.current.element.selectionStart || 0, imaskRef.current.element.selectionEnd || 0, imaskRef.current.element.selectionDirection || 'none'];
    }
    return [0, 0, 'none'];
  }
  function setSelection() {
    var _imaskRef$current8;
    for (var _len = arguments.length, _ref3 = new Array(_len), _key = 0; _key < _len; _key++) {
      _ref3[_key] = arguments[_key];
    }
    var start = _ref3[0],
      end = _ref3[1],
      direction = _ref3[2];
    (_imaskRef$current8 = imaskRef.current) == null || _imaskRef$current8.element.setSelectionRange(getNormalizedRange(start), getNormalizedRange(end), direction || 'none');
  }
  function jumpCaret(prev, headDirection) {
    var _imaskRef$current9;
    var word = /а-яa-z0-9_/.valueOf();
    var wordRegExp = new RegExp("([" + word + "])+[\\s]*|([^" + word + "])+", 'gi');
    var next = headDirection === 'right' ? prev : 0;
    (_imaskRef$current9 = imaskRef.current) == null || (_imaskRef$current9 = _imaskRef$current9.element.value.match(wordRegExp)) == null || _imaskRef$current9.reduce(function (s, a) {
      var pos = a.length + (s.slice(-1)[0] || 0);
      if (headDirection === 'right' && next === prev && next < pos) {
        next = getNormalizedRange(pos);
      } else if (headDirection === 'left' && prev > pos) {
        next = getNormalizedRange(pos);
      }
      return [].concat(s, [pos]);
    }, []);
    return next;
  }

  /**
   * Вычислят положение каретки при управлении клавишами
   * @param e
   */
  function calcSelection(e) {
    var _getSelection3 = getSelection(),
      start = _getSelection3[0],
      end = _getSelection3[1],
      direction = _getSelection3[2];
    var isSelectionMode = isModShift()(e);
    var tail = start !== end && direction === 'backward' ? end : start;
    var head = start !== end && direction === 'backward' ? start : end;
    var headDirection = someKeys(isKeyArrowLeft, isKeyArrowUp, isKeyHome)(e) ? 'left' : 'right';
    var step = isKeyArrowHorizontal(e) ? 1 : Infinity;
    var increment = headDirection === 'left' ? -step : step;
    if (isShortcutJumpCaret(e)) {
      head = jumpCaret(head, headDirection);
    } else if (head !== tail && !isSelectionMode && isKeyArrowHorizontal(e)) {
      head = headDirection === 'right' ? Math.max(tail, head) : Math.min(tail, head);
    } else {
      head = head + increment;
    }
    if (isSelectionMode) {
      var _start = Math.min(tail, head);
      var _end = Math.max(tail, head);
      return [getNormalizedRange(_start), getNormalizedRange(_end), _end === head ? 'forward' : 'backward'];
    }
    tail = head;
    return [getNormalizedRange(tail), getNormalizedRange(head), 'none'];
  }
  function handleMouseUp(e) {
    normalizeSelection();
    props.onMouseUp == null || props.onMouseUp(e);
  }
  function handleFocus(e) {
    focused.current = true;
    fillTypedValue();
    setTimeout(normalizeSelection);
    props.onFocus == null || props.onFocus(e);
  }
  function handleBlur(e) {
    focused.current = false;
    fillTypedValue();
    props.onBlur == null || props.onBlur(e);
  }
  function handleAccept() {
    fillTypedValue();
    for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
      args[_key2] = arguments[_key2];
    }
    props.onAccept == null || props.onAccept.apply(props, args);
  }
  function handleInput(e) {
    var _imaskRef$current10;
    var maskRef = (_imaskRef$current10 = imaskRef.current) == null ? void 0 : _imaskRef$current10.maskRef;
    if (maskRef && maskRef.rawInputValue === '') {
      // в случае, когда пользователь стер все из инпута, очищаем value полностью
      // иначе в value остаются символы маски
      props.onAccept == null || props.onAccept('', maskRef, e.nativeEvent);
    }
    props.onInput == null || props.onInput(e);
  }
  function handleKeyDown(e) {
    var nearest = getMaxCaretPosition();
    if (isShortcutSelectAll(e)) {
      e.preventDefault();
      setSelection(0, nearest);
    } else if (isKeyArrow(e) || isKeyEnd(e) || isKeyHome(e)) {
      e.preventDefault();
      var _calcSelection = calcSelection(e),
        start = _calcSelection[0],
        end = _calcSelection[1],
        direction = _calcSelection[2];
      setSelection(start, end, direction);
    }
    props.onKeyDown == null || props.onKeyDown(e);
  }
});