import _extends from "@babel/runtime/helpers/esm/extends";
import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose";
var _dec, _class, _DateInput;
import React from 'react';
import ReactDOM from 'react-dom';
import { globalObject } from '@skbkontur/global-object';
import { getFullReactUIFlagsContext, ReactUIFeatureFlagsContext } from "../../../lib/featureFlagsContext";
import { ConditionalHandler } from "../../../lib/ConditionalHandler";
import { LENGTH_FULLDATE, MAX_FULLDATE, MIN_FULLDATE } from "../../../lib/date/constants";
import { InternalDateComponentType } from "../../../lib/date/types";
import { DatePickerLocaleHelper } from "../../DatePicker/locale";
import { InputLikeText } from "../../../internal/InputLikeText";
import { locale } from "../../../lib/locale/decorators";
import { ThemeContext } from "../../../lib/theming/ThemeContext";
import { CommonWrapper } from "../../../internal/CommonWrapper";
import { cx } from "../../../lib/theming/Emotion";
import { rootNode } from "../../../lib/rootNode";
import { createPropsGetter } from "../../../lib/createPropsGetter";
import { FocusControlWrapper } from "../../../internal/FocusControlWrapper";
import { withSize } from "../../../lib/size/SizeDecorator";
import { CalendarIcon } from "../CalendarIcon";
import { DateFragmentsView } from "../DateFragmentsView";
import { styles } from "../DateInput.styles";
import { Actions, extractAction } from "../helpers/DateInputKeyboardActions";
import { InternalDateMediator } from "../helpers/InternalDateMediator";
export var DateInputDataTids = {
  root: 'DateInput__root',
  icon: 'DateInput__icon'
};

/**
 * Компонент поля `DateInput` из DatePicker'а помогает выбирать дату с клавиатуры.
 */
