"use strict";

var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.TablePipeline = void 0;
exports.useTablePipeline = useTablePipeline;
var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/map"));
var _slice = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/slice"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/slicedToArray"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/defineProperty"));
var _extends3 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/extends"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/createClass"));
var _react = require("react");
var _utils = require("../utils");
var _autoFill = require("./features/autoFill");
var _utils2 = require("./features/featureApi/utils");
/**
 * 表格数据处理流水线。TablePipeline 提供了表格数据处理过程中的一些上下方与工具方法，包括……
 *
 * 1. ctx：上下文环境对象，step（流水线上的一步）可以对 ctx 中的字段进行读写。
 * ctx 中部分字段名称有特定的含义（例如 primaryKey 表示行的主键），使用自定义的上下文信息时注意避开这些名称。
 *
 * 2. rowPropsGetters：getRowProps 回调队列，step 可以通过 pipeline.appendRowPropsGetter 向队列中追加回调函数，
 *   在调用 pipeline.props() 队列中的所有函数会组合形成最终的 getRowProps
 *
 * 3. 当前流水线的状态，包括 dataSource, columns, rowPropsGetters 三个部分
 *
 * 4. snapshots，调用 pipeline.snapshot(name) 可以记录当前的状态，后续可以通过 name 来读取保存的状态
 * */
