"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 = buildCrossTable;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/defineProperty"));
var _extends2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/extends"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/toConsumableArray"));
var _getOwnPropertySymbols = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols"));
var _concat = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/concat"));
var _utils = require("../../utils");
var _constants = require("./constants");
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 _context4; if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = _sliceInstanceProperty(_context4 = {}.toString.call(r)).call(_context4, 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; }
var __rest = void 0 && (void 0).__rest || function (s, e) {
  var t = {};
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
  if (s != null && typeof _getOwnPropertySymbols.default === "function") for (var i = 0, p = (0, _getOwnPropertySymbols.default)(s); i < p.length; i++) {
    if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
  }
  return t;
};
function buildCrossTable(options) {
  var _a, _b, _c;
  var leftTotalNode = options.leftTotalNode,
    topTotalNode = options.topTotalNode;
  // 有的时候 leftTree/topTree 是通过 node.children 传入的
  // 此时 leftTree/topTree 等于 null 和等于空数组是等价的
  // 故在这里兼容 leftTree/topTree 为空的情况
  var leftTree = (_a = options.leftTree) !== null && _a !== void 0 ? _a : [];
  var topTree = (_b = options.topTree) !== null && _b !== void 0 ? _b : [];
  var leftMetaColumns = (_c = options.leftMetaColumns) !== null && _c !== void 0 ? _c : [];
  var leftHeaderWidth = Math.max(leftMetaColumns.length, (0, _utils.getTreeDepth)(leftTree) + 1);
  return {
    columns: getColumns(),
    dataSource: getDataSource()
  };
  /** 获取表格的列配置 */
  function getColumns() {
    var _context;
    return (0, _concat.default)(_context = []).call(_context, (0, _toConsumableArray2.default)(getLeftPartColumns()), (0, _toConsumableArray2.default)(getDataPartColumns()));
    function getLeftPartColumns() {
      var _a;
      var leftPartColumns = [];
      for (var index = 0; index < leftHeaderWidth; index++) {
        var metaCol = (_a = leftMetaColumns[index]) !== null && _a !== void 0 ? _a : {};
        var getCellProps = metaCol.getCellProps,
          render = metaCol.render,
          staticMetaColConfig = __rest(metaCol, ["getCellProps", "render"]);
        leftPartColumns.push((0, _extends2.default)((0, _extends2.default)({
          columnType: 'left',
          lock: true
        }, staticMetaColConfig), {
          getCellProps: leftHeaderGetCellPropsFactory(metaCol, index),
          getSpanRect: leftHeaderGetSpanRectFactory(metaCol, index),
          getValue: leftHeaderGetValueFactory(metaCol, index),
          render: leftHeaderRenderFactory(metaCol, index)
        }));
      }
      return leftPartColumns;
      function leftHeaderGetCellPropsFactory(metaCol, colIndex) {
        return function (_value, row, rowIndex) {
          var _a;
          var node = row.nodes[colIndex];
          return (_a = metaCol.getCellProps) === null || _a === void 0 ? void 0 : _a.call(metaCol, node, colIndex);
        };
      }
      function leftHeaderGetSpanRectFactory(metaCol, colIndex) {
        return function (_value, row) {
          return row.rects[colIndex];
        };
      }
      function leftHeaderGetValueFactory(metaCol, colIndex) {
        return function (row, rowIndex) {
          var node = row.nodes[colIndex];
          return node.value;
        };
      }
      function leftHeaderRenderFactory(metaCol, colIndex) {
        return function (v, row, rowIndex) {
          var _a;
          var node = row.nodes[colIndex];
          if (metaCol.render) {
            return metaCol.render(node, colIndex);
          }
          return (_a = node.title) !== null && _a !== void 0 ? _a : node.value;
        };
      }
    }
    /** 获取表格数据部分的列配置 */
    function getDataPartColumns() {
      if (topTree.length > 0) {
        return dfs(topTree, {
          valuePath: [],
          depth: 0
        });
      } else if (topTotalNode) {
        return dfs([topTotalNode], {
          valuePath: [],
          depth: 0
        });
      } else {
        return [];
      }
      function dfs(nodes, ctx) {
        var result = [];
        var _iterator = _createForOfIteratorHelper(nodes),
          _step;
        try {
          for (_iterator.s(); !(_step = _iterator.n()).done;) {
            var node = _step.value;
            ctx.valuePath.push(node.value);
            if ((0, _utils.isLeafNode)(node)) {
              // 叶子节点
              result.push(getDataColumn(node, ctx.depth));
            } else {
              var key = node.key,
                value = node.value,
                children = node.children,
                others = __rest(node
                // 强制展开的节点
                , ["key", "value", "children"]);
              // 强制展开的节点
              result.push((0, _extends2.default)((0, _extends2.default)({
                columnType: 'data-parent'
              }, others), {
                name: value,
                children: dfs(children, {
                  valuePath: ctx.valuePath,
                  depth: ctx.depth + 1
                })
              }));
            }
            ctx.valuePath.pop();
          }
        } catch (err) {
          _iterator.e(err);
        } finally {
          _iterator.f();
        }
        return result;
      }
    }
    function getDataColumn(topNode, topDepth) {
      var columnGetValue = function columnGetValue(row) {
        var leftDepth = row.nodes.length - 1;
        var leftNode = row.nodes[leftDepth];
        return options.getValue(leftNode, topNode, leftDepth, topDepth);
      };
      var key = topNode.key,
        value = topNode.value,
        children = topNode.children,
        others = __rest(topNode, ["key", "value", "children"]);
      return (0, _extends2.default)((0, _extends2.default)({
        columnType: 'data'
      }, others), {
        getValue: columnGetValue,
        name: value,
        children: null,
        render: function render(value, row) {
          if (options.render) {
            var leftDepth = row.nodes.length - 1;
            var leftNode = row.nodes[leftDepth];
            return options.render(value, leftNode, topNode, leftDepth, topDepth);
          }
          return value;
        },
        getCellProps: function getCellProps(value, row) {
          if (options.getCellProps) {
            var leftDepth = row.nodes.length - 1;
            var leftNode = row.nodes[leftDepth];
            return options.getCellProps(value, leftNode, topNode, leftDepth, topDepth);
          }
        }
      });
    }
  }
  function getDataSource() {
    var flatRows = [];
    var ctx = {
      depth: 0,
      nodes: [],
      rects: [],
      rowIndex: 0
    };
    if (leftTree.length > 0) {
      dfs(leftTree, ctx);
    } else if (leftTotalNode) {
      dfs([leftTotalNode], ctx);
    } // else 表格没有行，展示空表格
    return flatRows;
    function dfs(nodes, ctx) {
      var count = 0;
      var _iterator2 = _createForOfIteratorHelper(nodes),
        _step2;
      try {
        for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
          var _context2, _context3;
          var node = _step2.value;
          if (node.hidden) {
            // 跳过被隐藏的节点
            continue;
          }
          var rect = {
            top: ctx.rowIndex + count,
            bottom: -1,
            left: ctx.depth,
            right: -1
          };
          var row = (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _constants.ROW_KEY, node.key), "rects", (0, _concat.default)(_context2 = []).call(_context2, (0, _toConsumableArray2.default)(ctx.rects), [rect])), "nodes", (0, _concat.default)(_context3 = []).call(_context3, (0, _toConsumableArray2.default)(ctx.nodes), [node]));
          if ((0, _utils.isLeafNode)(node)) {
            rect.right = leftHeaderWidth;
            rect.bottom = rect.top + 1;
            flatRows.push(row);
            count += 1;
          } else {
            ctx.rects.push(rect);
            ctx.nodes.push(node);
            var ret = dfs(node.children, {
              nodes: ctx.nodes,
              rects: ctx.rects,
              depth: ctx.depth + 1,
              rowIndex: ctx.rowIndex + count
            });
            ctx.rects.pop();
            ctx.nodes.pop();
            count += ret.count;
            rect.right = rect.left + 1;
            rect.bottom = rect.top + ret.count;
          }
        }
      } catch (err) {
        _iterator2.e(err);
      } finally {
        _iterator2.f();
      }
      return {
        count: count
      };
    }
  }
}