"use strict";

var _sliceInstanceProperty = require("@babel/runtime-corejs3/core-js-stable/instance/slice");

var _Array$from = require("@babel/runtime-corejs3/core-js-stable/array/from");

var _Symbol = require("@babel/runtime-corejs3/core-js-stable/symbol");

var _getIteratorMethod = require("@babel/runtime-corejs3/core-js/get-iterator-method");

var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exportTableAsExcel;

var _filter = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/filter"));

var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/map"));

var _SpanManager = _interopRequireDefault(require("../base/helpers/SpanManager"));

var _internals = require("../internals");

var _collectNodes = _interopRequireDefault(require("./collectNodes"));

var _getTreeDepth = _interopRequireDefault(require("./getTreeDepth"));

var _isLeafNode = _interopRequireDefault(require("./isLeafNode"));

function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof _Symbol !== "undefined" && _getIteratorMethod(o) || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, 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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }

function _unsupportedIterableToArray(o, minLen) { var _context2; if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = _sliceInstanceProperty(_context2 = Object.prototype.toString.call(o)).call(_context2, 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 safeGetSpanRect(column, record, rowIndex, colIndex) {
  var colSpan = 1;
  var rowSpan = 1;

  if (column.getSpanRect) {
    var value = _internals.internals.safeGetValue(column, record, rowIndex);

    var spanRect = column.getSpanRect(value, record, rowIndex);
    colSpan = spanRect == null ? 1 : spanRect.right - colIndex;
    rowSpan = spanRect == null ? 1 : spanRect.bottom - rowIndex;
  } else {
    var cellProps = _internals.internals.safeGetCellProps(column, record, rowIndex);

    if (cellProps.colSpan != null) {
      colSpan = cellProps.colSpan;
    }

    if (cellProps.rowSpan != null) {
      rowSpan = cellProps.rowSpan;
    }
  } // 注意这里没有考虑「rowSpan/colSpan 不能过大，避免 rowSpan/colSpan 影响因虚拟滚动而未渲染的单元格」


  return {
    top: rowIndex,
    bottom: rowIndex + rowSpan,
    left: colIndex,
    right: colIndex + colSpan
  };
}

function move(_ref, dx, dy) {
  var c = _ref.c,
      r = _ref.r;
  return {
    c: c + dx,
    r: r + dy
  };
}

function sanitizeCellDatum(value) {
  if (value === Infinity || value === -Infinity || typeof value === 'number' && isNaN(value)) {
    return null;
  } else {
    return value;
  }
}
/** 根据 BaseTable 的 dataSource 和 column，将表格数据导出为 Excel 文件 */


function exportTableAsExcel(xlsxPackage, dataSource, columns, filename) {
  var sheet = xlsxPackage.utils.aoa_to_sheet([]);
  var topHeaderHeight = (0, _getTreeDepth.default)(columns) + 1;
  var origin = {
    c: 0,
    r: 0
  };
  addTopHeaders(origin);
  addDataPart(move(origin, 0, topHeaderHeight));
  xlsxPackage.writeFile({
    SheetNames: ['Sheet1'],
    Sheets: {
      Sheet1: sheet
    }
  }, filename);

  function addTopHeaders(origin) {
    dfs(columns, 0, 0);

    function dfs(cols, startDx, startDy) {
      var _a;

      var start = move(origin, startDx, startDy);
      var offsetX = 0;

      var _iterator = _createForOfIteratorHelper(cols),
          _step;

      try {
        for (_iterator.s(); !(_step = _iterator.n()).done;) {
          var col = _step.value;

          if ((_a = col.features) === null || _a === void 0 ? void 0 : _a.noExport) {
            continue;
          }

          var current = move(start, offsetX, 0);
          addOne(col.name, current);

          if ((0, _isLeafNode.default)(col)) {
            offsetX += 1;
            mergeCells(current, 1, topHeaderHeight - startDy);
          } else {
            var childrenWidth = dfs(col.children, startDx + offsetX, startDy + 1);
            mergeCells(current, childrenWidth, 1);
            offsetX += childrenWidth;
          }
        }
      } catch (err) {
        _iterator.e(err);
      } finally {
        _iterator.f();
      }

      return offsetX;
    }
  }

  function addDataPart(origin) {
    var _context;

    var leafColumns = (0, _filter.default)(_context = (0, _collectNodes.default)(columns, 'leaf-only')).call(_context, function (col) {
      var _a;

      return !((_a = col.features) === null || _a === void 0 ? void 0 : _a.noExport);
    });
    var spanManager = new _SpanManager.default();
    var dataPart = (0, _map.default)(dataSource).call(dataSource, function (record, rowIndex) {
      spanManager.stripUpwards(rowIndex);
      return (0, _map.default)(leafColumns).call(leafColumns, function (col, colIndex) {
        if (spanManager.testSkip(rowIndex, colIndex)) {
          return null;
        }

        var spanRect = safeGetSpanRect(col, record, rowIndex, colIndex);
        var rowSpan = spanRect.bottom - spanRect.top;
        var colSpan = spanRect.right - spanRect.left;

        if (rowSpan > 1 || colSpan > 1) {
          spanManager.add(spanRect.top, spanRect.left, colSpan, rowSpan);
          mergeCells(move(origin, spanRect.left, spanRect.top), colSpan, rowSpan);
        }

        return sanitizeCellDatum(_internals.internals.safeGetValue(col, record, rowIndex));
      });
    });
    add(dataPart, origin);
  }

  function add(data, origin) {
    xlsxPackage.utils.sheet_add_aoa(sheet, data, {
      origin: origin
    });
  }

  function addOne(datum, origin) {
    xlsxPackage.utils.sheet_add_aoa(sheet, [[datum]], {
      origin: origin
    });
  }

  function mergeCells(addr, width, height) {
    if (width === 1 && height === 1) {
      return;
    }

    if (sheet['!merges'] == null) {
      sheet['!merges'] = [];
    }

    sheet['!merges'].push({
      s: addr,
      e: move(addr, width - 1, height - 1)
    });
  }
}