import _sliceInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/slice";
import _Array$from from "@babel/runtime-corejs3/core-js-stable/array/from";
import _Symbol from "@babel/runtime-corejs3/core-js-stable/symbol";
import _getIteratorMethod from "@babel/runtime-corejs3/core-js/get-iterator-method";
import _typeof from "@babel/runtime-corejs3/helpers/typeof";
import _extends from "@babel/runtime-corejs3/helpers/extends";
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof _Symbol && _getIteratorMethod(r) || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
function _unsupportedIterableToArray(r, a) { if (r) { var _context; if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = _sliceInstanceProperty(_context = {}.toString.call(r)).call(_context, 8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? _Array$from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
import _Set from "@babel/runtime-corejs3/core-js-stable/set";
import _Object$is from "@babel/runtime-corejs3/core-js-stable/object/is";
import _Object$keys from "@babel/runtime-corejs3/core-js-stable/object/keys";
import { asyncScheduler, BehaviorSubject, defer, fromEvent, Subscription } from 'rxjs';
import { map, throttleTime } from 'rxjs/operators';
import ResizeObserver from 'resize-observer-polyfill';
import * as styledComponents from 'styled-components';
import cssVars from 'css-vars-ponyfill';
import mergeCellProps from '../utils/mergeCellProps';
import { isStickyUIDegrade } from '../utils';
import { defaultCSSVariables } from './styles';
import { hasScroll } from '../utils/element';
/** styled-components 类库的版本，ali-react-table 同时支持 v3 和 v5 */
export var STYLED_VERSION = styledComponents.createGlobalStyle != null ? 'v5' : 'v3';
export var STYLED_REF_PROP = STYLED_VERSION === 'v3' ? 'innerRef' : 'ref';
export var OVERSCAN_SIZE = 100;
export var AUTO_VIRTUAL_THRESHOLD = 100;
export function sum(arr) {
  var result = 0;
  arr.forEach(function (x) {
    result += x;
  });
  return result;
}
// 使用 defer 避免过早引用 window，导致在 SSR 场景下报错
export var throttledWindowResize$ = defer(function () {
  return fromEvent(window, 'resize', {
    passive: true
  }).pipe(throttleTime(150, asyncScheduler, {
    leading: true,
    trailing: true
  }));
});
export var addResizeObserver = function addResizeObserver(element, handler) {
  var measure = function measure(entries) {
    if (!entries[0] || !entries[0].contentRect) {
      return;
    }
    var contentRect = entries[0].contentRect;
    var hide = contentRect.width === 0 && contentRect.height === 0; // 隐藏条件：高宽都为0
    var rect = _extends({
      hide: hide
    }, contentRect);
    handler && handler(rect);
  };
  var resizeObserver = new ResizeObserver(measure);
  resizeObserver && resizeObserver.observe(element);
  return resizeObserver;
};
/** 获取默认的滚动条大小 */
function getScrollbarSizeImpl() {
  var scrollDiv = document.createElement('div');
  scrollDiv.style.position = 'absolute';
  scrollDiv.style.width = '100px';
  scrollDiv.style.height = '100px';
  scrollDiv.style.overflow = 'scroll';
  scrollDiv.style.top = '-9999px';
  document.body.appendChild(scrollDiv);
  var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
  var scrollbarHeight = scrollDiv.offsetHeight - scrollDiv.clientHeight;
  document.body.removeChild(scrollDiv);
  return {
    width: scrollbarWidth,
    height: scrollbarHeight
  };
}
var scrollBarSize$;
export function getScrollbarSize() {
  if (scrollBarSize$ == null) {
    scrollBarSize$ = new BehaviorSubject(getScrollbarSizeImpl());
    throttledWindowResize$.pipe(map(function () {
      return getScrollbarSizeImpl();
    })).subscribe(scrollBarSize$);
  }
  return scrollBarSize$.value;
}
/** 同步多个元素之间的 scrollLeft, 每当 scrollLeft 发生变化时 callback 会被调用 */
export function syncScrollLeft(elements, callback) {
  var bypassSet = new _Set();
  function publishScrollLeft(origin, scrollLeft) {
    bypassSet.clear();
    var _iterator = _createForOfIteratorHelper(elements),
      _step;
    try {
      for (_iterator.s(); !(_step = _iterator.n()).done;) {
        var elem = _step.value;
        if (elem === origin) {
          continue;
        }
        elem.scrollLeft = scrollLeft;
        bypassSet.add(elem);
      }
    } catch (err) {
      _iterator.e(err);
    } finally {
      _iterator.f();
    }
  }
  var subscription = new Subscription();
  var _iterator2 = _createForOfIteratorHelper(elements),
    _step2;
  try {
    var _loop = function _loop() {
      var ele = _step2.value;
      var listener = function listener() {
        if (bypassSet.has(ele)) {
          bypassSet.delete(ele);
          return;
        }
        var scrollLeft = ele.scrollLeft;
        // 某一元素当滚动条消失时会触发scroll事件（scrolLeft重置为0），不同步其他其他元素的scrollLeft
        if (scrollLeft === 0 && !hasScroll(ele)) {
          return;
        }
        publishScrollLeft(ele, scrollLeft);
        callback(scrollLeft);
      };
      ele.addEventListener('scroll', listener, {
        passive: true
      });
      subscription.add(function () {
        return ele.removeEventListener('scroll', listener);
      });
    };
    for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
      _loop();
    }
  } catch (err) {
    _iterator2.e(err);
  } finally {
    _iterator2.f();
  }
  return subscription;
}
/**
 * Performs equality by iterating through keys on an object and returning false
 * when any key has values which are not strictly equal between the arguments.
 * Returns true when the values of all keys are strictly equal.
 */
export function shallowEqual(objA, objB) {
  var hasOwnProperty = Object.prototype.hasOwnProperty;
  if (_Object$is(objA, objB)) {
    return true;
  }
  if (_typeof(objA) !== 'object' || objA === null || _typeof(objB) !== 'object' || objB === null) {
    return false;
  }
  var keysA = _Object$keys(objA);
  var keysB = _Object$keys(objB);
  if (keysA.length !== keysB.length) {
    return false;
  }
  // Test for A's keys different from B.
  for (var i = 0; i < keysA.length; i++) {
    if (!hasOwnProperty.call(objB, keysA[i]) || !_Object$is(objA[keysA[i]], objB[keysA[i]])) {
      return false;
    }
  }
  return true;
}
// todo: 抽出mergeRowProps
export function composeRowPropsGetter(getRowProps, pendingRowProps) {
  var keys = _Object$keys(pendingRowProps);
  if (keys.length) {
    return function (row, rowIndex) {
      return mergeCellProps(getRowProps(row, rowIndex), pendingRowProps);
    };
  }
  return getRowProps;
}
export function getTableScrollHeaderDOM(domHelper) {
  return isStickyUIDegrade() ? domHelper.tableHeaderMain : domHelper.tableHeader;
}
export function getTableScrollFooterDOM(domHelper) {
  return isStickyUIDegrade() ? domHelper.tableFooterMain : domHelper.tableFooter;
}
export var cssPolifill = function cssPolifill(_ref) {
  var variables = _ref.variables,
    enableCSSVariables = _ref.enableCSSVariables,
    bordered = _ref.bordered;
  if (enableCSSVariables === false) {
    return;
  }
  var conditionCSSVariables = {};
  // 默认情况下存在td、th无左右边框，开启`bordered`属性后才开启，否则隐藏这两种属性
  if (!bordered) {
    conditionCSSVariables['--cell-border-vertical'] = 'none';
    conditionCSSVariables['--header-cell-border-vertical'] = 'none';
  }
  cssVars({
    // exclude: 'link[href*="semantic-ui"]',
    // onlyLegacy: false,
    // rootElement: rootElement,
    include: 'style[data-styled]',
    variables: _extends({}, defaultCSSVariables, variables, conditionCSSVariables),
    watch: true,
    silent: true
  });
};