import _extends from "@babel/runtime/helpers/esm/extends";
import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
var _class, _Button;
var _excluded = ["children"],
  _excluded2 = ["corners", "active", "disabled", "borderless", "checked", "error", "warning", "loading", "narrow", "arrow", "icon", "rightIcon", "_noPadding", "_noRightPadding", "visuallyFocused", "align", "disableFocus", "width", "tabIndex", "component", "use", "theme"];
import React from 'react';
import { globalObject } from '@skbkontur/global-object';
import { isKonturIcon } from "../../../lib/utils";
import { isIE11, isEdge, isSafari } from "../../../lib/client";
import { keyListener } from "../../../lib/events/keyListener";
import { isThemeGTE } from "../../../lib/theming/ThemeHelpers";
import { ThemeContext } from "../../../lib/theming/ThemeContext";
import { CommonWrapper } from "../../../internal/CommonWrapper";
import { cx } from "../../../lib/theming/Emotion";
import { rootNode } from "../../../lib/rootNode";
import { ThemeFactory } from "../../../lib/theming/ThemeFactory";
import { createPropsGetter } from "../../../lib/createPropsGetter";
import { Link } from "../../Link";
import { withSize } from "../../../lib/size/SizeDecorator";
import { styles, activeStyles, globalClasses } from "../Button.styles";
import { ButtonIcon, getButtonIconSizes } from "../ButtonIcon";
import { useButtonArrow } from "../ButtonArrow";
import { getInnerLinkTheme } from "../getInnerLinkTheme";
import { LoadingButtonIcon } from "../LoadingButtonIcon";
export var BUTTON_DEFAULT_COMPONENT = 'button';
export var ButtonDataTids = {
  rootElement: 'Button__rootElement',
  root: 'Button__root',
  spinner: 'Button__spinner'
};
var SpanComponent = function SpanComponent(_ref) {
  var children = _ref.children,
    rest = _objectWithoutPropertiesLoose(_ref, _excluded);
  return /*#__PURE__*/React.createElement("span", rest, children);
};

