import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose";
var _excluded = ["innerRef", "tabIndex", "placeholder", "align", "borderless", "width", "error", "warning", "onValueChange", "disabled", "prefix", "suffix", "leftIcon", "rightIcon", "value", "onMouseDragStart", "onMouseDragEnd", "takeContentWidth", "aria-describedby", "aria-label", "aria-labelledby", "showClearIcon", "onClearCrossClick"];
var _class, _InputLikeText;
import React from 'react';
import ReactDOM from 'react-dom';
import debounce from 'lodash.debounce';
import { globalObject } from '@skbkontur/global-object';
import { isNonNullable } from "../../../lib/utils";
import { isKeyTab, isShortcutPaste } from "../../../lib/events/keyboard/identifiers";
import { MouseDrag } from "../../../lib/events/MouseDrag";
import { isEdge, isIE11, isMobile } from "../../../lib/client";
import { removeAllSelections, selectNodeContents } from "../../../lib/dom/selectionHelpers";
import { calculateClearCrossShowedState, InputDataTids } from "../../../components/Input";
import { styles as jsInputStyles } from "../../../components/Input/Input.styles";
import { ThemeContext } from "../../../lib/theming/ThemeContext";
import { CommonWrapper } from "../../CommonWrapper";
import { cx } from "../../../lib/theming/Emotion";
import { findRenderContainer } from "../../../lib/listenFocusOutside";
import { rootNode } from "../../../lib/rootNode";
import { createPropsGetter } from "../../../lib/createPropsGetter";
import { InputLayoutAside } from "../../../components/Input/InputLayout/InputLayoutAside";
import { InputLayoutContext, InputLayoutContextDefault } from "../../../components/Input/InputLayout/InputLayoutContext";
import { isInstanceOf } from "../../../lib/isInstanceOf";
import { FocusControlWrapper } from "../../FocusControlWrapper";
import { ClearCrossIcon } from "../../ClearCrossIcon/ClearCrossIcon";
import { blink as _blink } from "../../../lib/blink";
import { withSize } from "../../../lib/size/SizeDecorator";
import { HiddenInput } from "../HiddenInput";
import { styles } from "../InputLikeText.styles";
export var InputLikeTextDataTids = {
  root: 'InputLikeText__root',
  input: 'InputLikeText__input',
  nativeInput: 'InputLikeText__nativeInput'
};
export var InputLikeText = withSize(_class = rootNode(_class = (_InputLikeText = /*#__PURE__*/function (_React$Component) {
  function InputLikeText() {
    var _this;
    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }
    _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;
    _this.getProps = createPropsGetter(InputLikeText.defaultProps);
    _this.getClearCrossShowed = function (_ref) {
      var focused = _ref.focused,
        hovered = _ref.hovered;
      if (_this.props.disabled) {
        return false;
      }
      return calculateClearCrossShowedState({
        showClearIcon: _this.getProps().showClearIcon,
        notEmptyValue: Boolean(_this.props.children),
        focused: focused,
        hovered: hovered
      });
    };
    _this.state = {
      focused: false,
      clearCrossShowed: _this.getClearCrossShowed({
        focused: false
      })
    };
    _this.node = null;
    _this.hiddenInput = null;
    _this.lastSelectedInnerNode = null;
    _this.frozen = false;
    _this.frozenBlur = false;
    _this.dragging = false;

    // Async call required for Firefox
    _this.selectNodeContentsDebounced = debounce(selectNodeContents, 0);
    _this.selectInnerNode = function (node, start, end) {
      if (start === void 0) {
        start = 0;
      }
      if (end === void 0) {
        end = 1;
      }
      if (_this.dragging || !node) {
        return;
      }
      if (isIE11 && globalObject.document && findRenderContainer(node, globalObject.document.body)) {
        // Code below causes Popup to close after triggering the focus event on the body in IE11
        return;
      }
      _this.frozen = true;
      _this.frozenBlur = true;
      _this.lastSelectedInnerNode = [node, start, end];
      _this.selectNodeContentsDebounced(node, start, end);
      if (_this.focusTimeout) {
        globalObject.clearInterval(_this.focusTimeout);
      }
      _this.focusTimeout = globalObject.setTimeout(function () {
        return (isIE11 || isEdge) && _this.node && _this.node.focus();
      }, 0);
    };
    _this.renderMain = function (props) {
      var _cx, _cx2, _cx3;
      var innerRef = props.innerRef,
        tabIndex = props.tabIndex,
        placeholder = props.placeholder,
        align = props.align,
        borderless = props.borderless,
        width = props.width,
        error = props.error,
        warning = props.warning,
        onValueChange = props.onValueChange,
        disabled = props.disabled,
        prefix = props.prefix,
        suffix = props.suffix,
        leftIcon = props.leftIcon,
        rightIcon = props.rightIcon,
        value = props.value,
        onMouseDragStart = props.onMouseDragStart,
        onMouseDragEnd = props.onMouseDragEnd,
        takeContentWidth = props.takeContentWidth,
        ariaDescribedby = props['aria-describedby'],
        ariaLabel = props['aria-label'],
        ariaLabelledby = props['aria-labelledby'],
        showClearIcon = props.showClearIcon,
        onClearCrossClick = props.onClearCrossClick,
        rest = _objectWithoutPropertiesLoose(props, _excluded);
      var focused = _this.state.focused;
      var getRightIcon = function getRightIcon() {
        return _this.state.clearCrossShowed ? /*#__PURE__*/
        React.createElement(ClearCrossIcon, {
          "data-tid": InputDataTids.clearCross,
          size: _this.size,
          onFocus: function onFocus(event) {
            return event.stopPropagation();
          },
          onClick: onClearCrossClick
        }) : rightIcon;
      };
      var leftSide = /*#__PURE__*/React.createElement(InputLayoutAside, {
        icon: leftIcon,
        text: prefix,
        side: "left"
      });
      var rightSide = /*#__PURE__*/React.createElement(InputLayoutAside, {
        icon: getRightIcon(),
        text: suffix,
        side: "right"
      });
      var className = cx(styles.root(), jsInputStyles.root(_this.theme), _this.getSizeClassName(), (_cx = {}, _cx[jsInputStyles.disabled(_this.theme)] = !!disabled, _cx[jsInputStyles.borderless()] = !!borderless, _cx[jsInputStyles.focus(_this.theme)] = focused, _cx[jsInputStyles.hovering(_this.theme)] = !focused && !disabled && !warning && !error && !borderless, _cx[jsInputStyles.warning(_this.theme)] = !!warning, _cx[jsInputStyles.error(_this.theme)] = !!error, _cx[jsInputStyles.focusFallback(_this.theme)] = focused && (isIE11 || isEdge), _cx[jsInputStyles.warningFallback(_this.theme)] = !!warning && (isIE11 || isEdge), _cx[jsInputStyles.errorFallback(_this.theme)] = !!error && (isIE11 || isEdge), _cx[jsInputStyles.hideBlinkingCursor()] = isMobile, _cx));
      var wrapperClass = cx(jsInputStyles.wrapper(), (_cx2 = {}, _cx2[styles.userSelectContain()] = focused, _cx2));
      var size = _this.size;
      var context = InputLayoutContextDefault;
      Object.assign(context, {
        disabled: disabled,
        focused: focused,
        size: size
      });
      return /*#__PURE__*/(
        React.createElement(FocusControlWrapper, {
          disabled: disabled,
          onBlurWhenDisabled: _this.resetFocus
        }, /*#__PURE__*/
        React.createElement("span", _extends({
          "data-tid": InputLikeTextDataTids.root
        }, rest, {
          className: className,
          style: {
            width: width,
            textAlign: align
          },
          tabIndex: disabled ? -1 : 0,
          onFocus: _this.handleFocus,
          onMouseEnter: _this.handleHover,
          onMouseLeave: _this.handleUnhover,
          onBlur: _this.handleBlur,
          ref: _this.innerRef,
          onKeyDown: _this.handleKeyDown,
          onMouseDown: _this.handleMouseDown,
          role: "textbox",
          "aria-disabled": disabled,
          "aria-describedby": ariaDescribedby,
          "aria-label": ariaLabel,
          "aria-labelledby": ariaLabelledby
        }), /*#__PURE__*/

        React.createElement(InputLayoutContext.Provider, {
          value: context
        }, /*#__PURE__*/
        React.createElement("input", {
          type: "hidden",
          "data-tid": InputLikeTextDataTids.nativeInput,
          value: value,
          disabled: disabled
        }), leftSide, /*#__PURE__*/
        React.createElement("span", {
          className: wrapperClass
        }, /*#__PURE__*/
        React.createElement("span", {
          "data-tid": InputLikeTextDataTids.input,
          className: cx(jsInputStyles.input(_this.theme), (_cx3 = {}, _cx3[styles.absolute()] = !takeContentWidth, _cx3[jsInputStyles.inputFocus(_this.theme)] = focused, _cx3[jsInputStyles.inputDisabled(_this.theme)] = disabled, _cx3))
        }, _this.props.children), _this.renderPlaceholder()), rightSide, isIE11 && focused && /*#__PURE__*/React.createElement(HiddenInput, {
          nodeRef: _this.hiddenInputRef
        }))))
      );
    };
    _this.renderPlaceholder = function () {
      var _this$props = _this.props,
        children = _this$props.children,
        placeholder = _this$props.placeholder,
        disabled = _this$props.disabled;
      var focused = _this.state.focused;
      var hasValue = isNonNullable(children) && children !== '';
      if (!hasValue && placeholder) {
        var _cx4;
        return /*#__PURE__*/(
          React.createElement("span", {
            className: cx(jsInputStyles.placeholder(_this.theme), (_cx4 = {}, _cx4[jsInputStyles.placeholderDisabled(_this.theme)] = disabled, _cx4[jsInputStyles.placeholderFocus(_this.theme)] = focused, _cx4))
          }, placeholder)
        );
      }
      return null;
    };
    _this.handleDocumentMouseDown = function (e) {
      if (_this.state.focused && _this.node && isInstanceOf(e.target, globalObject.Node) && !_this.node.contains(e.target)) {
        _this.defrost();
      }
    };
    _this.handleDocumentKeyDown = function (e) {
      if (_this.state.focused && isKeyTab(e)) {
        _this.defrost();
      }
    };
    _this.handleMouseDown = function () {
      _this.frozen = true;
    };
    _this.handleKeyDown = function (e) {
      if (_this.props.disabled) {
        return;
      }
      if (isIE11 && isShortcutPaste(e) && _this.hiddenInput) {
        _this.frozen = true;
        globalObject.setTimeout(function () {
          if (_this.lastSelectedInnerNode) {
            var _this2;
            (_this2 = _this).selectInnerNode.apply(_this2, _this.lastSelectedInnerNode);
          }
          if (_this.node) {
            _this.node.focus();
          }
        }, 0);
        _this.hiddenInput.focus();
      }
      if (_this.props.onKeyDown) {
        _this.props.onKeyDown(e);
      }
    };
    _this.handleMouseDragStart = function (e) {
      var _globalObject$documen;
      _this.dragging = true;
      (_globalObject$documen = globalObject.document) == null || _globalObject$documen.documentElement.classList.add(styles.userSelectNone());
      if (_this.props.onMouseDragStart) {
        _this.props.onMouseDragStart(e);
      }
    };
    _this.handleMouseDragEnd = function (e) {
      var _globalObject$documen2;
      // Дожидаемся onMouseUp
      globalObject.setTimeout(function () {
        _this.dragging = false;
        if (_this.props.onMouseDragEnd) {
          _this.props.onMouseDragEnd(e);
        }
      }, 0);
      (_globalObject$documen2 = globalObject.document) == null || _globalObject$documen2.documentElement.classList.remove(styles.userSelectNone());
    };
    _this.handleFocus = function (e) {
      if (isMobile) {
        var _this$node;
        (_this$node = _this.node) == null || _this$node.setAttribute('contenteditable', 'true');
      }
      if (_this.props.disabled) {
        if (isIE11 && globalObject.document) {
          selectNodeContents(globalObject.document.body, 0, 0);
        }
        return;
      }
      if ((isIE11 || isEdge) && _this.frozen) {
        _this.frozen = false;
        if (_this.state.focused) {
          return;
        }
      }

      // Auto-batching React@18 creates problems that are fixed with flushSync
      // https://github.com/skbkontur/retail-ui/pull/3144#issuecomment-1535235366
      if (React.version.search('18') === 0) {
        ReactDOM.flushSync(function () {
          return _this.setState({
            focused: true
          });
        });
      } else {
        _this.setState({
          focused: true
        });
      }
      if (_this.props.onFocus) {
        _this.props.onFocus(e);
      }
    };
    _this.resetFocus = function () {
      _this.selectNodeContentsDebounced.cancel();
      if (isMobile) {
        var _this$node2;
        (_this$node2 = _this.node) == null || _this$node2.removeAttribute('contenteditable');
      }
      if ((isIE11 || isEdge) && _this.frozenBlur) {
        _this.frozenBlur = false;
      }
      removeAllSelections();
      _this.setState({
        focused: false
      });
    };
    _this.handleBlur = function (e) {
      _this.selectNodeContentsDebounced.cancel();
      if (isMobile) {
        var _this$node3;
        (_this$node3 = _this.node) == null || _this$node3.removeAttribute('contenteditable');
      }
      if (_this.props.disabled) {
        e.stopPropagation();
        return;
      }
      if ((isIE11 || isEdge) && _this.frozenBlur) {
        _this.frozenBlur = false;
        return;
      }
      if ((isIE11 || isEdge) && _this.frozen) {
        return;
      }
      removeAllSelections();
      _this.setState({
        focused: false
      });
      _this.props.onBlur == null || _this.props.onBlur(e);
    };
    _this.handleHover = function () {
      _this.setState({
        clearCrossShowed: _this.getClearCrossShowed({
          focused: _this.state.focused,
          hovered: true
        })
      });
    };
    _this.handleUnhover = function () {
      _this.setState({
        clearCrossShowed: _this.getClearCrossShowed({
          focused: _this.state.focused,
          hovered: false
        })
      });
    };
    _this.hiddenInputRef = function (el) {
      _this.hiddenInput = el;
    };
    _this.innerRef = function (el) {
      if (_this.props.innerRef) {
        _this.props.innerRef(el);
      }
      _this.node = el;
    };
    _this.defrost = function () {
      _this.frozen = false;
      _this.frozenBlur = false;
    };
    _this.getSizeClassName = function () {
      var _cx5, _cx6, _cx7;
      switch (_this.size) {
        case 'large':
          return cx((_cx5 = {}, _cx5[jsInputStyles.sizeLarge(_this.theme)] = true, _cx5[jsInputStyles.sizeLargeFallback(_this.theme)] = isIE11 || isEdge, _cx5));
        case 'medium':
          return cx((_cx6 = {}, _cx6[jsInputStyles.sizeMedium(_this.theme)] = true, _cx6[jsInputStyles.sizeMediumFallback(_this.theme)] = isIE11 || isEdge, _cx6));
        case 'small':
        default:
          return cx((_cx7 = {}, _cx7[jsInputStyles.sizeSmall(_this.theme)] = true, _cx7[jsInputStyles.sizeSmallFallback(_this.theme)] = isIE11 || isEdge, _cx7));
      }
    };
    return _this;
  }
  _inheritsLoose(InputLikeText, _React$Component);
  var _proto = InputLikeText.prototype; /**
                                        * @public
                                        */
  _proto.focus = function focus() {
    if (this.node) {
      this.node.focus();
    }
  } /**
    * @public
    */;
  _proto.blur = function blur() {
    if (this.node) {
      this.node.blur();
    }
  } /**
    * @public
    */;
  _proto.blink = function blink() {
    if (this.props.disabled) {
      return;
    }
    _blink({
      el: this.node,
      blinkColor: this.theme.inputBlinkColor
    });
  };
  _proto.getNode = function getNode() {
    return this.node;
  };
  _proto.componentDidMount = function componentDidMount() {
    var _globalObject$documen3, _globalObject$documen4;
    if (this.node) {
      MouseDrag.listen(this.node).onMouseDragStart(this.handleMouseDragStart).onMouseDragEnd(this.handleMouseDragEnd);
    }
    (_globalObject$documen3 = globalObject.document) == null || _globalObject$documen3.addEventListener('mousedown', this.handleDocumentMouseDown);
    (_globalObject$documen4 = globalObject.document) == null || _globalObject$documen4.addEventListener('keydown', this.handleDocumentKeyDown);
  };
  _proto.componentWillUnmount = function componentWillUnmount() {
    var _globalObject$documen5, _globalObject$documen6;
    MouseDrag.stop(this.node);
    (_globalObject$documen5 = globalObject.document) == null || _globalObject$documen5.removeEventListener('mousedown', this.handleDocumentMouseDown);
    (_globalObject$documen6 = globalObject.document) == null || _globalObject$documen6.removeEventListener('keydown', this.handleDocumentKeyDown);
  };
  _proto.render = function render() {
    var _this3 = this;
    return /*#__PURE__*/React.createElement(ThemeContext.Consumer, null, function (theme) {
      _this3.theme = theme;
      return /*#__PURE__*/React.createElement(CommonWrapper, _extends({
        rootNodeRef: _this3.setRootNode
      }, _this3.getProps()), _this3.renderMain);
    });
  };
  return InputLikeText;
}(React.Component), _InputLikeText.__KONTUR_REACT_UI__ = 'InputLikeText', _InputLikeText.displayName = 'InputLikeText', _InputLikeText.defaultProps = {
  showClearIcon: 'never'
}, _InputLikeText)) || _class) || _class;