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 = ["error", "warning", "size", "onMouseEnter", "onMouseLeave", "onMouseOver", "onValueChange", "type", "initialIndeterminate", "aria-describedby", "aria-label"];
var _class, _Checkbox;
import React from 'react';
import { globalObject } from '@skbkontur/global-object';
import { keyListener } from "../../../lib/events/keyListener";
import { ThemeContext } from "../../../lib/theming/ThemeContext";
import { isEdge, isIE11 } from "../../../lib/client";
import { CommonWrapper } from "../../../internal/CommonWrapper";
import { cx } from "../../../lib/theming/Emotion";
import { rootNode } from "../../../lib/rootNode";
import { fixFirefoxModifiedClickOnLabel } from "../../../lib/events/fixFirefoxModifiedClickOnLabel";
import { FocusControlWrapper } from "../../../internal/FocusControlWrapper";
import { withSize } from "../../../lib/size/SizeDecorator";
import { createPropsGetter } from "../../../lib/createPropsGetter";
import { styles, globalClasses } from "../Checkbox.styles";
import { CheckedIcon } from "../CheckedIcon";
import { IndeterminateIcon } from "../IndeterminateIcon";
export var CheckboxDataTids = {
  root: 'Checkbox__root'
};

/**
 * `Checkbox` используется для управления параметром с двумя состояниями.
 *
 * Чекбокс не запускает действие немедленно. Как правило, для этого нужно нажать подтверждающую кнопку.
 * Для немедленного включения какого-то режима в интерфейсе лучше подходит Toggle.
 */