/** Кнопка запускает действие, сценарий или позволяет перейти на другую страницу. */
export var Button = withSize(_class = rootNode(_class = (_Button = /*#__PURE__*/function (_React$Component) {
  function Button() {
    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(Button.defaultProps);
    _this.state = {
      focusedByTab: false
    };
    _this.node = null;
    _this.renderMain = function (props) {
      var _cx, _cx4, _cx5;
      var corners = props.corners,
        active = props.active,
        disabled = props.disabled,
        borderless = props.borderless,
        checked = props.checked,
        error = props.error,
        warning = props.warning,
        loading = props.loading,
        narrow = props.narrow,
        arrow = props.arrow,
        icon = props.icon,
        rightIcon = props.rightIcon,
        _noPadding = props._noPadding,
        _noRightPadding = props._noRightPadding,
        visuallyFocused = props.visuallyFocused,
        align = props.align,
        disableFocus = props.disableFocus,
        width = props.width,
        tabIndex = props.tabIndex,
        _component = props.component,
        useProp = props.use,
        theme = props.theme,
        rest = _objectWithoutPropertiesLoose(props, _excluded2);
      var _this$getProps = _this.getProps(),
        use = _this$getProps.use,
        component = _this$getProps.component,
        children = _this$getProps.children;
      var sizeClass = _this.getSizeClassName();
      var isFocused = _this.state.focusedByTab || visuallyFocused;
      var isLink = use === 'link';
      var _useButtonArrow = useButtonArrow(_extends({}, _this.props, {
          isFocused: Boolean(isFocused),
          size: _this.size
        }), _this.theme),
        rootClassNameWithArrow = _useButtonArrow[0],
        arrowNode = _useButtonArrow[1];
      var isUseStateWithoutOutlineInDisabledState = !['default', 'backless'].includes(use);
      var nonInteractive = disabled || loading;
      var rootClassName = cx.apply(void 0, [styles.root(_this.theme), styles[use](_this.theme), sizeClass, narrow && styles.narrow(), _noPadding && styles.noPadding(), _noRightPadding && styles.noRightPadding(), rootClassNameWithArrow].concat(nonInteractive ? [styles.disabled(_this.theme), isUseStateWithoutOutlineInDisabledState && styles.disabledWithoutOutline(_this.theme), checked && styles.checkedDisabled(_this.theme), borderless && styles.borderless(), use === 'backless' && styles.backlessDisabled(_this.theme), use === 'text' && styles.textDisabled(), globalClasses.disabled] : [active && !checked && activeStyles[use](_this.theme), isFocused && styles.focus(_this.theme), checked && styles.checked(_this.theme), checked && isFocused && styles.checkedFocused(_this.theme), borderless && !checked && !isFocused && styles.borderless()]));
      var rootProps = _extends({}, rest, {
        className: rootClassName,
        style: _extends({
          textAlign: align
        }, corners),
        onFocus: _this.handleFocus,
        onBlur: _this.handleBlur,
        tabIndex: _this.getTabIndex({
          disableFocus: disableFocus,
          disabled: nonInteractive,
          tabIndex: tabIndex
        })
      });
      var wrapProps = {
        className: cx(globalClasses.root, (_cx = {}, _cx[styles.wrap(_this.theme)] = true, _cx[_this.getSizeWrapClassName()] = true, _cx)),
        style: {
          width: width
        }
      };
      var buttonOnlyProps = component === 'button' ? {
        disabled: nonInteractive
      } : {};
      var innerShadowNode = null;
      var outlineNode = null;
      if ((!isFocused || isLink) && !nonInteractive) {
        var _cx2;
        outlineNode = /*#__PURE__*/
        React.createElement("div", {
          className: cx(styles.outline(), (_cx2 = {}, _cx2[styles.outlineWarning(_this.theme)] = warning, _cx2[styles.outlineError(_this.theme)] = error, _cx2[styles.outlineLink()] = isLink, _cx2[styles.outlineLinkWarning(_this.theme)] = isLink && warning, _cx2[styles.outlineLinkError(_this.theme)] = isLink && error, _cx2))
        });
      }
      var iconProps = {
        use: use,
        size: _this.size,
        hasChildren: !!children,
        loading: loading || false
      };
      var leftIconNode = icon && /*#__PURE__*/React.createElement(ButtonIcon, _extends({}, iconProps, {
        position: "left",
        icon: icon
      }));
      var rightIconNode = rightIcon && /*#__PURE__*/
      React.createElement(ButtonIcon, _extends({}, iconProps, {
        hasBothIcons: !!icon && !!rightIcon,
        position: "right",
        icon: rightIcon
      }));

      // Force disable all props and features, that cannot be use with Link
      if (isLink) {
        var _cx3;
        rootProps.className = cx((_cx3 = {}, _cx3[styles.root(_this.theme)] = true, _cx3[sizeClass] = true, _cx3[styles.link(_this.theme)] = true, _cx3[styles.linkLineHeight()] = !isSafari, _cx3[styles.linkLineHeightSafariFallback()] = isSafari, _cx3[styles.linkFocus(_this.theme)] = isFocused, _cx3[styles.linkDisabled(_this.theme)] = nonInteractive, _cx3));
        Object.assign(wrapProps, {
          className: cx(styles.wrap(_this.theme), styles.wrapLink()),
          style: {
            width: wrapProps.style.width
          }
        });
        rootProps.style.textAlign = undefined;
      }
      var hasLoadingNode = loading && !icon && !rightIcon;
      var loadingNode = hasLoadingNode && /*#__PURE__*/React.createElement(LoadingButtonIcon, {
        size: _this.size
      });
      var captionNode = /*#__PURE__*/
      React.createElement("div", {
        className: cx(styles.caption(), globalClasses.caption, (_cx4 = {}, _cx4[styles.captionLink()] = isLink, _cx4[styles.captionDisabled()] = !checked && disabled, _cx4))
      }, loadingNode, leftIconNode, /*#__PURE__*/
      React.createElement("span", {
        className: cx(globalClasses.text, (_cx5 = {}, _cx5[styles.visibilityHidden()] = hasLoadingNode, _cx5))
      }, children), rightIconNode);
      if (isLink && !loading) {
        captionNode = /*#__PURE__*/
        React.createElement(ThemeContext.Provider, {
          value: getInnerLinkTheme(_this.theme)
        }, /*#__PURE__*/

        React.createElement(Link, {
          focused: isFocused,
          disabled: disabled,
          icon: _this.renderIcon2022(icon),
          rightIcon: _this.renderIcon2022(rightIcon),
          tabIndex: -1,
          component: SpanComponent
        }, children));
      }
      var Root = component;
      return /*#__PURE__*/(
        React.createElement("span", _extends({}, wrapProps, {
          "data-tid": ButtonDataTids.root
        }), /*#__PURE__*/
        React.createElement(Root, _extends({
          "data-tid": ButtonDataTids.rootElement,
          ref: _this._ref
        }, rootProps, buttonOnlyProps), innerShadowNode, outlineNode, arrowNode, captionNode))
      );
    };
    _this.handleFocus = function (e) {
      if (!_this.props.disabled && !_this.props.disableFocus) {
        // 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
            });
          }
        });
        _this.props.onFocus == null || _this.props.onFocus(e);
      }
    };
    _this.handleBlur = function (e) {
      _this.setState({
        focusedByTab: false
      });
      if (!_this.props.disabled && !_this.props.disableFocus) {
        _this.props.onBlur == null || _this.props.onBlur(e);
      }
    };
    _this._ref = function (node) {
      _this.node = node;
    };
    return _this;
  }
  _inheritsLoose(Button, _React$Component);
  var _proto = Button.prototype;
  _proto.componentDidMount = function componentDidMount() {
    if (this.props.autoFocus) {
      keyListener.isTabPressed = true;
      this.focus();
    } // warning(
    //   this.props.use !== 'link',
    //   `[Button]: Use 'Link' has been deprecated. Please, use Link with 'component=button' prop instead.`,
    // );
  };
  Button.getDerivedStateFromProps = function getDerivedStateFromProps(props) {
    if (props.loading || props.disabled) {
      return {
        focusedByTab: false
      };
    }
    return null;
  } /** Программно устанавливает фокус на кнопке. Появляется фокусная рамка, элемент получает клавиатурные события и воспринимается как текущий элемент для чтения скринридерами.
    * @public
    */;
  _proto.focus = function focus() {
    var _this$node;
    (_this$node = this.node) == null || _this$node.focus();
  } /** Программно снимает фокус с кнопки.
    * @public
    */;
  _proto.blur = function blur() {
    var _this$node2;
    (_this$node2 = this.node) == null || _this$node2.blur();
  };
  _proto.render = function render() {
    var _this2 = this;
    return /*#__PURE__*/React.createElement(ThemeContext.Consumer, null, function (theme) {
      _this2.theme = _this2.props.theme ? ThemeFactory.create(_this2.props.theme, theme) : theme;
      return /*#__PURE__*/React.createElement(CommonWrapper, _extends({
        rootNodeRef: _this2.setRootNode
      }, _this2.props), _this2.renderMain);
    });
  };
  _proto.getTabIndex = function getTabIndex(_ref2) {
    var disableFocus = _ref2.disableFocus,
      disabled = _ref2.disabled,
      _ref2$tabIndex = _ref2.tabIndex,
      tabIndex = _ref2$tabIndex === void 0 ? 0 : _ref2$tabIndex;
    if (disableFocus || disabled) {
      return -1;
    }
    return tabIndex;
  };
  _proto.renderIcon2022 = function renderIcon2022(icon) {
    if (icon && isKonturIcon(icon)) {
      var _icon$props$size;
      var sizes = getButtonIconSizes(this.theme);
      return /*#__PURE__*/React.cloneElement(icon, {
        size: (_icon$props$size = icon.props.size) != null ? _icon$props$size : sizes[this.size]
      });
    }
    return icon;
  };
  _proto.getSizeClassName = function getSizeClassName() {
    var _this$getProps2 = this.getProps(),
      icon = _this$getProps2.icon,
      rightIcon = _this$getProps2.rightIcon,
      children = _this$getProps2.children;
    var isThemeGTE_5_3 = isThemeGTE(this.theme, '5.3');
    switch (this.size) {
      case 'large':
        {
          var _commonClasses, _themeSpecificClasses;
          var commonClasses = (_commonClasses = {}, _commonClasses[styles.sizeLargeIE11(this.theme)] = isIE11 || isEdge, _commonClasses[styles.sizeLargeWithIcon(this.theme)] = !!icon, _commonClasses[styles.sizeLargeWithIconWithoutText(this.theme)] = !!icon && !children, _commonClasses);
          var themeSpecificClasses = (_themeSpecificClasses = {}, _themeSpecificClasses[styles.sizeLargeWithRightIcon(this.theme)] = !!rightIcon, _themeSpecificClasses[styles.sizeLargeWithIconWithoutText5_3(this.theme)] = (!!icon || !!rightIcon) && !children, _themeSpecificClasses);
          return cx(styles.sizeLarge(this.theme), commonClasses, isThemeGTE_5_3 && themeSpecificClasses);
        }
      case 'medium':
        {
          var _commonClasses3, _themeSpecificClasses3;
          var _commonClasses2 = (_commonClasses3 = {}, _commonClasses3[styles.sizeMediumIE11(this.theme)] = isIE11 || isEdge, _commonClasses3[styles.sizeMediumWithIcon(this.theme)] = !!icon, _commonClasses3[styles.sizeMediumWithIconWithoutText(this.theme)] = !!icon && !children, _commonClasses3);
          var _themeSpecificClasses2 = (_themeSpecificClasses3 = {}, _themeSpecificClasses3[styles.sizeMediumWithRightIcon(this.theme)] = !!rightIcon, _themeSpecificClasses3[styles.sizeMediumWithIconWithoutText5_3(this.theme)] = (!!icon || !!rightIcon) && !children, _themeSpecificClasses3);
          return cx(styles.sizeMedium(this.theme), _commonClasses2, isThemeGTE_5_3 && _themeSpecificClasses2);
        }
      case 'small':
      default:
        {
          var _commonClasses5, _themeSpecificClasses5;
          var _commonClasses4 = (_commonClasses5 = {}, _commonClasses5[styles.sizeSmallIE11(this.theme)] = isIE11 || isEdge, _commonClasses5[styles.sizeSmallWithIcon(this.theme)] = !!icon, _commonClasses5[styles.sizeSmallWithIconWithoutText(this.theme)] = !!icon && !children, _commonClasses5);
          var _themeSpecificClasses4 = (_themeSpecificClasses5 = {}, _themeSpecificClasses5[styles.sizeSmallWithRightIcon(this.theme)] = !!rightIcon, _themeSpecificClasses5[styles.sizeSmallWithIconWithoutText5_3(this.theme)] = (!!icon || !!rightIcon) && !children, _themeSpecificClasses5);
          return cx(styles.sizeSmall(this.theme), _commonClasses4, isThemeGTE_5_3 && _themeSpecificClasses4);
        }
    }
  };
  _proto.getSizeWrapClassName = function getSizeWrapClassName() {
    switch (this.size) {
      case 'large':
        return styles.wrapLarge(this.theme);
      case 'medium':
        return styles.wrapMedium(this.theme);
      case 'small':
      default:
        return styles.wrapSmall(this.theme);
    }
  };
  return Button;
}(React.Component), _Button.__KONTUR_REACT_UI__ = 'Button', _Button.displayName = 'Button', _Button.__BUTTON__ = true, _Button.defaultProps = {
  use: 'default',
  // By default, the type attribute is 'submit'. IE8 will fire a click event
  // on this button if somewhere on the page user presses Enter while some
  // input is focused. So we set type to 'button' by default.
  type: 'button',
  component: BUTTON_DEFAULT_COMPONENT
}, _Button)) || _class) || _class;