var TablePipeline = exports.TablePipeline = /*#__PURE__*/function () {
  function TablePipeline(_ref) {
    var state = _ref.state,
      setState = _ref.setState,
      ctx = _ref.ctx,
      ref = _ref.ref;
    (0, _classCallCheck2.default)(this, TablePipeline);
    this._snapshots = {};
    this._rowPropsGetters = [];
    this._tableProps = {};
    this.ctx = {
      components: {},
      indents: TablePipeline.defaultIndents
    };
    this.state = state;
    this.setState = setState;
    this.ref = ref;
    (0, _extends3.default)(this.ctx, ctx);
  }
  // Generate a pseudo-GUID by concatenating random hexadecimal.
  return (0, _createClass2.default)(TablePipeline, [{
    key: "guid",
    value: function guid() {
      function S4() {
        return ((1 + Math.random()) * 0x10000 | 0).toString(16).substring(1);
      }
      return S4() + S4() + '-' + S4() + '-' + S4() + '-' + S4() + '-' + S4() + S4() + S4();
    }
  }, {
    key: "appendRowPropsGetter",
    value: function appendRowPropsGetter(getter) {
      this._rowPropsGetters.push(getter);
      return this;
    }
  }, {
    key: "addTableProps",
    value: function addTableProps(props) {
      this._tableProps = (0, _utils.mergeCellProps)(this._tableProps, props);
    }
  }, {
    key: "getDataSource",
    value: function getDataSource(name) {
      if (name == null) {
        return this._dataSource;
      } else {
        return this._snapshots[name].dataSource;
      }
    }
  }, {
    key: "isSameInputDataSource",
    value: function isSameInputDataSource() {
      return this._isSameInputDataSource;
    }
  }, {
    key: "getColumns",
    value: function getColumns(name) {
      if (name == null) {
        return this._columns;
      } else {
        return this._snapshots[name].columns;
      }
    }
  }, {
    key: "getFooterDataSource",
    value: function getFooterDataSource() {
      return this._footerDataSource;
    }
  }, {
    key: "getStateAtKey",
    value: function getStateAtKey(stateKey, defaultValue) {
      var _a;
      return (_a = this.state[stateKey]) !== null && _a !== void 0 ? _a : defaultValue;
    }
    /** 将 stateKey 对应的状态设置为 partialState  */
  }, {
    key: "setStateAtKey",
    value: function setStateAtKey(stateKey, partialState, extraInfo) {
      this.setState(function (prev) {
        return (0, _extends3.default)((0, _extends3.default)({}, prev), (0, _defineProperty2.default)({}, stateKey, partialState));
      }, stateKey, partialState, extraInfo);
    }
    /** 确保 primaryKey 已被设置，并返回 primaryKey  */
  }, {
    key: "ensurePrimaryKey",
    value: function ensurePrimaryKey(hint) {
      if (this.ctx.primaryKey == null) {
        throw new Error(hint ? "\u4F7F\u7528 ".concat(hint, " \u4E4B\u524D\u5FC5\u987B\u5148\u8BBE\u7F6E primaryKey") : '必须先设置 primaryKey');
      }
      return this.ctx.primaryKey;
    }
    /** 设置流水线的输入数据 */
  }, {
    key: "input",
    value: function input(_input) {
      var _context,
        _this = this;
      if (this._dataSource != null || this._columns != null) {
        throw new Error('input 不能调用两次');
      }
      // 在 pipeline 中识别本次更新是否有数据变化
      this._isSameInputDataSource = _input.dataSource === this.ref.current._lastInputDataSource;
      this._dataSource = _input.dataSource;
      this.ref.current._lastInputDataSource = _input.dataSource;
      this.ref.current.lastPipeline = this;
      this._columns = (0, _map.default)(_context = _input.columns).call(_context, function (col) {
        return (0, _extends3.default)((0, _extends3.default)({}, col), {
          key: _this.guid()
        });
      });
      this.snapshot('input');
      return this;
    }
    /** 设置 dataSource */
  }, {
    key: "dataSource",
    value: function dataSource(rows) {
      this._dataSource = rows;
      return this;
    }
    /** 设置 columns */
  }, {
    key: "columns",
    value: function columns(cols) {
      this._columns = cols;
      return this;
    }
    /** 设置主键 */
  }, {
    key: "primaryKey",
    value: function primaryKey(key) {
      this.ctx.primaryKey = key;
      return this;
    }
    /** 设置页脚数据 */
  }, {
    key: "footerDataSource",
    value: function footerDataSource(rows) {
      this._footerDataSource = rows;
      return this;
    }
    /** 保存快照 */
  }, {
    key: "snapshot",
    value: function snapshot(name) {
      var _context2;
      this._snapshots[name] = {
        dataSource: this._dataSource,
        columns: this._columns,
        rowPropsGetters: (0, _slice.default)(_context2 = this._rowPropsGetters).call(_context2)
      };
      return this;
    }
    /** @deprecated
     *  应用一个 kd-table Table transform */
  }, {
    key: "useTransform",
    value: function useTransform(transform) {
      var next = transform({
        dataSource: this.getDataSource(),
        columns: this.getColumns()
      });
      return this.dataSource(next.dataSource).columns(next.columns);
    }
    /** 使用 pipeline 功能拓展 */
  }, {
    key: "use",
    value: function use(step) {
      return step(this);
    }
    /** 转换 dataSource */
  }, {
    key: "mapDataSource",
    value: function mapDataSource(mapper) {
      return this.dataSource(mapper(this.getDataSource()));
    }
    /** 转换 columns */
  }, {
    key: "mapColumns",
    value: function mapColumns(mapper) {
      return this.columns(mapper(this.getColumns()));
    }
    /** 获取featureOptions 内容 */
  }, {
    key: "getFeatureOptions",
    value: function getFeatureOptions(optionKey) {
      var _a;
      return (_a = this.ref.current.featureOptions) === null || _a === void 0 ? void 0 : _a[optionKey];
    }
    /** 设置pipelineOptions 内容 */
  }, {
    key: "setFeatureOptions",
    value: function setFeatureOptions(optionKey, value) {
      this.ref.current.featureOptions[optionKey] = value;
    }
    /** 获取 BaseTable 的 props，结果中包含 dataSource/columns/primaryKey/getRowProps 四个字段 */
  }, {
    key: "getProps",
    value: function getProps() {
      var _this2 = this;
      this.use((0, _autoFill.autoFillTableWidth)());
      var result = {
        dataSource: this._dataSource,
        columns: this._columns
      };
      if (this.ctx.primaryKey) {
        result.primaryKey = this.ctx.primaryKey;
      }
      if (this._footerDataSource) {
        result.footerDataSource = this._footerDataSource;
      }
      if (this._rowPropsGetters.length > 0) {
        result.getRowProps = function (row, rowIndex) {
          return _this2._rowPropsGetters.reduce(function (res, get) {
            return (0, _utils.mergeCellProps)(res, get(row, rowIndex));
          }, {});
        };
      }
      result.getTableProps = function () {
        return _this2._tableProps;
      };
      result.setTableWidth = function (tableWidth) {
        var preTableWidth = _this2.getStateAtKey(_autoFill.tableWidthKey);
        if (preTableWidth !== tableWidth) {
          tableWidth && _this2.setStateAtKey(_autoFill.tableWidthKey, tableWidth);
        }
      };
      result.setTableDomHelper = function (domHelper) {
        _this2.ref.current.domHelper = domHelper;
      };
      result.setRowHeightManager = function (rowHeightManager) {
        _this2.ref.current.rowHeightManager = rowHeightManager;
      };
      return result;
    }
  }, {
    key: "getFeatureApi",
    value: function getFeatureApi(featureName) {
      var _a;
      return (_a = this.ref.current.featureApi) === null || _a === void 0 ? void 0 : _a[featureName];
    }
  }, {
    key: "addFeatureApi",
    value: function addFeatureApi(featureName) {
      if (!this.getFeatureApi(featureName)) {
        this.ref.current.featureApi[featureName] = (0, _utils2.createFeatureApi)(featureName, this);
      }
      return this.ref.current.featureApi[featureName];
    }
  }, {
    key: "getLastPipeline",
    value: function getLastPipeline() {
      return this.ref.current.lastPipeline;
    }
  }]);
}();
TablePipeline.defaultIndents = {
  iconIndent: -8,
  iconWidth: 16,
  iconGap: 0,
  indentSize: 16
};
function useTablePipeline(ctx) {
  var _useState = (0, _react.useState)({}),
    _useState2 = (0, _slicedToArray2.default)(_useState, 2),
    state = _useState2[0],
    setState = _useState2[1];
  var ref = (0, _react.useRef)({
    featureOptions: {},
    featureApi: {}
  });
  return new TablePipeline({
    state: state,
    setState: setState,
    ctx: ctx,
    ref: ref
  });
}