export var Checkbox = rootNode(_class = withSize(_class = (_Checkbox = /*#__PURE__*/function (_React$PureComponent) {
  function Checkbox() {
    var _this;
    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }
    _this = _React$PureComponent.call.apply(_React$PureComponent, [this].concat(args)) || this;
    _this.state = {
      focusedByTab: false,
      indeterminate: _this.props.initialIndeterminate || false,
      isShiftPressed: false
    };
    _this.input = /*#__PURE__*/React.createRef();
    _this.getProps = createPropsGetter({});
    _this.handleShiftPress = function (e) {
      if (e.key === 'Shift') {
        _this.setState(function () {
          return {
            isShiftPressed: true
          };
        });
      }
    };
    _this.handleShiftRelease = function (e) {
      if (e.key === 'Shift') {
        _this.setState({
          isShiftPressed: false
        });
      }
    };
    _this.componentDidMount = function () {
      var _globalObject$documen, _globalObject$documen2;
      if (_this.state.indeterminate && _this.input.current) {
        _this.input.current.indeterminate = true;
      }
      (_globalObject$documen = globalObject.document) == null || _globalObject$documen.addEventListener('keydown', _this.handleShiftPress);
      (_globalObject$documen2 = globalObject.document) == null || _globalObject$documen2.addEventListener('keyup', _this.handleShiftRelease);
    };
    _this.componentWillUnmount = function () {
      var _globalObject$documen3, _globalObject$documen4;
      (_globalObject$documen3 = globalObject.document) == null || _globalObject$documen3.removeEventListener('keydown', _this.handleShiftPress);
      (_globalObject$documen4 = globalObject.document) == null || _globalObject$documen4.removeEventListener('keyup', _this.handleShiftRelease);
    };

    /**
     * Устанавливает чекбокс в HTML-состояние `indeterminate`.
     * @public
     */
    _this.setIndeterminate = function () {
      _this.setState({
        indeterminate: true
      });
      if (_this.input.current) {
        _this.input.current.indeterminate = true;
      }
    };

    /**
     * Снимает с чекбокса HTML-состояние `indeterminate`.
     * @public
     */
    _this.resetIndeterminate = function () {
      _this.setState({
        indeterminate: false
      });
      if (_this.input.current) {
        _this.input.current.indeterminate = false;
      }
    };
    _this.renderMain = function (props) {
      var _cx, _cx3, _cx4;
      var error = props.error,
        warning = props.warning,
        size = props.size,
        onMouseEnter = props.onMouseEnter,
        onMouseLeave = props.onMouseLeave,
        onMouseOver = props.onMouseOver,
        onValueChange = props.onValueChange,
        type = props.type,
        initialIndeterminate = props.initialIndeterminate,
        ariaDescribedby = props['aria-describedby'],
        ariaLabel = props['aria-label'],
        rest = _objectWithoutPropertiesLoose(props, _excluded);
      var isIndeterminate = _this.state.indeterminate;
      var iconClass = cx(styles.icon(), !_this.props.checked && !isIndeterminate && styles.iconUnchecked());
      var iconSize = parseInt(_this.getCheckboxBoxSize());
      var IconCheck = /*#__PURE__*/
      React.createElement("span", {
        className: iconClass
      }, /*#__PURE__*/
      React.createElement(CheckedIcon, {
        size: iconSize
      }));
      var IconSquare = /*#__PURE__*/
      React.createElement("span", {
        className: iconClass
      }, /*#__PURE__*/
      React.createElement(IndeterminateIcon, {
        size: iconSize
      }));
      var rootClass = cx(_this.getRootSizeClassName(), (_cx = {}, _cx[styles.root(_this.theme)] = true, _cx[styles.rootFallback()] = isIE11 || isEdge, _cx[styles.rootChecked(_this.theme)] = _this.props.checked || isIndeterminate, _cx[styles.rootDisableTextSelect()] = _this.state.isShiftPressed, _cx[styles.disabled(_this.theme)] = Boolean(_this.props.disabled), _cx));
      var inputProps = _extends({}, rest, {
        type: 'checkbox',
        className: styles.input(),
        onChange: _this.handleChange,
        onFocus: _this.handleFocus,
        onBlur: _this.handleBlur,
        onClick: _this.handleClick,
        ref: _this.input
      });
      var caption = null;
      if (_this.props.children) {
        var _cx2;
        var captionClass = cx((_cx2 = {}, _cx2[styles.caption(_this.theme)] = true, _cx2[styles.captionIE11()] = isIE11 || isEdge, _cx2[styles.disabled(_this.theme)] = Boolean(_this.props.disabled), _cx2));
        caption = /*#__PURE__*/React.createElement("span", {
          className: captionClass
        }, _this.props.children);
      }
      var box = /*#__PURE__*/
      React.createElement("div", {
        className: cx(_this.getBoxWrapperSizeClassName(), (_cx3 = {}, _cx3[styles.boxWrapper(_this.theme)] = true, _cx3))
      }, /*#__PURE__*/

      React.createElement("div", {
        className: cx(styles.box(_this.theme), globalClasses.box, (_cx4 = {}, _cx4[styles.boxChecked(_this.theme)] = _this.props.checked || isIndeterminate, _cx4[styles.boxFocus(_this.theme)] = _this.state.focusedByTab, _cx4[styles.boxError(_this.theme)] = _this.props.error, _cx4[styles.boxWarning(_this.theme)] = _this.props.warning, _cx4[styles.boxDisabled(_this.theme)] = _this.props.disabled, _cx4))
      }, isIndeterminate && IconSquare || IconCheck));
      return /*#__PURE__*/(
        React.createElement("label", {
          "data-tid": CheckboxDataTids.root,
          className: rootClass,
          onMouseEnter: onMouseEnter,
          onMouseLeave: onMouseLeave,
          onMouseOver: onMouseOver,
          onClick: fixFirefoxModifiedClickOnLabel(_this.input)
        }, /*#__PURE__*/

        React.createElement(FocusControlWrapper, {
          onBlurWhenDisabled: _this.resetFocus
        }, /*#__PURE__*/
        React.createElement("input", _extends({}, inputProps, {
          "aria-label": ariaLabel,
          "aria-describedby": ariaDescribedby
        }))), box, caption)
      );
    };
    _this.handleFocus = function (e) {
      if (!_this.props.disabled) {
        // focus event fires before keyDown eventlistener
        // so we should check tabPressed in async way
        globalObject.requestAnimationFrame == null || globalObject.requestAnimationFrame(function () {
          if (keyListener.isTabPressed) {
            _this.setState({
              focusedByTab: true
            });
          }
        });
        if (_this.props.onFocus) {
          _this.props.onFocus(e);
        }
      }
    };
    _this.resetFocus = function () {
      return _this.setState({
        focusedByTab: false
      });
    };
    _this.handleBlur = function (e) {
      _this.resetFocus();
      _this.props.onBlur == null || _this.props.onBlur(e);
    };
    _this.handleChange = function (event) {
      var checked = event.currentTarget.checked;
      _this.props.onValueChange == null || _this.props.onValueChange(checked);
      _this.resetIndeterminate();
      _this.props.onChange == null || _this.props.onChange(event);
    };
    _this.handleClick = function (e) {
      _this.props.onClick == null || _this.props.onClick(e);
      // support IE11's and old Edge's special behavior
      // https://github.com/jquery/jquery/issues/1698
      if (_this.state.indeterminate && (isIE11 || isEdge)) {
        _this.resetIndeterminate();
        // simulate correct behavior only if onValueChange is used
        // because we cant simulate real native onChange event
        if (_this.props.onValueChange && _this.input.current) {
          var checked = !_this.input.current.checked;
          if (_this.props.checked === undefined) {
            // in case of uncontrolled mode
            _this.input.current.checked = checked;
          }
          _this.props.onValueChange(checked);
        }
      }
    };
    return _this;
  }
  _inheritsLoose(Checkbox, _React$PureComponent);
  var _proto = Checkbox.prototype;
  _proto.getRootSizeClassName = function getRootSizeClassName() {
    switch (this.size) {
      case 'large':
        return styles.rootLarge(this.theme);
      case 'medium':
        return styles.rootMedium(this.theme);
      case 'small':
      default:
        return styles.rootSmall(this.theme);
    }
  };
  _proto.getBoxWrapperSizeClassName = function getBoxWrapperSizeClassName() {
    switch (this.size) {
      case 'large':
        return styles.boxWrapperLarge(this.theme);
      case 'medium':
        return styles.boxWrapperMedium(this.theme);
      case 'small':
      default:
        return styles.boxWrapperSmall(this.theme);
    }
  };
  _proto.getCheckboxBoxSize = function getCheckboxBoxSize() {
    switch (this.size) {
      case 'large':
        return this.theme.checkboxBoxSizeLarge;
      case 'medium':
        return this.theme.checkboxBoxSizeMedium;
      case 'small':
      default:
        return this.theme.checkboxBoxSizeSmall;
    }
  };
  _proto.componentDidUpdate = function componentDidUpdate(prevProps) {
    if (prevProps.checked !== this.props.checked) {
      this.resetIndeterminate();
    }
  };
  _proto.render = function render() {
    var _this2 = this;
    return /*#__PURE__*/React.createElement(ThemeContext.Consumer, null, function (theme) {
      _this2.theme = theme;
      return /*#__PURE__*/React.createElement(CommonWrapper, _extends({
        rootNodeRef: _this2.setRootNode
      }, _this2.getProps()), _this2.renderMain);
    });
  } /**
    * Программная установка фокуса чекбоксу.
    * @public
    */;
  _proto.focus = function focus() {
    var _this$input$current;
    keyListener.isTabPressed = true;
    (_this$input$current = this.input.current) == null || _this$input$current.focus();
  } /**
    * Программное снятие фокуса с чекбокса.
    * @public
    */;
  _proto.blur = function blur() {
    var _this$input$current2;
    (_this$input$current2 = this.input.current) == null || _this$input$current2.blur();
  };
  return Checkbox;
}(React.PureComponent), _Checkbox.__KONTUR_REACT_UI__ = 'Checkbox', _Checkbox.displayName = 'Checkbox', _Checkbox)) || _class) || _class;