"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.useColumns = useColumns;
var _react = _interopRequireWildcard(require("react"));
var _types = require("../types");
var _customCells = require("../components/custom-cells");
var _useTranslation = require("../../hooks/use-translation");
var _skeleton = require("../../skeleton");
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
function calculateDelta(columns, maxWidth, padding = 0, columnSizing = {}, visibility = {}) {
  // we are interested only in visible columns
  const visibleColumns = columns.filter(({
    accessorKey,
    id
  }) => {
    // visibility state uses column ids for setting visibility, and for most cases it's the same as accessorKey
    // but for the case when either 1) user provided an explicit id to the columnDef or 2) accessorKey is a complex get object path like `<object_name>.<object_property_name>`
    // accessorKey would be different from id. Thus we should add a check on columnDef.id here
    const visibilityValue = visibility[id] ?? visibility[accessorKey];
    return visibilityValue !== false;
  });
  // we need to know columns that do have maxSize set, as it will influence how free space is distributed
  const columnsWithMaxSize = visibleColumns.filter(column => !!column.maxSize);

  // calculation of all current columns width
  const currentWidth = visibleColumns.reduce((acc, current) => {
    const resizeValue = columnSizing[current.id] || columnSizing[current.accessorKey];
    const minWidth = current.minSize || _types.COLUMN_SIZE.MIN_WIDTH;
    const resizeWidth = resizeValue ? Math.max(resizeValue, minWidth) : 0;
    const columnSize = Math.max(current.size || _types.COLUMN_SIZE.WIDTH, minWidth);
    return acc + (resizeWidth || columnSize);
  }, padding);

  // if sum of al columns is greater than container width, no free space to distribute
  if (currentWidth > maxWidth) {
    return {};
  }

  // all free space available for distribution
  const delta = maxWidth - currentWidth;
  // selecting columns among which to distribute free space. (Filtering out columns that have eiterh size set in their columnDef, or ones
  // whose size was altered manually by drag-n-drop in UI)
  const notSettedColumns = visibleColumns.filter(({
    size,
    accessorKey,
    id
  }) => !size && !(columnSizing[id] || columnSizing[accessorKey]));
  const evenDistribution = delta / notSettedColumns.length;

  // if there is no max size on any columns - distribute free space evenly across columns
  if (columnsWithMaxSize.length === 0) {
    return notSettedColumns.reduce((acc, column) => {
      acc[column.accessorKey] = evenDistribution;
      return acc;
    }, {});
  }

  // get columns withMaxSize where column.currentSize + delta > column.maxSize
  // and give them the portion of delta to reach maxSize
  const columnsWithCappedDelta = columnsWithMaxSize.reduce((acc, current) => {
    const minWidth = current.minSize || _types.COLUMN_SIZE.MIN_WIDTH;
    const columnSize = Math.max(current.size || _types.COLUMN_SIZE.WIDTH, minWidth);
    if (columnSize + evenDistribution > current.maxSize) {
      acc[current.accessorKey] = current.maxSize - columnSize;
    }
    return acc;
  }, {});

  // calculate delta left after columns which reached max size are given their deltas
  const evenlyDistributedSpaceAfterMaxSized = (delta - Object.values(columnsWithCappedDelta).reduce((acc, item) => acc + item, 0)) / (notSettedColumns.length - Object.values(columnsWithCappedDelta).length);

  // return a map of <accessorKey>: <respectiveDelta> for all visible columns
  return notSettedColumns.reduce((acc, notSettedColumn) => {
    // if current column has maxSize corner case - take delta from previously computed columnsWithCappedDelta
    if (columnsWithCappedDelta[notSettedColumn.accessorKey]) {
      acc[notSettedColumn.accessorKey] = columnsWithCappedDelta[notSettedColumn.accessorKey];
    } else {
      // otherwise use newly computed evenly distributed delta
      acc[notSettedColumn.accessorKey] = evenlyDistributedSpaceAfterMaxSized;
    }
    return acc;
  }, {});
}
function useColumns(columns, showCheckboxes, maxWidth, visibility, columnSizing, showExpandRow, isRowActionsExist, localizationProps) {
  const {
    t
  } = (0, _useTranslation.useTranslation)();
  const decoratedColumns = (0, _react.useMemo)(() => {
    const checkBoxColumn = {
      id: _types.CHECKBOXES_COLUMN.ID,
      accessorKey: _types.CHECKBOXES_COLUMN.ID,
      header: ({
        table,
        keyboardNavCellId
      }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_customCells.CheckboxHeaderCell, {
        table: table,
        keyboardNavCellId: keyboardNavCellId,
        selectAllRowsAriaLabel: localizationProps?.selectAllRowsCheckBoxAriaLabel
      }),
      cell: ({
        row,
        table,
        rowSelectionDisabled,
        keyboardNavCellId
      }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_customCells.CheckboxBodyCell, {
        row: row,
        table: table,
        rowSelectionDisabled: rowSelectionDisabled,
        keyboardNavCellId: keyboardNavCellId,
        selectRowAriaLabel: localizationProps?.selectRowCheckBoxAriaLabel
      }),
      size: _types.CHECKBOXES_COLUMN.SIZE,
      enableSorting: false,
      meta: {
        className: 'select-checkbox',
        hideFromSettings: true,
        hideSeparator: true,
        hideMenu: true,
        truncateText: false,
        hasCustomCellAction: true,
        loader: {
          type: _skeleton.SKELETON_TYPES.CIRCULAR,
          width: 16,
          height: 16
        },
        headerAriaLabel: localizationProps?.checkboxHeaderCellAriaLabel || t('Click to select all rows in the table'),
        cellAriaLabel: localizationProps?.checkBoxBodyCellAriaLabel || t('Click to select the row')
      }
    };
    const rowActionsColumn = {
      id: _types.ROW_ACTIONS_COLUMN.ID,
      accessorKey: _types.ROW_ACTIONS_COLUMN.ID,
      header: () => null,
      cell: ({
        row,
        getRowActions,
        getRowFooterAction,
        keyboardNavCellId
      }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_customCells.TableRowActionsCell, {
        getRowActions: getRowActions || (() => []),
        getRowFooterAction: getRowFooterAction,
        row: row,
        rowActionsTriggerAriaLabel: localizationProps?.rowActionsTriggerAriaLabel,
        keyboardNavCellId: keyboardNavCellId
      }),
      size: _types.ROW_ACTIONS_COLUMN.SIZE,
      enableSorting: false,
      meta: {
        className: 'row-actions',
        hideFromSettings: true,
        ariaHidden: true,
        hideSeparator: true,
        hideMenu: true,
        truncateText: false,
        hasCustomCellAction: true,
        loader: {
          type: _skeleton.SKELETON_TYPES.CIRCULAR,
          width: 16,
          height: 16
        },
        cellAriaLabel: localizationProps?.tableRowActionsAriaLabel || t('Click to open row actions dropdown')
      }
    };
    const rowExpandToggleColumn = {
      id: _types.EXPAND_TOGGLE_COLUMN.ID,
      accessorKey: _types.EXPAND_TOGGLE_COLUMN.ID,
      header: () => null,
      cell: props => /*#__PURE__*/(0, _jsxRuntime.jsx)(_customCells.RowExpandCell, {
        ...props,
        expandRowButtonAriaLabel: localizationProps?.expandRowButtonAriaLabel
      }),
      size: _types.EXPAND_TOGGLE_COLUMN.SIZE,
      enableSorting: false,
      meta: {
        className: 'row-expand-toggle',
        ariaHidden: true,
        hideFromSettings: true,
        hideSeparator: true,
        hideMenu: true,
        truncateText: false,
        hasCustomCellAction: true,
        loader: {
          type: _skeleton.SKELETON_TYPES.CIRCULAR,
          width: 16,
          height: 16
        },
        cellAriaLabel: localizationProps?.expandRowCellAriaLabel || t('Click to expand the row')
      }
    };
    const actionsCellWidth = isRowActionsExist ? _types.ROW_ACTIONS_COLUMN.SIZE : 0;
    const checkBoxWidth = showCheckboxes ? _types.CHECKBOXES_COLUMN.SIZE : 0;
    const expandRowCellWidth = showExpandRow ? _types.EXPAND_TOGGLE_COLUMN.SIZE : 0;
    const columnsDelta = calculateDelta(columns, maxWidth, checkBoxWidth + actionsCellWidth + expandRowCellWidth, columnSizing, visibility);
    const updatedColumns = columns.map(col => ({
      minSize: col.minSize || _types.COLUMN_SIZE.MIN_WIDTH,
      maxSize: col.maxSize || _types.COLUMN_SIZE.MAX_WIDTH,
      size: columnSizing[col.accessorKey] || Math.max(_types.COLUMN_SIZE.WIDTH, col.minSize ?? 0) + (columnsDelta[col.accessorKey] ?? 0),
      ...col,
      meta: {
        truncateText: !col.cell,
        ...(col.meta || {})
      }
    }));
    return [...(showExpandRow ? [rowExpandToggleColumn] : []), ...(showCheckboxes ? [checkBoxColumn] : []), ...updatedColumns, ...(isRowActionsExist ? [rowActionsColumn] : [])];
  }, [maxWidth, visibility, showCheckboxes, isRowActionsExist, columns, showExpandRow]);
  return decoratedColumns;
}