"use strict";

function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.fixedWidthTypeList = exports.fieldTypeShrink = exports.computeableWidthTypeList = void 0;
exports.genAutoWidthColumns = genAutoWidthColumns;
exports.shadowContainer = exports.shadowActionColumnContainer = void 0;
var _react = _interopRequireWildcard(require("react"));
var _utils = require("@teamix/utils");
var _pureColumnRender = require("./pureColumnRender");
var _columnRender = require("./columnRender");
var _actions = require("../../actions");
var _proField = require("@teamix/pro-field");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(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 _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
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 ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
// 最大宽度
var maxColumnWidth = 600;
// 最小宽度
var minColumnWidth = 48;
// 每个列可以缩减的最大宽度
var columnShrinkMaxWidth = 100;
/**
 * @param fileteredColumns
 * @param ref
 * @param data
 * @returns
 */
function genAutoWidthColumns(columns, ref, data, size, useRowSelection, actionColumnRef) {
  if (!(ref === null || ref === void 0 ? void 0 : ref.current)) {
    return columns;
  }
  var hasLockFlag = false;
  var dom = ref.current;
  var actionColumnDom = actionColumnRef === null || actionColumnRef === void 0 ? void 0 : actionColumnRef.current;
  var childNodes = dom.children;
  if (dom.children.length === 0) {
    return columns;
  }
  var finalColumns = [];
  var filterdColumnsResult = _utils._.cloneDeep(columns);
  filterdColumnsResult.forEach(function (column, index) {
    var render = column.render,
      _column$valueType = column.valueType,
      valueType = _column$valueType === void 0 ? 'text' : _column$valueType,
      _column$isAutoWidth = column.isAutoWidth,
      isAutoWidth = _column$isAutoWidth === void 0 ? true : _column$isAutoWidth,
      actionSchema = column.actionSchema,
      sortable = column.sortable,
      lock = column.lock;
    if (lock) {
      hasLockFlag = true;
    }
    //@ts-ignore
    var type = render === null || render === void 0 ? void 0 : render.type;
    var finalType = type || valueType || '';
    var shrink = fieldTypeShrink[finalType];
    column.shrink = column.shrink || (shrink !== undefined ? shrink : 1);
    if ((column === null || column === void 0 ? void 0 : column.isAutoWidth) === false) {
      // console.log(column.title, 'isAutoWidth')
      finalColumns.push(column);
      return;
    }
    if ((column === null || column === void 0 ? void 0 : column.columnFilters) === false) {
      finalColumns.push(column);
      return;
    }
    // column.isAutoWidth = true
    //@ts-ignore
    // if (!autoWidth) {
    //   finalColumns.push(column);
    //   return;
    // }
    if (actionSchema) {
      // TODO 操作列暂时未处理，但是应该根据actionSchema的数量直接推测出操作列的宽度
      // console.log('column', column);
      column.shrink = 0;
      // column.width = 280;
      // console.log(
      //   'actionColumnDom',
      //   actionColumnDom?.childNodes[0].scrollWidth,
      // );
      if (actionColumnDom === null || actionColumnDom === void 0 ? void 0 : actionColumnDom.childNodes[0]) {
        //@ts-ignore
        var width = actionColumnDom === null || actionColumnDom === void 0 ? void 0 : actionColumnDom.childNodes[0].scrollWidth;
        if (width >= 280) {
          width = 280;
        }
        column.isAutoWidth = false;
        column.width = defaultPaddingFixer(width, size, false);
      }
      finalColumns.push(column);
      return;
    }
    // 当列没出来的时候不比较
    // @ts-ignore
    if ((column === null || column === void 0 ? void 0 : column.columnFilters) === false) {
      finalColumns.push(column);
      return;
    }
    // @ts-ignore
    var titleWidth = _utils._.get(childNodes[index], "children[0].scrollWidth", 0);
    // const titleWidth = childNodes[index]?.children[0].scrollWidth
    // @ts-ignore
    if (fixedWidthTypeList[finalType]) {
      // console.log(
      //   'fixedWidthTypeList[finalType]',
      //   fixedWidthTypeList[finalType],
      // );
      // 固定宽度
      // console.log(column.title, '固定宽度')
      column.isAutoWidth = false;
      column.width = defaultPaddingFixer(
      // @ts-ignore
      Math.max(titleWidth, fixedWidthTypeList[finalType]), size, index === 0 && useRowSelection);
      // @ts-ignore
    } else if (computeableWidthTypeList[finalType]) {
      // 可计算宽度
      // console.log(column.title, '可计算宽度')
      column.isAutoWidth = false;
      column.width = defaultPaddingFixer(
      // @ts-ignore
      Math.max(titleWidth, computeableWidthTypeList[finalType](data, render)), size, index === 0 && useRowSelection);
    } else {
      var _column$render;
      // 直接根据 dom 计算
      // console.log(column.title, '可计算 dom')
      column.isAutoWidth = false;
      column.width = defaultPaddingFixer(Math.max(titleWidth,
      // @ts-ignore
      calcWidthWithParentDOM(childNodes[index], column.shrink)), size, index === 0 && useRowSelection);
      if ((column === null || column === void 0 ? void 0 : column.sortable) && ((column === null || column === void 0 ? void 0 : column.tooltip) || (column === null || column === void 0 ? void 0 : column.filters))) {
        // 检测有 sortable 和 tooltip 的时候增加宽度
        column.width = column.width + 40;
      } else if (column === null || column === void 0 ? void 0 : column.sortable) {
        column.width = column.width + 24;
      }
      // @ts-ignore
      if (column === null || column === void 0 ? void 0 : (_column$render = column.render) === null || _column$render === void 0 ? void 0 : _column$render.copy) {
        column.width = column.width + 16;
      }
    }
    if (index === 0) {
      // 首列不会被挤占
      column.shrink = 0;
    }
    finalColumns.push(column);
  });
  if (!hasLockFlag) {
    // 如果没有锁列的情况，需要将所有列放到一屏内，此时需要将所有列放到一起计算一次
    var containerWidth = dom.offsetWidth;
    var comboColumns = calcMultiColumnLength(finalColumns, useRowSelection ? containerWidth - 50 : containerWidth);
    return comboColumns;
  }
  return finalColumns;
}
var shadowContainer = function shadowContainer(props) {
  var ref = /*#__PURE__*/(0, _react.createRef)();
  var columns = props.columns,
    data = props.data,
    shadowContainerRef = props.shadowContainerRef;
  if (data.length === 0) return null;
  return /*#__PURE__*/_react.default.createElement("div", {
    ref: shadowContainerRef,
    className: "teamix-pro-table-shadow-container"
  }, columns.map(function (column, index) {
    var dataIndex = column.dataIndex,
      valueType = column.valueType;
    if (!(column === null || column === void 0 ? void 0 : column.actionSchema)) {
      return /*#__PURE__*/_react.default.createElement("div", {
        className: "teamix-pro-table-shadow-container-columns",
        key: index
      }, /*#__PURE__*/_react.default.createElement("div", null, (0, _columnRender.renderColumnsTitle)(column, ref)),
      //@ts-ignore
      !computeableWidthTypeList[valueType] &&
      //@ts-ignore
      !fixedWidthTypeList[valueType] && data.map(function (item, index) {
        // @ts-ignore
        var newColumn = _utils._.cloneDeep(column);
        newColumn.smartWidth = (0, _columnRender.renderCellSmartWidth)(getValueFromRecord(dataIndex, item), column, index, item);
        newColumn.render = _objectSpread(_objectSpread({}, column.render), {}, {
          description: ''
        });
        return (0, _pureColumnRender.renderCell)(getValueFromRecord(dataIndex, item), newColumn, index, item);
      }));
    }
  }));
};
exports.shadowContainer = shadowContainer;
var shadowActionColumnContainer = function shadowActionColumnContainer(columns, shadowActionColumnContainerRef) {
  var actionColumn = columns.find(function (column) {
    return column === null || column === void 0 ? void 0 : column.actionSchema;
  });
  if (actionColumn === null || actionColumn === void 0 ? void 0 : actionColumn.actionSchema) {
    return /*#__PURE__*/_react.default.createElement("div", {
      ref: shadowActionColumnContainerRef,
      className: "teamix-pro-table-action-column-shadow-container"
    }, /*#__PURE__*/_react.default.createElement(_actions.ProActionGroup, _objectSpread(_objectSpread({
      type: "text"
    }, actionColumn === null || actionColumn === void 0 ? void 0 : actionColumn.actionSchema), {}, {
      context: _objectSpread({}, actionColumn === null || actionColumn === void 0 ? void 0 : actionColumn.actionSchema.context)
    })));
  }
};
// 计算操作列的宽度
exports.shadowActionColumnContainer = shadowActionColumnContainer;
function getValueFromRecord(dataIndex, record) {
  if (!dataIndex) {
    return null;
  }
  if (Array.isArray(dataIndex)) {
    var value = dataIndex.map(function (item) {
      return (0, _utils.getTargetValue)("{{".concat(item, "}}"), _objectSpread(_objectSpread({}, record), {}, {
        record: record
      }));
    });
    return value;
  } else {
    var result = record;
    var array = dataIndex.split('.');
    array.forEach(function (item) {
      return result = result ? result[item] : undefined;
    });
    return result;
  }
}
// TODO 某些可以直接算出结果的 profield 类型白名单，待补充，每个类型下支持一个函数，用当前值和渲染类型算出一个结果
var computeableWidthTypeList = {
  dateTime: function dateTime(data, render) {
    var result = (0, _proField.getProFieldWidth)('dateTime', render);
    // @ts-ignore
    return (result === null || result === void 0 ? void 0 : result.minWidth) || 0;
  }
};
// TODO 某些固定宽度的 profield 类型白名单，这里的数据可能需要综合考虑 dataFold 和 render.rows
exports.computeableWidthTypeList = computeableWidthTypeList;
var fixedWidthTypeList = {
  // 时间日期
  // dateTime: 142,
  // dateMonth: 74, // 60
  // dateWeek: 74,
  // date: 100,
  // dateYear: 46,
  // dateQuarter: 64,
  // dateRange: 212,
  dateWeekRange: 156,
  dateMonthRange: 156,
  dateYearRange: 102,
  dateQuarterRange: 136,
  dateTimeRange: 326,
  time: 38,
  timeRange: 124
};
// TODO 不同类型的 profield 的 shrink，0表示不可以省略号，数字越大越容易被挤占空间
exports.fixedWidthTypeList = fixedWidthTypeList;
var fieldTypeShrink = {
  tag: 0,
  statusTag: 0,
  statusIconTag: 0,
  circle: 0,
  rank: 0,
  progress: 0,
  money: 0,
  number: 0,
  percent: 0,
  dateTime: 0,
  ip: 0
};
exports.fieldTypeShrink = fieldTypeShrink;
function calcWidthWithParentDOM(dom, shrink) {
  if (dom) {
    var childNodes = _toConsumableArray(dom.children);
    childNodes.shift();
    return calcSingleColumnLength(childNodes.map(function (node) {
      return node.scrollWidth;
    }), shrink);
  } else {
    return 0;
  }
}
function calcSingleColumnLength() {
  var list = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  var shrink = arguments.length > 1 ? arguments[1] : undefined;
  if (shrink === 0) {
    return Math.ceil(Math.max.apply(null, list));
  }
  return getConfidence90UpperBound(list);
}
/**
 * 根据所有列的宽度和权重，结合总宽度，计算出各个列合适的宽度
 * 目前算法：
 * 当前需要的总宽度-总宽度=需要降低的宽度
 * 从后往前，将shrink不为0的列，降低一些宽度到最小宽度
 * 最小宽度可以用百分比去算
 * TODO 当前shrink只用了0，其他的权重也要考虑一下
 * @param list
 * @param max
 * @returns
 */
function calcMultiColumnLength() {
  var list = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  var max = arguments.length > 1 ? arguments[1] : undefined;
  var result = _toConsumableArray(list);
  var targetList = [];
  var needWidth = 0;
  var canShrink = 0;
  list.forEach(function (item) {
    //@ts-ignore
    needWidth += item.width;
    if (item.shrink !== 0) {
      targetList.push(item);
      //@ts-ignore
      canShrink += Math.min(item.width - minColumnWidth, columnShrinkMaxWidth);
    }
  });
  var widthToBeRemoved = needWidth - max;
  if (widthToBeRemoved <= 0) {
    return list;
  }
  // TODO 超过的特别多直接加锁列，这个逻辑怎么设计
  // 目前用可以缩小的宽度加起来比较一下
  if (canShrink < widthToBeRemoved) {
    list[0].lock = 'left';
    if (list[list.length - 1].actionSchema) {
      list[list.length - 1].lock = 'right';
    }
    return list;
  }
  //@ts-ignore
  var sortedList = targetList.sort(function (a, b) {
    return a.width - b.width;
  });
  var shrinkedWidth = 0;
  for (var i = sortedList.length - 1; i >= 0; i--) {
    if (shrinkedWidth >= widthToBeRemoved) {
      break;
    }
    var singleShrinkedWidth = Math.min(sortedList[i].width - minColumnWidth, columnShrinkMaxWidth, widthToBeRemoved - shrinkedWidth);
    sortedList[i].width = sortedList[i].width - singleShrinkedWidth;
    shrinkedWidth += singleShrinkedWidth;
  }
  return result;
}
/**
 * 修正内容放在table中默认的padding
 * @param width
 * @returns
 */
function defaultPaddingFixer(width) {
  var size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'medium';
  var half = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
  return size === 'medium' ? width + (half ? 16 : 32) + 0.5 : width + (half ? 8 : 16) + 0.5;
}
function sum() {
  var list = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  if (list.length === 0) return 0;
  return list === null || list === void 0 ? void 0 : list.reduce(function (a, b) {
    return a + b;
  });
}
/**
 * 假设样本正态分布，取 90% 置信区间的上界
 * 当上界与最大值差距不大(目前是20)的时候，直接用最大值
 * TODO 这里没考虑是否可以直接用标准差做评判依据，如标准差过大时，直接排序并展示前90%，或标准差很小时直接用最大值
 * TODO 这里极限情况是不是会挂？ 如：长度为9个100和2个10000，估计会挂，是否置信区间这个不靠谱。。。最差情况就直接展示90%的数据算了
 */
function getConfidence90UpperBound() {
  var list = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  var max = Math.max.apply(null, list);
  var length = list.length;
  var mean = sum(list) / length;
  var std = Math.sqrt(sum(list.map(function (n) {
    return (n - mean) * (n - mean);
  })) / length);
  var interval = length > 30 ? 1.65 * std / Math.sqrt(length) : 2.2622 * std / Math.sqrt(length);
  var bound = Math.ceil(mean + interval);
  if (max - bound < 20) {
    return Math.min(max, maxColumnWidth);
  }
  return Math.min(bound, maxColumnWidth);
}