import _extends from "@babel/runtime/helpers/extends";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
import _objectSpread from "@babel/runtime/helpers/objectSpread2";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _get from "@babel/runtime/helpers/get";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/inherits";
import _createSuper from "@babel/runtime/helpers/createSuper";
import _typeof from "@babel/runtime/helpers/typeof";
import _regeneratorRuntime from "@babel/runtime/regenerator";
import { __decorate } from "tslib";
import React, { Children } from 'react';
import classNames from 'classnames';
import omit from 'lodash/omit';
import noop from 'lodash/noop';
import debounce from 'lodash/debounce';
import isString from 'lodash/isString';
import { computed, observable, runInAction, action, isArrayLike } from 'mobx';
import { observer } from 'mobx-react';
import isPromise from 'is-promise';
import { isFragment as isReactFragment } from 'react-is';
import { ProgressType } from '../../../es/progress/enum';
import Icon from '../icon';
import FormContext from '../form/FormContext';
import Progress from '../progress';
import Ripple from '../ripple';
import { ButtonTooltip, ButtonType, FuncType } from './enum';
import { DataSetStatus } from '../data-set/enum';
import { Size, WaitType } from '../core/enum';
import DataSetComponent from '../data-set/DataSetComponent';
import autobind from '../_util/autobind';
import { hide, show } from '../tooltip/singleton';
import isOverflow from '../overflow-tip/util';
import getReactNodeText from '../_util/getReactNodeText';
import { cloneElement } from '../_util/reactNode';
var rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/;
var isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar); // Insert one space between two chinese characters automatically.

function insertSpace(child, needInserted) {
  // Check the child if is undefined or null.
  if (child == null) {
    return;
  }

  var SPACE = needInserted ? ' ' : ''; // strictNullChecks oops.

  if (typeof child !== 'string' && typeof child !== 'number' && isString(child.type) && isTwoCNChar(child.props.children)) {
    return cloneElement(child, {
      children: child.props.children.split('').join(SPACE)
    });
  }

  if (typeof child === 'string') {
    return isTwoCNChar(child) ? /*#__PURE__*/React.createElement("span", null, child.split('').join(SPACE)) : /*#__PURE__*/React.createElement("span", null, child);
  }

  if (isReactFragment(child)) {
    return /*#__PURE__*/React.createElement("span", null, child);
  }

  return child;
}

function spaceChildren(children, needInserted) {
  var isPrevChildPure = false;
  var childList = [];
  React.Children.forEach(children, function (child) {
    var type = _typeof(child);

    var isCurrentChildPure = type === 'string' || type === 'number';

    if (isPrevChildPure && isCurrentChildPure) {
      var lastIndex = childList.length - 1;
      var lastChild = childList[lastIndex];
      childList[lastIndex] = "".concat(lastChild).concat(child);
    } else {
      childList.push(child);
    }

    isPrevChildPure = isCurrentChildPure;
  }); // Pass to React.Children.map to auto fill key

  return React.Children.map(childList, function (child) {
    return insertSpace(child, needInserted);
  });
}

