"use strict";var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;exports.__esModule = true;exports.ColorableInputElement = void 0;var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));

var _react = _interopRequireWildcard(require("react"));
var _lodash = _interopRequireDefault(require("lodash.debounce"));

var _ThemeContext = require("../../../lib/theming/ThemeContext");

var _forwardRefAndName = require("../../../lib/forwardRefAndName");
var _Emotion = require("../../../lib/theming/Emotion");
var _utils = require("../../../lib/utils");

var _ColorableInputElement = require("./ColorableInputElement.styles");var _excluded = ["children", "onInput", "onFocus", "onBlur", "showOnFocus", "alwaysShowMask"]; /* eslint react-hooks/exhaustive-deps: 2 */







// Возможно придётся включить.
// Иногда, на тяжёлых страницах, текст рендерится итеративно.
// Из-за этого могут оставаться артефакты при покраске компонента, которые пропадут только после фокуса.
// setInterval(() => window.requestAnimationFrame(() => dictionary.forEach((paint) => paint())), 1000);

var ColorableInputElement = exports.ColorableInputElement = (0, _forwardRefAndName.forwardRefAndName)(
  'ColorableInputElement',
  function ColorableInputElement(props, ref) {var _props$style3;
    var inputRef = (0, _react.useRef)(null);
    var spanRef = (0, _react.useRef)(null);
    var focused = (0, _react.useRef)(false);
    var updateActiveTimer = (0, _react.useRef)();
    var theme = (0, _react.useContext)(_ThemeContext.ThemeContext);
    var _useState = (0, _react.useState)(
        Boolean(props.alwaysShowMask || !props.placeholder && (props.value || props.defaultValue))
      ),active = _useState[0],setActive = _useState[1];

    var children = props.children,onInput = props.onInput,onFocus = props.onFocus,onBlur = props.onBlur,showOnFocus = props.showOnFocus,alwaysShowMask = props.alwaysShowMask,inputProps = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);

    var stopUpdateActive = (0, _react.useCallback)(function () {
      clearTimeout(updateActiveTimer.current);
    }, []);

    var updateActive = (0, _react.useCallback)(function () {
      stopUpdateActive();
      updateActiveTimer.current = setTimeout(function () {
        var nextActive = true;
        if (inputRef.current) {var _inputRef$current2;
          var _inputRef$current = inputRef.current,clientWidth = _inputRef$current.clientWidth,scrollWidth = _inputRef$current.scrollWidth;
          var scrollable = scrollWidth > clientWidth;

          var placeholderShown = (_inputRef$current2 = inputRef.current) == null || (_inputRef$current2 = _inputRef$current2.parentElement) == null ? void 0 : _inputRef$current2.querySelector(':placeholder-shown');

          nextActive = !(scrollable || placeholderShown);
        }
        setActive(nextActive);
      }, 0);
    }, [stopUpdateActive]);

    var paintText = (0, _react.useCallback)(function () {var _inputRef$current4, _shadow, _shadow2, _props$style, _props$style2;
      var win = (0, _utils.tryGetWindow)(inputRef.current);
      var doc = (0, _utils.tryGetDocument)(inputRef.current);
      if (!spanRef.current || !inputRef.current || !(0, _utils.isWindow)(win) || !(0, _utils.isDocument)(doc) || !active) {var _inputRef$current3;
        inputRef.current && (inputRef.current.style.backgroundImage = '');
        (_inputRef$current3 = inputRef.current) == null || _inputRef$current3.classList.remove(_ColorableInputElement.globalClasses.input);

        return;
      }

      (_inputRef$current4 = inputRef.current) == null || _inputRef$current4.classList.add(_ColorableInputElement.globalClasses.input);

      var shadow = spanRef.current.shadowRoot;
      var typedValueElement = (_shadow = shadow) == null ? void 0 : _shadow.getElementById('typed-value');
      var fullValueElement = (_shadow2 = shadow) == null ? void 0 : _shadow2.getElementById('full-value');

      if (!typedValueElement || !fullValueElement) {
        shadow = spanRef.current.attachShadow({ mode: 'open' });

        typedValueElement = doc.createElement('span');
        fullValueElement = doc.createElement('span');
        typedValueElement.setAttribute('id', 'typed-value');
        fullValueElement.setAttribute('id', 'full-value');

        shadow.append(typedValueElement, fullValueElement);
      }

      var style = getComputedStyle(inputRef.current);

      typedValueElement.textContent =
      (inputRef.current.getAttribute('data-unmasked-value') || focused.current) &&
      inputRef.current.getAttribute('data-typed-value') ||
      '';

      fullValueElement.textContent = inputRef.current.value || inputRef.current.defaultValue || '';

      var inputRect = inputRef.current.getBoundingClientRect();
      var typedValueRect = typedValueElement.getBoundingClientRect();
      var fullValueRect = fullValueElement.getBoundingClientRect();

      var threshold = typedValueRect.width / (inputRect.width / 100);
      var degree = style.fontStyle === 'italic' ? 100 : 90;
      var restValueWidth = 1 - Math.min(fullValueRect.width / inputRect.width, 1);

      var typedValueColor = theme.inputTextColor;
      var maskColor = theme.inputPlaceholderColor;
      var indent = 0;

      if (props.disabled) {
        typedValueColor = theme.inputTextColorDisabled;
        maskColor = theme.inputTextColorDisabled;
      }
      if (props.showOnFocus) {
        maskColor = focused.current ? maskColor : 'transparent';
      }
      if (((_props$style = props.style) == null ? void 0 : _props$style.textAlign) === 'right') {
        indent = 100 * restValueWidth;
      }
      if (((_props$style2 = props.style) == null ? void 0 : _props$style2.textAlign) === 'center') {
        indent = 50 * restValueWidth;
      }

      inputRef.current.style.backgroundImage = "\n      linear-gradient(\n          " +

      degree + "deg,\n          " +
      typedValueColor + " " + (threshold + indent) + "%,\n          " +
      maskColor + " " + (threshold + indent) + "%\n      )";

    }, [
    active,
    props.showOnFocus,
    props.disabled,
    theme.inputTextColor,
    theme.inputPlaceholderColor,
    theme.inputTextColorDisabled, (_props$style3 =
    props.style) == null ? void 0 : _props$style3.textAlign]
    );

    var debouncedPaintText = (0, _react.useCallback)(function () {return (0, _lodash.default)(paintText);}, [paintText])();

    var handleInput = (0, _react.useCallback)(
      function (e) {
        debouncedPaintText();

        onInput == null || onInput(e);
      },
      [debouncedPaintText, onInput]
    );

    var handleFocus = (0, _react.useCallback)(
      function (e) {
        updateActive();

        focused.current = true;

        onFocus == null || onFocus(e);
      },
      [onFocus, updateActive]
    );

    var handleBlur = (0, _react.useCallback)(
      function (e) {
        updateActive();

        focused.current = false;

        onBlur == null || onBlur(e);
      },
      [onBlur, updateActive]
    );

    (0, _react.useImperativeHandle)(
      ref,
      function () {return {
          input: inputRef.current,
          getRootNode: function getRootNode() {return inputRef.current;}
        };},
      []
    );

    (0, _react.useEffect)(function () {
      debouncedPaintText();
      updateActive();

      return stopUpdateActive;
    }, [updateActive, props.value, props.defaultValue, theme, debouncedPaintText, stopUpdateActive]);

    return /*#__PURE__*/(
      _react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/
      _react.default.cloneElement(children, (0, _extends2.default)({},
      inputProps, {
        onInput: handleInput,
        onFocus: handleFocus,
        onBlur: handleBlur,
        inputRef: inputRef,
        className: (0, _Emotion.cx)(props.className, active && _ColorableInputElement.globalClasses.input) })
      ),
      active && /*#__PURE__*/_react.default.createElement("span", { style: { visibility: 'hidden', position: 'absolute', whiteSpace: 'pre' }, ref: spanRef })
      ));

  }
);