"use strict";

function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;
var _react = _interopRequireWildcard(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _lodash = _interopRequireDefault(require("lodash.debounce"));
var _web = require("@react-spring/web");
var _box = _interopRequireDefault(require("../box"));
var _resize = _interopRequireDefault(require("../resize"));
var _edit = _interopRequireDefault(require("../edit"));
require("./index.css");
var _focus = _interopRequireDefault(require("../../focus"));
var _mutationObserver = _interopRequireDefault(require("../../mutation-observer"));
var _scrollbar = _interopRequireDefault(require("../../scrollbar"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var preCls = 'titaui-super-table';
var getPinnedLeft = function getPinnedLeft(currentIndex, columns) {
  return columns.slice(0, currentIndex).reduce(function (pre, cur) {
    return pre + cur._width;
  }, 0);
};
var getPinnedRight = function getPinnedRight(currentIndex, columns) {
  return columns.slice(currentIndex + 1).reduce(function (pre, cur) {
    return pre + cur._width;
  }, 0);
};
var getPinnedOption = function getPinnedOption(columns, currentIndex, pinned) {
  var columnsLength = columns.length;
  if (!pinned) return {
    isPinned: false,
    pinnedStyle: {},
    pinnedIndex: [0, columnsLength - 1]
  };

  // 这里是计算要被固定列的边界下标
  // 比如 pinned 设置了 [1, 1]，这就代表要固定第一列和最后一列，边界下标也就是第一列和最后一列的下标
  // 左侧要被固定的最后一列的下标
  var leftIndex = pinned[0] - 1;
  // 右侧要被固定的第一列的下标
  var rightIndex = columnsLength - (pinned[1] || 0);
  var result = {
    isPinned: true,
    pinnedStyle: {},
    pinnedIndex: [leftIndex, rightIndex]
  };
  if (currentIndex <= leftIndex) {
    result.pinnedStyle = {
      position: 'sticky',
      left: getPinnedLeft(currentIndex, columns)
    };
    return result;
  }
  if (currentIndex >= rightIndex) {
    result.pinnedStyle = {
      position: 'sticky',
      right: getPinnedRight(currentIndex, columns)
    };
    return result;
  }
  return {
    isPinned: false,
    pinnedStyle: {},
    pinnedIndex: [0, columnsLength - 1]
  };
};
var fillWidth = function fillWidth(columns, offsetWidth) {
  var columnsTotalWidth = columns.reduce(function (width, curr) {
    return (curr.hidden ? 0 : curr.width || 0) + width;
  }, 0);

  // 剩余的宽度
  var surplusWidth = offsetWidth - columnsTotalWidth;

  // 将没有设置宽度的列均分，如果均分
  // 没有设置宽度的个数
  var unWidthColumnNum = columns.filter(function (_ref) {
    var width = _ref.width;
    return !width;
  }).length;
  // 平均值
  var columnWidth = surplusWidth / unWidthColumnNum;
  if (columnWidth < 118) columnWidth = 118;
  return columns.map(function (item) {
    var _width = columnWidth;
    if (item.width) _width = item.width;
    if (item.minWidth && item.minWidth > _width) _width = item.minWidth;
    return _objectSpread(_objectSpread({}, item), {}, {
      _width: _width
    });
  });
};
var getFormatColumns = function getFormatColumns(columns, offsetWidth, pinned) {
  var showColumnOptions = columns.filter(function (columnOption) {
    return !columnOption.hidden;
  });
  var formatColumns = fillWidth(showColumnOptions, offsetWidth).map(function (columnOption, colIndex) {
    var _getPinnedOption = getPinnedOption(showColumnOptions, colIndex, pinned),
      pinnedStyle = _getPinnedOption.pinnedStyle,
      pinnedIndex = _getPinnedOption.pinnedIndex,
      isPinned = _getPinnedOption.isPinned;
    return _objectSpread(_objectSpread({}, columnOption), {}, {
      pinnedStyle: pinnedStyle,
      isPinned: isPinned,
      pinnedIndex: pinnedIndex
    });
  });
  return formatColumns;
};
var SuperTable = /*#__PURE__*/(0, _react.forwardRef)(function (_ref2, ref) {
  var _classNames;
  var className = _ref2.className,
    style = _ref2.style,
    height = _ref2.height,
    columns = _ref2.columns,
    dataSource = _ref2.dataSource,
    showEdit = _ref2.showEdit,
    _ref2$showInsert = _ref2.showInsert,
    showInsert = _ref2$showInsert === void 0 ? true : _ref2$showInsert,
    onChangeTitle = _ref2.onChangeTitle,
    onAddColumn = _ref2.onAddColumn,
    onRemoveColumn = _ref2.onRemoveColumn,
    onColumnResize = _ref2.onColumnResize,
    pinned = _ref2.pinned,
    rowKey = _ref2.rowKey,
    pinnedHeader = _ref2.pinnedHeader;
  var scrollRef = (0, _react.useRef)();
  var headTrRef = (0, _react.useRef)();
  var _useState = (0, _react.useState)(0),
    _useState2 = _slicedToArray(_useState, 2),
    scrollHeight = _useState2[0],
    setScrollHeight = _useState2[1];
  (0, _react.useImperativeHandle)(ref, function () {
    return {
      focusTitle: function focusTitle(index) {
        var columnTh = headTrRef.current.querySelectorAll('th')[index];
        var input = columnTh.querySelector('input');
        input === null || input === void 0 ? void 0 : input.focus();
      }
    };
  });
  var _useState3 = (0, _react.useState)([]),
    _useState4 = _slicedToArray(_useState3, 2),
    formatColumns = _useState4[0],
    setFormatColumns = _useState4[1];
  var resizeAnimated = function resizeAnimated(formatColumns) {
    colSizesApi.start(function (i) {
      var _formatColumns$i;
      return {
        width: ((_formatColumns$i = formatColumns[i]) === null || _formatColumns$i === void 0 ? void 0 : _formatColumns$i._width) || 0
      };
    });
    tableWidthApi.start({
      width: formatColumns.reduce(function (prevWidth, currColumn) {
        return prevWidth + currColumn._width;
      }, 0)
    });
  };
  (0, _react.useEffect)(function () {
    if (scrollRef.current && scrollRef.current.getScrollWrapperEl) {
      var _scrollRef$current$ge = scrollRef.current.getScrollWrapperEl(),
        scrollLeft = _scrollRef$current$ge.scrollLeft,
        offsetWidth = _scrollRef$current$ge.offsetWidth,
        scrollWidth = _scrollRef$current$ge.scrollWidth;
      setShowPinnedRightShadow(scrollLeft < scrollWidth - offsetWidth);
      var _formatColumns = getFormatColumns(columns, offsetWidth, pinned);
      setFormatColumns(_formatColumns);
      resizeAnimated(_formatColumns);
    }
  }, [scrollRef, columns]);
  (0, _react.useEffect)(function () {
    // 当列配置更新后，重设 scrollHeight
    var _scrollRef$current$ge2 = scrollRef.current.getScrollWrapperEl(),
      offsetHeight = _scrollRef$current$ge2.offsetHeight;
    setScrollHeight(offsetHeight);
    var onResize = (0, _lodash["default"])(function onResize() {
      var _scrollRef$current$ge3 = scrollRef.current.getScrollWrapperEl(),
        offsetWidth = _scrollRef$current$ge3.offsetWidth;
      setTimeout(function () {
        var _scrollRef$current$ge4 = scrollRef.current.getScrollWrapperEl(),
          offsetHeight = _scrollRef$current$ge4.offsetHeight;
        // 宽度改变后，内容高度有可能发生变化，需要重设 scrollHeight
        setScrollHeight(Math.max(offsetHeight));
      }, 500);
      var newFormatColumnOptions = fillWidth(formatColumns, offsetWidth);
      resizeAnimated(newFormatColumnOptions);
      setFormatColumns(newFormatColumnOptions);
    }, 200);
    window.addEventListener('resize', onResize);
    return function () {
      window.removeEventListener('resize', onResize);
    };
  }, [formatColumns]);

  // 列宽
  var _useSprings = (0, _web.useSprings)(formatColumns.length, function (i) {
      return {
        width: formatColumns[i]._width
      };
    }),
    _useSprings2 = _slicedToArray(_useSprings, 2),
    colSizes = _useSprings2[0],
    colSizesApi = _useSprings2[1];
  // 表格总宽
  var _useSpring = (0, _web.useSpring)(function () {
      return {
        width: formatColumns.reduce(function (width, curr) {
          return (curr.hidden ? 0 : curr._width) + width;
        }, 0)
      };
    }),
    _useSpring2 = _slicedToArray(_useSpring, 2),
    tableWidth = _useSpring2[0],
    tableWidthApi = _useSpring2[1];
  // 当前选中列的索引
  var _useState5 = (0, _react.useState)(),
    _useState6 = _slicedToArray(_useState5, 2),
    selectedColIndex = _useState6[0],
    setSelectedColIndex = _useState6[1];

  // 列宽变化事件
  var onColumnResizeHandler = (0, _react.useCallback)(function (columnsWidth, colIndex, last) {
    tableWidthApi.start({
      width: columnsWidth.reduce(function (prevWidth, currWidth) {
        return prevWidth + currWidth;
      })
    });
    colSizesApi.start(function (i) {
      return {
        width: columnsWidth[i]
      };
    });
    if (last) {
      setFormatColumns(formatColumns.map(function (columnItem, i) {
        // 如果当前列有设置宽度 | columnItem 为当前被拖动的列
        // 当列被拖动后，页面重新 resize 时，不希望它被自动分配宽度，而是使用用户拖动后的宽度
        if (columnItem.width || i === colIndex) {
          return _objectSpread(_objectSpread({}, columnItem), {}, {
            width: columnsWidth[i],
            _width: columnsWidth[i]
          });
        }
        return _objectSpread(_objectSpread({}, columnItem), {}, {
          _width: columnsWidth[i]
        });
      }));
      if (onColumnResize) onColumnResize(colIndex, columnsWidth[colIndex]);
    }
  }, [formatColumns]);
  var _useState7 = (0, _react.useState)(false),
    _useState8 = _slicedToArray(_useState7, 2),
    showHeaderShadow = _useState8[0],
    setShowHeaderShadow = _useState8[1];
  var _useState9 = (0, _react.useState)(false),
    _useState10 = _slicedToArray(_useState9, 2),
    showPinnedLeftShadow = _useState10[0],
    setShowPinnedLeftShadow = _useState10[1];
  var _useState11 = (0, _react.useState)(false),
    _useState12 = _slicedToArray(_useState11, 2),
    showPinnedRightShadow = _useState12[0],
    setShowPinnedRightShadow = _useState12[1];
  var _useState13 = (0, _react.useState)(0),
    _useState14 = _slicedToArray(_useState13, 2),
    columnEditBarOffsetX = _useState14[0],
    setColumnEditBarOffsetX = _useState14[1];
  var onScrollContentHandler = (0, _react.useCallback)(function (e) {
    // @ts-ignore
    var _ref3 = e.target,
      scrollLeft = _ref3.scrollLeft,
      offsetWidth = _ref3.offsetWidth,
      scrollWidth = _ref3.scrollWidth;
    setColumnEditBarOffsetX(scrollLeft);
    setShowPinnedLeftShadow(scrollLeft > 0);
    setShowPinnedRightShadow(scrollLeft < scrollWidth - offsetWidth);
    // @ts-ignore
    setShowHeaderShadow(e.target.scrollTop > 0);
  }, []);

  // hover 插入按钮
  var _useState15 = (0, _react.useState)(),
    _useState16 = _slicedToArray(_useState15, 2),
    hoverInsertBarIndex = _useState16[0],
    setHoverInsertBarIndex = _useState16[1];
  var _useState17 = (0, _react.useState)(false),
    _useState18 = _slicedToArray(_useState17, 2),
    editing = _useState18[0],
    setEditing = _useState18[1];
  return /*#__PURE__*/_react["default"].createElement(_focus["default"], {
    onFocus: setEditing,
    onBlur: setEditing,
    className: (0, _classnames["default"])(preCls, className),
    style: style,
    excludeClassName: ['titaui-popup']
  }, /*#__PURE__*/_react["default"].createElement(_edit["default"], {
    onAddColumn: onAddColumn,
    onRemoveColumn: onRemoveColumn,
    columnOptions: formatColumns,
    onHoverInsertBar: setHoverInsertBarIndex,
    onSelectColumn: setSelectedColIndex,
    colWidth: colSizes,
    showEdit: editing,
    showInsert: showInsert,
    offsetX: columnEditBarOffsetX
  }), /*#__PURE__*/_react["default"].createElement(_resize["default"], {
    height: scrollHeight,
    columnOptions: formatColumns,
    onColumnResize: onColumnResizeHandler,
    hoverInsertBarIndex: hoverInsertBarIndex,
    showEdit: showEdit,
    offsetX: columnEditBarOffsetX
  }), /*#__PURE__*/_react["default"].createElement(_mutationObserver["default"], null, /*#__PURE__*/_react["default"].createElement(_scrollbar["default"], {
    ref: scrollRef,
    className: "".concat(preCls, "__table-scroll"),
    style: {
      height: height
    },
    onScroll: onScrollContentHandler
  }, /*#__PURE__*/_react["default"].createElement(_web.animated.div, {
    className: "".concat(preCls, "__table-container"),
    style: {
      width: tableWidth.width
    }
  }, /*#__PURE__*/_react["default"].createElement("table", {
    className: "".concat(preCls, "__content")
  }, /*#__PURE__*/_react["default"].createElement("colgroup", null, colSizes.map(function (_ref4, i) {
    var width = _ref4.width;
    return /*#__PURE__*/_react["default"].createElement(_web.animated.col, {
      key: "".concat(i, "_").concat(formatColumns[i].title),
      style: {
        width: formatColumns[i].hidden ? 0 : width
      }
    });
  })), /*#__PURE__*/_react["default"].createElement("thead", {
    className: (0, _classnames["default"])("".concat(preCls, "__head"), (_classNames = {}, _defineProperty(_classNames, "".concat(preCls, "__head--pinnedHeader"), pinnedHeader), _defineProperty(_classNames, "".concat(preCls, "__head--shadow"), showHeaderShadow), _classNames))
  }, /*#__PURE__*/_react["default"].createElement("tr", {
    ref: headTrRef
  }, formatColumns.map(function (columnOption, colIndex) {
    var _classNames2;
    var title = columnOption.title,
      canEditTitle = columnOption.canEditTitle,
      pinnedStyle = columnOption.pinnedStyle,
      isPinned = columnOption.isPinned,
      pinnedIndex = columnOption.pinnedIndex;
    return /*#__PURE__*/_react["default"].createElement("th", {
      key: "".concat(colIndex, "_").concat(columnOption.title),
      className: (0, _classnames["default"])("".concat(preCls, "__head-item"), (_classNames2 = {}, _defineProperty(_classNames2, "".concat(preCls, "__head-item--active"), selectedColIndex === colIndex), _defineProperty(_classNames2, "".concat(preCls, "__head-item--canEdit"), canEditTitle), _defineProperty(_classNames2, "".concat(preCls, "__left-shadow"), isPinned && showPinnedLeftShadow && colIndex === pinnedIndex[0]), _defineProperty(_classNames2, "".concat(preCls, "__right-shadow"), isPinned && showPinnedRightShadow && colIndex === pinnedIndex[1]), _classNames2)),
      style: _objectSpread({}, pinnedStyle)
    }, canEditTitle ? /*#__PURE__*/_react["default"].createElement("input", {
      className: (0, _classnames["default"])("".concat(preCls, "__head-item__edit"), {}),
      defaultValue: title,
      onBlur: function onBlur(e) {
        return onChangeTitle && onChangeTitle(e.target.value, colIndex, columnOption);
      }
    }) : title);
  }))), /*#__PURE__*/_react["default"].createElement("tbody", null, dataSource.map(function (record, rowIdx) {
    return /*#__PURE__*/_react["default"].createElement("tr", {
      key: typeof rowKey === 'string' ? record[rowKey] : rowKey(record, rowIdx)
    }, formatColumns.map(function (columnOption, colIndex) {
      var _classNames3;
      return /*#__PURE__*/_react["default"].createElement(_box["default"], {
        key: "".concat(colIndex, "_").concat(columnOption.title),
        width: colSizes[colIndex].width,
        className: (0, _classnames["default"])("".concat(preCls, "__box"), (_classNames3 = {}, _defineProperty(_classNames3, "".concat(preCls, "__left-shadow"), columnOption.isPinned && showPinnedLeftShadow && colIndex === columnOption.pinnedIndex[0]), _defineProperty(_classNames3, "".concat(preCls, "__right-shadow"), columnOption.isPinned && showPinnedRightShadow && colIndex === columnOption.pinnedIndex[1]), _classNames3)),
        record: record,
        rowIdx: rowIdx,
        columnOption: columnOption,
        active: selectedColIndex === colIndex,
        style: _objectSpread({}, columnOption.pinnedStyle)
      });
    }));
  })))))));
});
var _default = /*#__PURE__*/_react["default"].memo(SuperTable);
exports["default"] = _default;