import _slicedToArray from "@babel/runtime-corejs3/helpers/slicedToArray";
import _defineProperty from "@babel/runtime-corejs3/helpers/defineProperty";
import _extends from "@babel/runtime-corejs3/helpers/extends";
import _classCallCheck from "@babel/runtime-corejs3/helpers/classCallCheck";
import _createClass from "@babel/runtime-corejs3/helpers/createClass";
import _mapInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/map";
import _sliceInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/slice";
import { useState, useRef } from 'react';
import { mergeCellProps } from '../utils';
import { autoFillTableWidth, tableWidthKey } from './features/autoFill';
/**
 * 表格数据处理流水线。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 来读取保存的状态
 * */

export var TablePipeline = /*#__PURE__*/function () {
  function TablePipeline(_ref) {
    var state = _ref.state,
        setState = _ref.setState,
        ctx = _ref.ctx,
        ref = _ref.ref;

    _classCallCheck(this, TablePipeline);

    this._snapshots = {};
    this._rowPropsGetters = [];
    this._tableProps = {};
    this.ctx = {
      components: {},
      indents: TablePipeline.defaultIndents
    };
    this.state = state;
    this.setState = setState;
    this.ref = ref;

    _extends(this.ctx, ctx);
  } // Generate a pseudo-GUID by concatenating random hexadecimal.


  _createClass(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 = mergeCellProps(this._tableProps, props);
    }
  }, {
    key: "getDataSource",
    value: function getDataSource(name) {
      if (name == null) {
        return this._dataSource;
      } else {
        return this._snapshots[name].dataSource;
      }
    }
  }, {
    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 _extends(_extends({}, prev), _defineProperty({}, 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 不能调用两次');
      }

      this._dataSource = _input.dataSource;
      this._columns = _mapInstanceProperty(_context = _input.columns).call(_context, function (col) {
        return _extends(_extends({}, 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: _sliceInstanceProperty(_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(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 mergeCellProps(res, get(row, rowIndex));
          }, {});
        };
      }

      result.getTableProps = function () {
        return _this2._tableProps;
      };

      result.setTableWidth = function (tableWidth) {
        var preTableWidth = _this2.getStateAtKey(tableWidthKey);

        if (preTableWidth !== tableWidth) {
          _this2.setStateAtKey(tableWidthKey, tableWidth);
        }
      };

      result.setTableDomHelper = function (domHelper) {
        _this2.ref.current.domHelper = domHelper;
      }; // if (this.getFeatureOptions(rangeSelectionKey)) {
      //   result.clearRangeSelectionStatus = () => {
      //     const { rangeSelectedChange } = this.getFeatureOptions(rangeSelectionKey)
      //     const rangeSelection = this.getStateAtKey(rangeSelectionKey)
      //     if (rangeSelection) {
      //       rangeSelectedChange?.(null)
      //     }
      //   }
      // }


      return result;
    }
  }]);

  return TablePipeline;
}();
TablePipeline.defaultIndents = {
  iconIndent: -8,
  iconWidth: 16,
  iconGap: 0,
  indentSize: 16
};
export function useTablePipeline(ctx) {
  var _useState = useState({}),
      _useState2 = _slicedToArray(_useState, 2),
      state = _useState2[0],
      setState = _useState2[1];

  var ref = useRef({});
  ref.current.featureOptions = {};
  return new TablePipeline({
    state: state,
    setState: setState,
    ctx: ctx,
    ref: ref
  });
}