import { __extends, __assign, __spreadArray, __decorate, __metadata } from 'tslib';
import { Prop, Component } from 'vue-property-decorator';
import BaseComponent from '../BaseComponent.js';
import { classNamesFunction } from '@uifabric-vue/utilities';
import { DEFAULT_CELL_STYLE_PROPS } from './DetailsRow/DetailsRow.styles.js';
import { List } from '../List/List.js';
import { DetailsRow } from './DetailsRow/DetailsRow.js';
import { DetailsHeader } from './DetailsHeader/DetailsHeader.js';

var getClassNames = classNamesFunction();
var DetailsListBase = function(_super) {
  __extends(DetailsListBase2, _super);
  function DetailsListBase2() {
    var _this = _super !== null && _super.apply(this, arguments) || this;
    _this.lastWidth = -1;
    _this.lastSelectionMode = void 0;
    _this.columnOverrides = {};
    _this.lastSortedColumnKey = "";
    return _this;
  }
  DetailsListBase2.prototype.render = function(h) {
    var _this = this;
    var _a = this, classNames = _a.classNames, items = _a.items, adjustedColumns = _a.adjustedColumns, compact = _a.compact;
    return h("div", {
      class: classNames.root,
      attrs: {
        dataIsScrollable: "false"
      }
    }, [
      h("div", { attrs: { role: "grid" } }, [
        h("div", { class: classNames.headerWrapper }, [
          this.$scopedSlots.DetailsHeader ? this.$scopedSlots.DetailsHeader({ defaultRender: this.onRenderDetailsHeader }) : this.onRenderDetailsHeader()
        ]),
        h("div", { class: classNames.contentWrapper }, [
          h(List, {
            ref: "list",
            attrs: {
              role: "presentation",
              items: items
            },
            scopedSlots: {
              item: function(_a2) {
                var item = _a2.item;
                return h(DetailsRow, {
                  attrs: {
                    item: item,
                    columns: adjustedColumns,
                    compact: compact
                  },
                  scopedSlots: _this.$scopedSlots,
                  on: {
                    click: function(ev) {
                      return _this.$emit("item-clicked", ev, item);
                    }
                  }
                });
              }
            }
          })
        ])
      ])
    ]);
  };
  Object.defineProperty(DetailsListBase2.prototype, "classNames", {
    get: function() {
      var _a = this, styles = _a.styles, theme = _a.theme, className = _a.className, compact = _a.compact;
      return getClassNames(styles, {
        theme: theme,
        compact: compact,
        isFixed: false,
        isHorizontalConstrained: false,
        className: className
      });
    },
    enumerable: false,
    configurable: true
  });
  Object.defineProperty(DetailsListBase2.prototype, "adjustedColumns", {
    get: function() {
      return this._adjustColumns(this.$props);
    },
    enumerable: false,
    configurable: true
  });
  DetailsListBase2.prototype.onRenderDetailsHeader = function() {
    var h = this.$createElement;
    return h(DetailsHeader, { attrs: { columns: this.adjustedColumns } });
  };
  DetailsListBase2.prototype.created = function() {
    var _this = this;
    var DEFAULT_COLUMN = {
      key: "",
      name: "",
      fieldName: "",
      className: "",
      styles: null,
      minWidth: 0,
      ariaLabel: "",
      isRowHeader: false,
      maxWidth: 0,
      columnActionsMode: 1,
      iconName: "",
      isIconOnly: false,
      iconClassName: "",
      isCollapsible: false,
      isSorted: false,
      isSortedDescending: false,
      isResizable: false,
      isMultiline: false,
      onRender: null,
      getValueKey: null,
      isFiltered: false,
      onColumnClick: null,
      onColumnContextMenu: null,
      onColumnResize: null,
      isGrouped: false,
      data: {},
      calculatedWidth: 0,
      currentWidth: 0,
      headerClassName: "",
      isPadded: false,
      sortAscendingAriaLabel: "",
      sortDescendingAriaLabel: "",
      groupAriaLabel: "",
      filterAriaLabel: "",
      isMenuOpen: false
    };
    var _loop_1 = function(key2) {
      if (Object.prototype.hasOwnProperty.call(DEFAULT_COLUMN, key2)) {
        var value_1 = DEFAULT_COLUMN[key2];
        this_1.columns.forEach(function(col) {
          _this.$set(col, key2, col[key2] !== void 0 ? col[key2] : value_1);
        });
      }
    };
    var this_1 = this;
    for (var key in DEFAULT_COLUMN) {
      _loop_1(key);
    }
  };
  DetailsListBase2.prototype._rememberCalculatedWidth = function(column, newCalculatedWidth) {
    var overrides = this._getColumnOverride(column.key);
    overrides.calculatedWidth = newCalculatedWidth;
    overrides.currentWidth = newCalculatedWidth;
  };
  DetailsListBase2.prototype._getColumnOverride = function(key) {
    return this.columnOverrides[key] = this.columnOverrides[key] || {};
  };
  DetailsListBase2.prototype._adjustColumns = function(newProps, forceUpdate, resizingColumnIndex) {
    var adjustedColumns = this._getAdjustedColumns(newProps, forceUpdate, resizingColumnIndex);
    var viewportWidth = 1e3;
    if (adjustedColumns) {
      this.lastWidth = viewportWidth;
    }
    return adjustedColumns;
  };
  DetailsListBase2.prototype._getAdjustedColumns = function(newProps, forceUpdate, resizingColumnIndex) {
    var _this = this;
    var newItems = newProps.items, layoutMode = newProps.layoutMode, selectionMode = newProps.selectionMode, viewport = newProps.viewport;
    var viewportWidth = viewport && viewport.width ? viewport.width : 0;
    var newColumns = newProps.columns;
    var columns = this ? this.columns : [];
    var lastWidth = this ? this.lastWidth : -1;
    var lastSelectionMode = this ? this.lastSelectionMode : void 0;
    if (!forceUpdate && lastWidth === viewportWidth && lastSelectionMode === selectionMode && (!columns || newColumns === columns)) {
      return [];
    }
    newColumns = newColumns || buildColumns(newItems, true);
    var adjustedColumns;
    if (layoutMode !== 0) {
      adjustedColumns = this._getFixedColumns(newColumns);
      adjustedColumns.forEach(function(column) {
        _this._rememberCalculatedWidth(column, column.calculatedWidth);
      });
    } else {
      if (resizingColumnIndex !== void 0) {
        adjustedColumns = this._getJustifiedColumnsAfterResize(newColumns, viewportWidth, newProps, resizingColumnIndex);
      } else {
        adjustedColumns = this._getJustifiedColumns(newColumns, viewportWidth, newProps, 0);
      }
      adjustedColumns.forEach(function(column) {
        _this._getColumnOverride(column.key).currentWidth = column.calculatedWidth;
      });
    }
    return adjustedColumns;
  };
  DetailsListBase2.prototype._getFixedColumns = function(newColumns) {
    var _this = this;
    return newColumns.map(function(column) {
      var newColumn = __assign(__assign({}, column), _this.columnOverrides[column.key]);
      if (!newColumn.calculatedWidth) {
        newColumn.calculatedWidth = newColumn.maxWidth || newColumn.minWidth || MIN_COLUMN_WIDTH;
      }
      return newColumn;
    });
  };
  DetailsListBase2.prototype._getJustifiedColumnsAfterResize = function(newColumns, viewportWidth, props, resizingColumnIndex) {
    var _this = this;
    var fixedColumns = newColumns.slice(0, resizingColumnIndex);
    fixedColumns.forEach(function(column) {
      return column.calculatedWidth = _this._getColumnOverride(column.key).currentWidth;
    });
    var fixedWidth = fixedColumns.reduce(function(total, column, i) {
      return total + getPaddedWidth(column, i === 0, props);
    }, 0);
    var remainingColumns = newColumns.slice(resizingColumnIndex);
    var remainingWidth = viewportWidth - fixedWidth;
    return __spreadArray(__spreadArray([], fixedColumns, true), this._getJustifiedColumns(remainingColumns, remainingWidth, props, resizingColumnIndex), true);
  };
  DetailsListBase2.prototype._getJustifiedColumns = function(newColumns, viewportWidth, props, firstIndex) {
    var _this = this;
    var _a = props.selectionMode, selectionMode = _a === void 0 ? 0 : _a, checkboxVisibility = props.checkboxVisibility;
    var rowCheckWidth = selectionMode !== 0 && checkboxVisibility !== checkboxVisibility.hidden ? 10 : 0;
    var groupExpandWidth = 1 * 10;
    var totalWidth = 0;
    var availableWidth = viewportWidth - (rowCheckWidth + groupExpandWidth);
    var adjustedColumns = newColumns.map(function(column2, i2) {
      var newColumn = __assign(__assign(__assign({}, column2), { calculatedWidth: column2.minWidth || MIN_COLUMN_WIDTH }), _this.columnOverrides[column2.key]);
      var isFirst = i2 + firstIndex === 0;
      totalWidth += getPaddedWidth(newColumn, isFirst, props);
      return newColumn;
    });
    var lastIndex = adjustedColumns.length - 1;
    while (lastIndex > 0 && totalWidth > availableWidth) {
      var column = adjustedColumns[lastIndex];
      var minWidth = column.minWidth || MIN_COLUMN_WIDTH;
      var overflowWidth = totalWidth - availableWidth;
      if (column.calculatedWidth - minWidth >= overflowWidth || !(column.isCollapsible || column.isCollapsable)) {
        var originalWidth = column.calculatedWidth;
        column.calculatedWidth = Math.max(column.calculatedWidth - overflowWidth, minWidth);
        totalWidth -= originalWidth - column.calculatedWidth;
      } else {
        totalWidth -= getPaddedWidth(column, false, props);
        adjustedColumns.splice(lastIndex, 1);
      }
      lastIndex--;
    }
    for (var i = 0; i < adjustedColumns.length && totalWidth < availableWidth; i++) {
      var column = adjustedColumns[i];
      var isLast = i === adjustedColumns.length - 1;
      var overrides = this.columnOverrides[column.key];
      if (overrides && overrides.calculatedWidth && !isLast) {
        continue;
      }
      var spaceLeft = availableWidth - totalWidth;
      var increment = void 0;
      if (isLast) {
        increment = spaceLeft;
      } else {
        var maxWidth = column.maxWidth;
        var minWidth = column.minWidth || maxWidth || MIN_COLUMN_WIDTH;
        increment = maxWidth ? Math.min(spaceLeft, maxWidth - minWidth) : spaceLeft;
      }
      column.calculatedWidth = column.calculatedWidth + increment;
      totalWidth += increment;
    }
    return adjustedColumns;
  };
  __decorate([
    Prop({ type: Array, required: true }),
    __metadata("design:type", Array)
  ], DetailsListBase2.prototype, "columns", void 0);
  __decorate([
    Prop({ type: Array, default: function() {
      return [];
    } }),
    __metadata("design:type", Array)
  ], DetailsListBase2.prototype, "items", void 0);
  __decorate([
    Prop({ type: Boolean, default: false }),
    __metadata("design:type", Boolean)
  ], DetailsListBase2.prototype, "compact", void 0);
  DetailsListBase2 = __decorate([
    Component
  ], DetailsListBase2);
  return DetailsListBase2;
}(BaseComponent);
var MIN_COLUMN_WIDTH = 100;
function buildColumns(items, canResizeColumns, onColumnClick, sortedColumnKey, isSortedDescending, groupedColumnKey, isMultiline) {
  var columns = [];
  if (items && items.length) {
    var firstItem = items[0];
    for (var propName in firstItem) {
      if (Object.prototype.hasOwnProperty.call(firstItem, propName)) {
        columns.push({
          key: propName,
          name: propName,
          fieldName: propName,
          minWidth: MIN_COLUMN_WIDTH,
          maxWidth: 300,
          isCollapsable: !!columns.length,
          isCollapsible: !!columns.length,
          isMultiline: isMultiline === void 0 ? false : isMultiline,
          isSorted: sortedColumnKey === propName,
          isSortedDescending: !!isSortedDescending,
          isRowHeader: false,
          columnActionsMode: 0,
          isResizable: canResizeColumns,
          onColumnClick: onColumnClick,
          isGrouped: groupedColumnKey === propName
        });
      }
    }
  }
  return columns;
}
function getPaddedWidth(column, isFirst, props) {
  var _a = props.cellStyleProps, cellStyleProps = _a === void 0 ? DEFAULT_CELL_STYLE_PROPS : _a;
  return column.calculatedWidth + cellStyleProps.cellLeftPadding + cellStyleProps.cellRightPadding + (column.isPadded ? cellStyleProps.cellExtraRightPadding : 0);
}

export { DetailsListBase, buildColumns };
