import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized";
import _inherits from "@babel/runtime/helpers/esm/inherits";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";

/**
 * Affix.jsx
 *
 * @Author: zhangce
 * @Date: 18/3/23 下午4:20
 */
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

var getElementLeft = function getElementLeft(element) {
  var actualLeft = element.offsetLeft;
  var current = element.offsetParent;

  while (current !== null) {
    actualLeft += current.offsetLeft;
    current = current.offsetParent;
  }

  return actualLeft;
};

var getElementTop = function getElementTop(element) {
  var actualTop = element.offsetTop;
  var current = element.offsetParent;

  while (current !== null) {
    actualTop += current.offsetTop;
    current = current.offsetParent;
  }

  return actualTop;
};
/**
 * Affix
 * */


var Affix =
/*#__PURE__*/
function (_React$PureComponent) {
  _inherits(Affix, _React$PureComponent);

  function Affix(props, context) {
    var _this;

    _classCallCheck(this, Affix);

    _this = _possibleConstructorReturn(this, _getPrototypeOf(Affix).call(this, props, context));

    _defineProperty(_assertThisInitialized(_this), "handleTargetScroll", function () {
      if (!_this.affix) {
        return;
      }

      var _this$props = _this.props,
          offsetTop = _this$props.offsetTop,
          offsetBottom = _this$props.offsetBottom;
      var isWindowContainer = _this.targetEle === window;
      var affixHeight = _this.affix.clientHeight;
      var affixClientWidth = _this.affix.clientWidth;
      var scrollTop = isWindowContainer ? document.documentElement.scrollTop : _this.targetEle.scrollTop;
      var targetOffsetHeight = window.frameElement ? window.frameElement.offsetHeight : document.documentElement.clientHeight;
      var condition;
      var style = {
        position: 'fixed',
        left: getElementLeft(_this.affix),
        zIndex: 10
      };

      if (offsetBottom === void 0) {
        condition = scrollTop > getElementTop(_this.affix) - offsetTop;
        style.top = isWindowContainer ? offsetTop : getElementTop(_this.targetEle) + offsetTop;
      } else {
        condition = targetOffsetHeight - (getElementTop(_this.affix) - scrollTop) - affixHeight <= offsetBottom;
        style.bottom = isWindowContainer ? offsetBottom : getElementTop(_this.targetEle) + _this.targetEle.offsetHeight - _this.affix.offsetHeight - offsetBottom;
      }

      if (condition) {
        _this.setState({
          style: style,
          containerStyle: {
            width: affixClientWidth,
            height: affixHeight
          },
          affixed: true
        });
      } else {
        _this.setState({
          style: {},
          containerStyle: {},
          affixed: false
        });
      }
    });

    _this.state = {
      style: {},
      containerStyle: {},
      affixed: false
    };
    return _this;
  }

  _createClass(Affix, [{
    key: "componentDidMount",
    value: function componentDidMount() {
      var target = this.props.target;
      this.targetEle = target();
      this.targetEle.addEventListener('scroll', this.handleTargetScroll, false);
      this.handleTargetScroll();
    }
  }, {
    key: "componentDidUpdate",
    value: function componentDidUpdate(prevProps, prevState) {
      var onChange = this.props.onChange;

      if (prevState.affixed !== this.state.affixed) {
        onChange && onChange(this.state.affixed);
      }
    }
  }, {
    key: "render",
    value: function render() {
      var _this2 = this;

      var _this$props2 = this.props,
          children = _this$props2.children,
          offsetBottom = _this$props2.offsetBottom,
          offsetTop = _this$props2.offsetTop,
          target = _this$props2.target,
          onChange = _this$props2.onChange,
          prefixCls = _this$props2.prefixCls,
          other = _objectWithoutProperties(_this$props2, ["children", "offsetBottom", "offsetTop", "target", "onChange", "prefixCls"]);

      var _this$state = this.state,
          style = _this$state.style,
          containerStyle = _this$state.containerStyle,
          affixed = _this$state.affixed;
      var classStr = classNames(_defineProperty({}, prefixCls, affixed));
      return React.createElement("div", _extends({
        style: containerStyle,
        ref: function ref(_ref) {
          return _this2.affix = _ref;
        }
      }, other), React.createElement("div", {
        className: classStr,
        style: style
      }, children));
    }
  }]);

  return Affix;
}(React.PureComponent);

_defineProperty(Affix, "displayName", 'NeatUI.Affix');

_defineProperty(Affix, "propTypes", {
  /**
   * 距离窗口底部达到指定偏移量后触发
   * */
  offsetBottom: PropTypes.number,

  /**
   * 距离窗口顶部达到指定偏移量后触发
   * */
  offsetTop: PropTypes.number,

  /**
   * 设置 `Affix` 需要监听其滚动事件的元素，值为一个返回对应 DOM 元素的函数
   * */
  target: PropTypes.func,

  /**
   * 固定状态改变时触发的回调函数
   * */
  onChange: PropTypes.func
});

_defineProperty(Affix, "defaultProps", {
  prefixCls: 'ne-affix',
  offsetTop: 0,
  target: function target() {
    return window;
  }
});

export default Affix;