import _Symbol from "@babel/runtime-corejs3/core-js-stable/symbol";
import _Number$MAX_SAFE_INTEGER from "@babel/runtime-corejs3/core-js-stable/number/max-safe-integer";
import _findInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/find";
import _sliceInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/slice";
import _spliceInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/splice";
import _Map from "@babel/runtime-corejs3/core-js-stable/map";
import _findIndexInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/find-index";
import { getLeftNestedLockCount } from '../../base/calculations';
import { isLeafNode, makeRecursiveMapper } from '../../utils';
import { Classes } from '../../base/styles';
import { COLUMN_SIZE_KEY, LAST_RESIZED_COLUMN_KEY, RESIZED_COLUMN_KEY } from './columnResizeWidth';
export var FILL_COLUMN_CODE = '$_fill_column_&';
export var tableWidthKey = 'tableWidth';

var FLEX_COLUMN_COUNT = _Symbol('flexCount');

export var autoFillTableWidth = function autoFillTableWidth() {
  return function (pipeline) {
    var flexColumnResult = findFlexColumns(pipeline);
    var flexCount = flexColumnResult.get(FLEX_COLUMN_COUNT);

    if (flexCount) {
      // 设置了flex宽度，flex列平分剩余宽度
      var remainingWidth = getTableRemainingWidth(pipeline) || 0;

      if (remainingWidth > 0) {
        // 保存剩余的flex总和和剩余宽度总和宽度
        var residualFlexCount = flexCount;
        var residualFlexWidth = remainingWidth;
        var columnSize = pipeline.getFeatureOptions(COLUMN_SIZE_KEY);
        var enableColumnResizeWidthFeature = !!columnSize;
        pipeline.mapColumns(makeRecursiveMapper(function (col, recursiveFlatMapInfo) {
          var isLeaf = recursiveFlatMapInfo.isLeaf;

          if (isLeaf && isValidFlexColumn(col, pipeline)) {
            var code = col.code,
                _col$features = col.features,
                features = _col$features === void 0 ? {} : _col$features;
            var flex = features.flex,
                _features$minWidth = features.minWidth,
                minWidth = _features$minWidth === void 0 ? 0 : _features$minWidth,
                _features$maxWidth = features.maxWidth,
                maxWidth = _features$maxWidth === void 0 ? _Number$MAX_SAFE_INTEGER : _features$maxWidth;
            var usedRemainingWidth = Math.floor(remainingWidth * flex / flexCount);
            var preColWidth = col.width; // 如果当前已经是最后一个flex列，将剩余的宽度添加到该列，其他计算相应的列

            col.width = clamp(minWidth, preColWidth + (residualFlexCount === flex ? residualFlexWidth : usedRemainingWidth), maxWidth);
            residualFlexCount -= flex;
            residualFlexWidth -= col.width - preColWidth;

            if (enableColumnResizeWidthFeature) {
              columnSize[code] = col.width;
            }
          }

          return col;
        }));
        enableColumnResizeWidthFeature && pipeline.setFeatureOptions(COLUMN_SIZE_KEY, columnSize);
      }
    } else {
      // 未设置了flex宽度，创建占位列
      var columns = pipeline.getColumns();

      var fillColumns = _findInstanceProperty(columns).call(columns, function (col) {
        return col.code === FILL_COLUMN_CODE;
      });

      var width = getTableRemainingWidth(pipeline) || 0;

      if (fillColumns) {
        fillColumns.width = width;
      } else {
        var rightNestedLockCount = getLeftNestedLockCount(_sliceInstanceProperty(columns).call(columns).reverse());
        var spliceIndex = columns.length - rightNestedLockCount;
        var _fillColumns = {
          name: '',
          code: FILL_COLUMN_CODE,
          width: width,
          features: {
            resizeable: false
          },
          getCellProps: function getCellProps(value, record, rowIndex) {
            return {
              className: Classes.emptyColCell
            };
          }
        };

        _spliceInstanceProperty(columns).call(columns, spliceIndex || columns.length, 0, _fillColumns);
      }

      pipeline.columns(columns);
    }

    return pipeline;

    function findFlexColumns(pipeline) {
      var result = new _Map([[FLEX_COLUMN_COUNT, 0]]);
      dfs(pipeline.getColumns(), result);
      return result;

      function dfs(columns, result) {
        columns.forEach(function (col) {
          if (isLeafNode(col)) {
            if (isValidFlexColumn(col, pipeline)) {
              result.set(FLEX_COLUMN_COUNT, result.get(FLEX_COLUMN_COUNT) + col.features.flex);
            }
          } else {
            dfs(col.children, result);
          }
        });
      }
    }
  };
};

function getColumnWidthSum(pipeline) {
  return dfs(pipeline.getColumns());

  function dfs(columns) {
    return columns.reduce(function (acc, col) {
      var width = col.width,
          code = col.code;

      if (isLeafNode(col) && code !== FILL_COLUMN_CODE) {
        var resizeColumn = pipeline.getFeatureOptions(COLUMN_SIZE_KEY);
        return acc + (resizeColumn && resizeColumn[code] || width);
      } else {
        return acc + dfs(col.children);
      }
    }, 0);
  }
}

function getTableRemainingWidth(pipeline) {
  var _a, _b;

  var tableWidth = ((_b = (_a = pipeline.ref.current.domHelper) === null || _a === void 0 ? void 0 : _a.tableBody) === null || _b === void 0 ? void 0 : _b.clientWidth) || pipeline.getStateAtKey(tableWidthKey);
  if (!tableWidth) return;
  var remainingWidth = Math.floor(tableWidth - getColumnWidthSum(pipeline));
  return remainingWidth > 0 ? remainingWidth : 0;
}

function isAfterLastResizeCol(column, pipeline) {
  var _context, _context2;

  var lastResizedColumnCode = pipeline.getFeatureOptions(LAST_RESIZED_COLUMN_KEY);
  if (lastResizedColumnCode === undefined) return true;

  var lastResizedColumnIndex = _findIndexInstanceProperty(_context = pipeline.getColumns()).call(_context, function (col) {
    return col.code === lastResizedColumnCode;
  });

  var colIndex = _findIndexInstanceProperty(_context2 = pipeline.getColumns()).call(_context2, function (col) {
    return col.code === column.code;
  });

  return colIndex > lastResizedColumnIndex;
}

function isValidFlexColumn(col, pipeline) {
  var _a;

  var resizeColumn = pipeline.getFeatureOptions(RESIZED_COLUMN_KEY); // 拖拽列自动禁止flex

  if (resizeColumn === null || resizeColumn === void 0 ? void 0 : resizeColumn.has(col.code)) {
    return false;
  }

  var flex = (_a = col.features) === null || _a === void 0 ? void 0 : _a.flex;
  return typeof flex === 'number' && flex > 0 && isAfterLastResizeCol(col, pipeline);
}

function clamp(min, x, max) {
  return Math.max(min, Math.min(max, x));
}