var Button = /*#__PURE__*/function (_DataSetComponent) {
  _inherits(Button, _DataSetComponent);

  var _super = _createSuper(Button);

  function Button(props, context) {
    var _this;

    _classCallCheck(this, Button);

    _this = _super.call(this, props, context);
    _this.handleClickWait = _this.getHandleClick(props);
    return _this;
  }

  _createClass(Button, [{
    key: "loading",
    get: function get() {
      var _this$observableProps = this.observableProps,
          type = _this$observableProps.type,
          dataSet = _this$observableProps.dataSet,
          loading = _this$observableProps.loading;
      return loading || type === ButtonType.submit && !!dataSet && dataSet.status === DataSetStatus.submitting;
    },
    set: function set(loading) {
      var _this2 = this;

      runInAction(function () {
        _this2.observableProps.loading = loading;
      });
    }
  }, {
    key: "getObservableProps",
    value: function getObservableProps(props, context) {
      return _objectSpread(_objectSpread({}, _get(_getPrototypeOf(Button.prototype), "getObservableProps", this).call(this, props, context)), {}, {
        dataSet: 'dataSet' in props ? props.dataSet : context.dataSet,
        loading: 'loading' in props ? props.loading : this.observableProps ? this.observableProps.loading : false,
        type: props.type,
        disabled: context.disabled || props.disabled
      });
    }
  }, {
    key: "fixTwoCNChar",
    value: function fixTwoCNChar() {
      // For HOC usage
      var autoInsertSpace = this.getContextConfig('autoInsertSpaceInButton') !== false;

      if (!this.element || !autoInsertSpace) {
        return;
      }

      var buttonText = this.element.textContent;

      if (this.isNeedInserted() && isTwoCNChar(buttonText)) {
        if (!this.hasTwoCNChar) {
          this.hasTwoCNChar = true;
        }
      } else if (this.hasTwoCNChar) {
        this.hasTwoCNChar = false;
      }
    }
  }, {
    key: "componentDidMount",
    value: function componentDidMount() {
      _get(_getPrototypeOf(Button.prototype), "componentDidMount", this).call(this);

      this.fixTwoCNChar();
    }
  }, {
    key: "componentWillReceiveProps",
    value: function componentWillReceiveProps(nextProps, nextContext) {
      _get(_getPrototypeOf(Button.prototype), "componentWillReceiveProps", this).call(this, nextProps, nextContext);

      var _this$props = this.props,
          wait = _this$props.wait,
          waitType = _this$props.waitType;

      if (wait !== nextProps.wait || waitType !== nextProps.waitType) {
        this.handleClickWait = this.getHandleClick(nextProps);
      }
    }
  }, {
    key: "componentWillUnmount",
    value: function componentWillUnmount() {
      this.handleClickWait.cancel();

      if (this.isTooltipShown) {
        hide();
        delete this.isTooltipShown;
      }
    }
  }, {
    key: "getHandleClick",
    value: function getHandleClick(props) {
      var wait = props.wait,
          waitType = props.waitType;

      if (wait && waitType) {
        var options = {
          leading: true,
          trailing: true
        };

        if (waitType === WaitType.throttle) {
          options.trailing = false;
          options.maxWait = wait;
        } else if (waitType === WaitType.debounce) {
          options.leading = false;
        }

        return debounce(this.handleClick, wait, options);
      }

      return debounce(this.handleClick, 0);
    }
  }, {
    key: "handleClickIfBubble",
    value: function handleClickIfBubble(e) {
      var _this$props2 = this.props,
          wait = _this$props2.wait,
          waitType = _this$props2.waitType;

      if (wait && waitType) {
        e.stopPropagation();
        this.handleClickWait(e);
      } else {
        this.handleClick(e);
      }
    }
  }, {
    key: "handleClick",
    value: function () {
      var _handleClick = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(e) {
        var onButtonClick, target, _this$props3, children, icon, promise, onClick, afterClick;

        return _regeneratorRuntime.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                onButtonClick = this.context.getConfig('onButtonClick');

                if (onButtonClick && e) {
                  target = e.target;
                  _this$props3 = this.props, children = _this$props3.children, icon = _this$props3.icon;
                  promise = Promise.resolve(target && target.textContent || getReactNodeText(children));
                  promise.then(function (title) {
                    return onButtonClick({
                      icon: icon,
                      title: title
                    });
                  });
                }

                onClick = this.props.onClick;

                if (!onClick) {
                  _context.next = 13;
                  break;
                }

                afterClick = onClick(e);

                if (!isPromise(afterClick)) {
                  _context.next = 13;
                  break;
                }

                _context.prev = 6;
                this.loading = true;
                _context.next = 10;
                return afterClick;

              case 10:
                _context.prev = 10;
                this.loading = false;
                return _context.finish(10);

              case 13:
              case "end":
                return _context.stop();
            }
          }
        }, _callee, this, [[6,, 10, 13]]);
      }));

      function handleClick(_x) {
        return _handleClick.apply(this, arguments);
      }

      return handleClick;
    }()
  }, {
    key: "handleMouseEnter",
    value: function handleMouseEnter(e) {
      var _this$context = this.context,
          getTooltip = _this$context.getTooltip,
          getTooltipTheme = _this$context.getTooltipTheme,
          getTooltipPlacement = _this$context.getTooltipPlacement;
      var _this$props4 = this.props,
          _this$props4$tooltip = _this$props4.tooltip,
          tooltip = _this$props4$tooltip === void 0 ? getTooltip('button') : _this$props4$tooltip,
          children = _this$props4.children;
      var element = this.element;

      if (tooltip === ButtonTooltip.always || tooltip === ButtonTooltip.overflow && isOverflow(element)) {
        show(element, {
          title: children,
          theme: getTooltipTheme('button'),
          placement: getTooltipPlacement('button')
        });
        this.isTooltipShown = true;
      } else if (isArrayLike(tooltip)) {
        var tooltipType = tooltip[0];
        var buttonTooltipProps = tooltip[1] || {};
        var duration = (buttonTooltipProps.mouseEnterDelay || 0.1) * 1000;

        if (tooltipType === ButtonTooltip.always || tooltipType === ButtonTooltip.overflow && isOverflow(element)) {
          show(element, _objectSpread({
            theme: getTooltipTheme('button'),
            placement: getTooltipPlacement('button'),
            title: buttonTooltipProps.title ? buttonTooltipProps.title : children
          }, buttonTooltipProps), duration);
          this.isTooltipShown = true;
        }
      }

      var _this$props$onMouseEn = this.props.onMouseEnter,
          onMouseEnter = _this$props$onMouseEn === void 0 ? noop : _this$props$onMouseEn;
      onMouseEnter(e);
    }
  }, {
    key: "handleMouseLeave",
    value: function handleMouseLeave(e) {
      var getTooltip = this.context.getTooltip;
      var _this$props$tooltip = this.props.tooltip,
          tooltip = _this$props$tooltip === void 0 ? getTooltip('button') : _this$props$tooltip;

      if (isArrayLike(tooltip)) {
        var buttonTooltipProps = tooltip[1] || {};
        var duration = (buttonTooltipProps.mouseLeaveDelay || 0.1) * 1000;
        hide(duration);
      } else {
        hide();
      }

      var _this$props$onMouseLe = this.props.onMouseLeave,
          onMouseLeave = _this$props$onMouseLe === void 0 ? noop : _this$props$onMouseLe;
      onMouseLeave(e);
    }
  }, {
    key: "getOmitPropsKeys",
    value: function getOmitPropsKeys() {
      return _get(_getPrototypeOf(Button.prototype), "getOmitPropsKeys", this).call(this).concat(['icon', 'funcType', 'color', 'loading', 'wait', 'waitType', 'tooltip', 'block', 'onClick']);
    }
  }, {
    key: "getOtherProps",
    value: function getOtherProps() {
      var otherProps = _get(_getPrototypeOf(Button.prototype), "getOtherProps", this).call(this);

      var getTooltip = this.context.getTooltip;
      var _this$props$tooltip2 = this.props.tooltip,
          tooltip = _this$props$tooltip2 === void 0 ? getTooltip('button') : _this$props$tooltip2;

      if (!this.disabled && !this.loading) {
        otherProps.onClick = this.handleClickIfBubble;
      }

      if (isString(tooltip) && [ButtonTooltip.always, ButtonTooltip.overflow].includes(tooltip) || isArrayLike(tooltip) && [ButtonTooltip.always, ButtonTooltip.overflow].includes(tooltip[0])) {
        otherProps.onMouseEnter = this.handleMouseEnter;
        otherProps.onMouseLeave = this.handleMouseLeave;
      }

      return otherProps;
    }
  }, {
    key: "isNeedInserted",
    value: function isNeedInserted() {
      var _this$props5 = this.props,
          _this$props5$funcType = _this$props5.funcType,
          funcType = _this$props5$funcType === void 0 ? this.getContextConfig('buttonFuncType') : _this$props5$funcType,
          children = _this$props5.children,
          icon = _this$props5.icon;
      return Children.count(children) === 1 && !icon && !(funcType === FuncType.link || funcType === FuncType.flat);
    }
  }, {
    key: "getClassName",
    value: function getClassName() {
      var _get2, _ref;

      var prefixCls = this.prefixCls,
          _this$props6 = this.props,
          _this$props6$color = _this$props6.color,
          color = _this$props6$color === void 0 ? this.getContextConfig('buttonColor') : _this$props6$color,
          _this$props6$funcType = _this$props6.funcType,
          funcType = _this$props6$funcType === void 0 ? this.getContextConfig('buttonFuncType') : _this$props6$funcType,
          children = _this$props6.children,
          icon = _this$props6.icon,
          block = _this$props6.block;
      var childrenCount = Children.count(children);
      var autoInsertSpace = this.getContextConfig('autoInsertSpaceInButton') !== false;

      for (var _len = arguments.length, props = new Array(_len), _key = 0; _key < _len; _key++) {
        props[_key] = arguments[_key];
      }

      return (_get2 = _get(_getPrototypeOf(Button.prototype), "getClassName", this)).call.apply(_get2, [this, (_ref = {}, _defineProperty(_ref, "".concat(prefixCls, "-").concat(funcType), funcType), _defineProperty(_ref, "".concat(prefixCls, "-").concat(color), color), _defineProperty(_ref, "".concat(prefixCls, "-icon-only"), icon ? childrenCount === 0 || children === false : childrenCount === 1 && children.type && children.type.__C7N_ICON), _defineProperty(_ref, "".concat(prefixCls, "-block"), block), _defineProperty(_ref, "".concat(prefixCls, "-loading"), this.loading), _defineProperty(_ref, "".concat(prefixCls, "-two-chinese-chars"), this.hasTwoCNChar && autoInsertSpace), _ref)].concat(props));
    }
  }, {
    key: "render",
    value: function render() {
      var _this$props7 = this.props,
          children = _this$props7.children,
          icon = _this$props7.icon,
          href = _this$props7.href,
          funcType = _this$props7.funcType;
      var loading = this.loading,
          disabled = this.disabled;
      var autoInsertSpace = this.getContextConfig('autoInsertSpaceInButton') !== false;
      var buttonIcon = loading ? /*#__PURE__*/React.createElement(Progress, {
        key: "loading",
        type: ProgressType.loading,
        size: Size.small
      }) : icon && /*#__PURE__*/React.createElement(Icon, {
        type: icon
      });
      var hasString = Children.toArray(children).some(function (child) {
        return isString(child);
      });
      var Cmp = href ? 'a' : 'button';
      var props = this.getMergedProps();
      var onMouseEnter = props.onMouseEnter,
          onMouseLeave = props.onMouseLeave;
      var tooltipWrapper = disabled && !href && (onMouseEnter || onMouseLeave);
      var omits = [];

      if (tooltipWrapper) {
        omits.push('className', 'style');
      }

      if (href) {
        omits.push('type');

        if (disabled || loading) {
          omits.push('href');
        }
      }

      var kids = children || children === 0 ? spaceChildren(children, this.isNeedInserted() && autoInsertSpace) : null;
      var button = /*#__PURE__*/React.createElement(Ripple, {
        disabled: disabled || funcType === FuncType.link
      }, /*#__PURE__*/React.createElement(Cmp, _extends({}, omit(props, omits)), buttonIcon, hasString ? /*#__PURE__*/React.createElement("span", null, kids) : kids));
      return tooltipWrapper ? /*#__PURE__*/React.createElement("span", {
        className: classNames(props.className, "".concat(this.prefixCls, "-disabled-wrapper")),
        style: props.style,
        onMouseEnter: onMouseEnter,
        onMouseLeave: onMouseLeave
      }, button) : button;
    }
  }], [{
    key: "contextType",
    get: function get() {
      return FormContext;
    }
  }]);

  return Button;
}(DataSetComponent);

Button.displayName = 'Button'; // eslint-disable-next-line camelcase

Button.__PRO_BUTTON = true;
Button.defaultProps = {
  suffixCls: 'btn',
  type: ButtonType.button,
  waitType: WaitType.throttle
};

__decorate([observable], Button.prototype, "hasTwoCNChar", void 0);

__decorate([computed], Button.prototype, "loading", null);

__decorate([autobind, action], Button.prototype, "fixTwoCNChar", null);

__decorate([autobind], Button.prototype, "handleClickIfBubble", null);

__decorate([autobind], Button.prototype, "handleClick", null);

__decorate([autobind], Button.prototype, "handleMouseEnter", null);

__decorate([autobind], Button.prototype, "handleMouseLeave", null);

Button = __decorate([observer], Button);
export default Button;
//# sourceMappingURL=Button.js.map