export var DateInput = (_dec = locale('DatePicker', DatePickerLocaleHelper), rootNode(_class = _dec(_class = withSize(_class = (_DateInput = /*#__PURE__*/function (_React$Component) {
  function DateInput(props) {
    var _this;
    _this = _React$Component.call(this, props) || this;
    _this.getProps = createPropsGetter(DateInput.defaultProps);
    _this.iDateMediator = new InternalDateMediator();
    _this.inputLikeText = null;
    _this.dateFragmentsView = null;
    _this.isMouseDown = false;
    _this.isMouseFocus = false;
    _this.ignoringDelimiter = false;
    _this.blurEvent = null;
    _this.conditionalHandler = new ConditionalHandler().add(Actions.MoveSelectionLeft, function () {
      return _this.shiftSelection(-1);
    }).add(Actions.MoveSelectionRight, function () {
      return _this.shiftSelection(1);
    }).add(Actions.Separator, function () {
      return _this.pressDelimiter();
    }).add(Actions.MoveSelectionFirst, function () {
      return _this.selectDateComponent(_this.iDateMediator.getLeftmostType());
    }).add(Actions.MoveSelectionLast, function () {
      return _this.selectDateComponent(_this.iDateMediator.getRightmostType());
    }).add(Actions.Increment, function () {
      return _this.shiftDateComponent(1);
    }).add(Actions.Decrement, function () {
      return _this.shiftDateComponent(-1);
    }).add(Actions.Digit, function (e) {
      return _this.inputValue(e);
    }).add(Actions.ClearSelection, function () {
      return _this.clearSelected();
    }).add(Actions.ClearOneChar, function () {
      return _this.clearOneChar();
    }).add(Actions.FullSelection, function () {
      return _this.fullSelection();
    }).add(Actions.WrongInput, function () {
      return _this.blink();
    }).build();
    _this.selectNode = function () {
      var type = _this.state.selected;
      var dateFragmentsView = _this.dateFragmentsView && _this.dateFragmentsView.getRootNode();
      if (type === null || !_this.inputLikeText || !dateFragmentsView) {
        return;
      }
      if (type === InternalDateComponentType.All) {
        _this.inputLikeText.selectInnerNode(dateFragmentsView, 0, 5);
        return;
      }
      var index = _this.iDateMediator.getTypesOrder().indexOf(type);
      if (index > -1) {
        _this.inputLikeText.selectInnerNode(dateFragmentsView, index * 2, index * 2 + 1);
      }
    };
    _this.renderIcon = function () {
      var _this$props = _this.props,
        withIcon = _this$props.withIcon,
        _this$props$disabled = _this$props.disabled,
        disabled = _this$props$disabled === void 0 ? false : _this$props$disabled;
      var size = _this.size;
      if (withIcon) {
        var _cx;
        var theme = _this.theme;
        var icon = /*#__PURE__*/React.createElement(CalendarIcon, {
          size: size
        });
        var iconStyles = cx((_cx = {}, _cx[styles.icon(theme)] = true, _cx[styles.iconSmall(theme)] = size === 'small', _cx[styles.iconMedium(theme)] = size === 'medium', _cx[styles.iconLarge(theme)] = size === 'large', _cx[styles.iconDisabled(theme)] = disabled, _cx));
        return /*#__PURE__*/(
          React.createElement("span", {
            className: iconStyles,
            "data-tid": DateInputDataTids.icon
          }, icon)
        );
      }
      return null;
    };
    _this.handleFocus = function (e) {
      _this.setState(function (prevState) {
        return {
          focused: true,
          selected: _this.isMouseDown && !prevState.focused ? prevState.selected : _this.iDateMediator.getLeftmostType()
        };
      });
      if (_this.props.onFocus) {
        _this.props.onFocus(e);
      }
    };
    _this.resetFocus = function () {
      return _this.updateValue({
        focused: false,
        selected: null,
        inputMode: false
      }, false);
    };
    _this.handleBlur = function (e) {
      _this.resetFocus();
      if (_this.props.onBlur) {
        var restored = _this.iDateMediator.restore();
        if (restored) {
          e.persist();
          _this.blurEvent = e;
        } else {
          _this.props.onBlur(e);
        }
      }
    };
    _this.handleMouseDownCapture = function (e) {
      var isFragment = _this.dateFragmentsView ? _this.dateFragmentsView.isFragment(e.target) : false;
      if (_this.state.focused && !isFragment) {
        e.preventDefault();
      }
      _this.isMouseFocus = !_this.state.focused;
      _this.isMouseDown = isFragment;
    };
    _this.handleSelectDateComponent = function (type) {
      if (!(_this.isMouseFocus && _this.iDateMediator.isEmpty())) {
        _this.selectDateComponent(type);
      }
      _this.isMouseFocus = false;
      _this.isMouseDown = false;
    };
    _this.handleMouseDragStart = function () {
      _this.setState({
        dragged: true,
        selected: null
      });
    };
    _this.handleMouseDragEnd = function () {
      var selection = globalObject.getSelection == null ? void 0 : globalObject.getSelection();
      if (selection && selection.toString().length === LENGTH_FULLDATE && _this.state.selected !== InternalDateComponentType.All) {
        _this.selectDateComponent(InternalDateComponentType.All);
      }
    };
    _this.handleKeyDown = function (e) {
      if (_this.conditionalHandler(extractAction(e), e)) {
        e.preventDefault();
      }
      if (_this.props.onKeyDown) {
        _this.props.onKeyDown(e);
      }
    };
    _this.handlePaste = function (e) {
      var pasted = e && e.clipboardData.getData('text').trim();
      if (pasted && _this.iDateMediator.validateString(pasted)) {
        _this.iDateMediator.paste(pasted);
        _this.updateValue();
      }
    };
    _this.handleDoubleClick = function () {
      _this.selectDateComponent(InternalDateComponentType.All);
    };
    _this.inputLikeTextRef = function (el) {
      _this.inputLikeText = el;
    };
    _this.dateFragmentsViewRef = function (el) {
      _this.dateFragmentsView = el;
    };
    _this.selectDateComponent = function (selected) {
      _this.setState({
        selected: selected,
        inputMode: false
      });
    };
    _this.updateValue = function (state, sync) {
      if (state === void 0) {
        state = {};
      }
      if (sync === void 0) {
        sync = true;
      }
      var valueFormatted = _this.iDateMediator.getString();
      var update = function update() {
        return _this.setState(_extends({}, state, {
          valueFormatted: valueFormatted
        }), _this.emitChange);
      };
      if (sync && React.version.search('18') === 0) {
        ReactDOM.flushSync(update);
      } else {
        update();
      }
    };
    _this.updateFromProps = function (sync) {
      _this.iDateMediator.update(_this.props, _this.locale);
      _this.updateValue({}, sync);
    };
    _this.fullSelection = function () {
      _this.selectDateComponent(InternalDateComponentType.All);
    };
    _this.pressDelimiter = function () {
      var value = _this.iDateMediator.get(_this.state.selected);
      if (value !== null && value !== '') {
        if (!_this.ignoringDelimiter) {
          _this.shiftSelection(1);
        }
        _this.ignoringDelimiter = false;
      }
    };
    _this.emitChange = function () {
      if (_this.props.onValueChange) {
        var value = _this.iDateMediator.getInternalString();
        if (_this.props.value !== value) {
          _this.props.onValueChange(value);
        }
      }

      // `this.blurEvent` is always null in `flushSync` without `setTimeout` due to sync update
      setTimeout(function () {
        if (_this.blurEvent && _this.props.onBlur) {
          _this.props.onBlur(_this.blurEvent);
          _this.blurEvent = null;
        }
      });
    };
    _this.clearSelected = function () {
      var selected = _this.state.selected === null ? _this.iDateMediator.getLeftmostType() : _this.state.selected;
      _this.iDateMediator.clear(selected);
      _this.updateValue({
        inputMode: false,
        selected: selected === InternalDateComponentType.All ? _this.iDateMediator.getLeftmostType() : selected
      });
    };
    _this.clearOneChar = function () {
      var _this$state = _this.state,
        selected = _this$state.selected,
        inputMode = _this$state.inputMode;
      var nextType = selected === null ? _this.iDateMediator.getRightmostType() : selected;
      if (_this.iDateMediator.isNull(nextType)) {
        _this.shiftSelection(-1);
        return;
      }
      if (selected === InternalDateComponentType.All) {
        _this.iDateMediator.clear(InternalDateComponentType.All);
        _this.updateValue({
          selected: _this.iDateMediator.getLeftmostType()
        });
        return;
      }
      _this.iDateMediator.deleteOneCharRight(nextType, inputMode);
      _this.updateValue({
        inputMode: _this.iDateMediator.get(nextType) !== null,
        selected: nextType
      });
    };
    _this.shiftDateComponent = function (step) {
      var selected = _this.state.selected;
      var changed = _this.iDateMediator.shiftDateComponent(selected, step);
      if (!changed) {
        _this.blink();
        return;
      }
      _this.updateValue({
        inputMode: false,
        selected: selected === InternalDateComponentType.All ? _this.iDateMediator.getLeftmostType() : selected
      });
    };
    _this.shiftSelection = function (step) {
      var selected = _this.iDateMediator.getShiftedType(_this.state.selected, step);
      if (selected !== _this.state.selected) {
        _this.setState({
          selected: selected,
          inputMode: false
        });
      }
    };
    _this.inputValue = function (event) {
      var selected = _this.state.selected;
      if (selected === InternalDateComponentType.All) {
        selected = _this.iDateMediator.getLeftmostType();
        _this.iDateMediator.clear(InternalDateComponentType.All);
        _this.setState({
          selected: selected
        });
      }
      var _this$iDateMediator$i = _this.iDateMediator.inputKey(event.key, selected, _this.state.inputMode, _this.featureFlags.dateInputAllowInvalidValuesInDays),
        inputMode = _this$iDateMediator$i.inputMode,
        changed = _this$iDateMediator$i.changed;
      if (!_this.featureFlags.dateInputFixSameNumberTypingOnRefocus) {
        if (!changed) {
          _this.blink();
          return;
        }
      }
      if (!inputMode) {
        _this.ignoringDelimiter = true;
        _this.shiftSelection(1);
      }
      _this.updateValue({
        inputMode: inputMode
      });
    };
    _this.state = {
      valueFormatted: '',
      selected: null,
      inputMode: false,
      focused: false,
      dragged: false
    };
    return _this;
  }
  _inheritsLoose(DateInput, _React$Component);
  var _proto = DateInput.prototype;
  _proto.componentDidUpdate = function componentDidUpdate(prevProps) {
    var _this$getProps = this.getProps(),
      value = _this$getProps.value,
      minDate = _this$getProps.minDate,
      maxDate = _this$getProps.maxDate;
    if (prevProps.value !== value || prevProps.minDate !== minDate || prevProps.maxDate !== maxDate || this.iDateMediator.isChangedLocale(this.locale)) {
      this.updateFromProps(false);
    }
    !this.props.disabled && this.selectNode();
  };
  _proto.componentDidMount = function componentDidMount() {
    this.updateFromProps(false);
    if (this.props.autoFocus) {
      this.focus();
    }
  };
  _proto.blur = function blur() {
    if (this.inputLikeText) {
      this.inputLikeText.blur();
    }
  };
  _proto.focus = function focus() {
    if (this.inputLikeText) {
      this.inputLikeText.focus();
    }
  };
  _proto.blink = function blink() {
    if (this.inputLikeText) {
      this.inputLikeText.blink();
    }
  };
  _proto.render = function render() {
    var _this2 = this;
    return /*#__PURE__*/React.createElement(ReactUIFeatureFlagsContext.Consumer, null, function (flags) {
      _this2.featureFlags = getFullReactUIFlagsContext(flags);
      return /*#__PURE__*/React.createElement(ThemeContext.Consumer, null, function (theme) {
        _this2.theme = theme;
        return _this2.renderMain();
      });
    });
  };
  _proto.renderMain = function renderMain() {
    var _cx2;
    var _this$state2 = this.state,
      focused = _this$state2.focused,
      selected = _this$state2.selected,
      inputMode = _this$state2.inputMode,
      valueFormatted = _this$state2.valueFormatted;
    var showValue = Boolean(focused || valueFormatted);
    var _this$getProps2 = this.getProps(),
      width = _this$getProps2.width;
    return /*#__PURE__*/React.createElement(CommonWrapper, _extends({
      rootNodeRef: this.setRootNode
    }, this.props), /*#__PURE__*/React.createElement(FocusControlWrapper, {
      onBlurWhenDisabled: this.resetFocus
    }, /*#__PURE__*/React.createElement(InputLikeText, {
      "data-tid": DateInputDataTids.root,
      id: this.props.id,
      width: width,
      ref: this.inputLikeTextRef,
      size: this.size,
      disabled: this.props.disabled,
      error: this.props.error,
      warning: this.props.warning,
      onBlur: this.handleBlur,
      onFocus: this.handleFocus,
      onClick: this.props.onClick,
      onKeyDown: this.handleKeyDown,
      onMouseDownCapture: this.handleMouseDownCapture,
      onPaste: this.handlePaste,
      rightIcon: this.renderIcon(),
      onDoubleClickCapture: this.handleDoubleClick,
      onMouseDragStart: this.handleMouseDragStart,
      onMouseDragEnd: this.handleMouseDragEnd,
      value: this.iDateMediator.getInternalString(),
      inputMode: 'numeric',
      takeContentWidth: true,
      "aria-describedby": this.props['aria-describedby'],
      "aria-label": this.props['aria-label'],
      "aria-labelledby": this.props['aria-labelledby']
    }, /*#__PURE__*/React.createElement("span", {
      className: cx(styles.value(), (_cx2 = {}, _cx2[styles.valueVisible()] = showValue, _cx2))
    }, /*#__PURE__*/React.createElement(DateFragmentsView, {
      ref: this.dateFragmentsViewRef,
      fragments: this.iDateMediator.getFragments(),
      onSelectDateComponent: this.handleSelectDateComponent,
      selected: selected,
      inputMode: inputMode
    })))));
  };
  return DateInput;
}(React.Component), _DateInput.__KONTUR_REACT_UI__ = 'DateInput', _DateInput.displayName = 'DateInput', _DateInput.defaultProps = {
  value: '',
  minDate: MIN_FULLDATE,
  maxDate: MAX_FULLDATE,
  width: 125
}, _DateInput)) || _class) || _class) || _class);