function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure 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 _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 _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

/*
Copyright (c) Uber Technologies, Inc.

This source code is licensed under the MIT license found in the
LICENSE file in the root directory of this source tree.
*/
import * as React from 'react';
import { useStyletron } from '../styles';
import HeaderCell from './header-cell';
import { useRef } from 'react'; // Measures the column header + sampled data

function MeasureColumn(_ref) {
  var sampleIndexes = _ref.sampleIndexes,
      column = _ref.column,
      columnIndex = _ref.columnIndex,
      rows = _ref.rows,
      isSelectable = _ref.isSelectable,
      onLayout = _ref.onLayout;

  var _useStyletron = useStyletron(),
      _useStyletron2 = _slicedToArray(_useStyletron, 1),
      css = _useStyletron2[0];

  var ref = useRef();
  React.useEffect(function () {
    if (typeof document !== 'undefined') {
      if (ref.current) {
        onLayout(columnIndex, ref.current.getBoundingClientRect());
      }
    }
  }, []);
  return /*#__PURE__*/React.createElement("div", {
    ref: ref,
    className: css({
      display: 'flex',
      flexDirection: 'column',
      width: 'fit-content'
    })
  }, /*#__PURE__*/React.createElement(HeaderCell, {
    index: columnIndex,
    isHovered: true,
    isMeasured: true,
    isSelectedAll: false,
    isSelectedIndeterminate: false,
    onMouseEnter: function onMouseEnter() {},
    onMouseLeave: function onMouseLeave() {},
    onSelectAll: function onSelectAll() {},
    onSelectNone: function onSelectNone() {},
    onSort: function onSort(i) {},
    sortable: column.sortable,
    sortDirection: null,
    title: column.title,
    isSelectable: isSelectable
  }), sampleIndexes.map(function (rowIndex, i) {
    var Cell = column.renderCell;
    return /*#__PURE__*/React.createElement(Cell, {
      key: "measure-".concat(i),
      value: column.mapDataToValue(rows[rowIndex].data),
      isSelectable: isSelectable,
      isMeasured: true,
      sortable: column.sortable,
      x: 0,
      y: rowIndex
    });
  }));
}

var MAX_SAMPLE_SIZE = 50;

function generateSampleIndices(inputMin, inputMax, maxSamples) {
  var indices = [];
  var queue = [[inputMin, inputMax]];

  while (queue.length > 0) {
    var _queue$shift = queue.shift(),
        _queue$shift2 = _slicedToArray(_queue$shift, 2),
        min = _queue$shift2[0],
        max = _queue$shift2[1];

    if (indices.length < maxSamples) {
      var pivot = Math.floor((min + max) / 2);
      indices.push(pivot);
      var left = pivot - 1;
      var right = pivot + 1;

      if (left >= min) {
        queue.push([min, left]);
      }

      if (right <= max) {
        queue.push([right, max]);
      }
    }
  }

  return indices;
}

export default function MeasureColumnWidths(_ref2) {
  var columns = _ref2.columns,
      rows = _ref2.rows,
      widths = _ref2.widths,
      isSelectable = _ref2.isSelectable,
      onWidthsChange = _ref2.onWidthsChange;

  var _useStyletron3 = useStyletron(),
      _useStyletron4 = _slicedToArray(_useStyletron3, 1),
      css = _useStyletron4[0];

  var widthMap = React.useMemo(function () {
    return new Map();
  }, []);
  var sampleSize = rows.length < MAX_SAMPLE_SIZE ? rows.length : MAX_SAMPLE_SIZE;
  var finishedMeasurementCount = (sampleSize + 1) * columns.length;
  var sampleIndexes = React.useMemo(function () {
    return generateSampleIndices(0, rows.length - 1, sampleSize);
  }, [columns, rows, widths, sampleSize]);
  var handleDimensionsChange = React.useCallback(function (columnIndex, dimensions) {
    var nextWidth = Math.min(Math.max(columns[columnIndex].minWidth || 0, widthMap.get(columnIndex) || 0, dimensions.width + 1), columns[columnIndex].maxWidth || Infinity);

    if (nextWidth !== widthMap.get(columnIndex)) {
      widthMap.set(columnIndex, nextWidth);
    }

    if ( // Refresh at 100% of done
    widthMap.size === columns.length || // ...50%
    widthMap.size === Math.floor(columns.length / 2) || // ...25%
    widthMap.size === Math.floor(columns.length / 4)) {
      onWidthsChange(Array.from(widthMap.values()));
    }
  }, [columns, finishedMeasurementCount, onWidthsChange]);
  var hiddenStyle = css({
    position: 'absolute',
    overflow: 'hidden',
    height: 0
  }); // Remove the measurement nodes after we are done updating our column width

  if (widthMap.size === columns.length) {
    return null;
  }

  return (
    /*#__PURE__*/
    // eslint-disable-next-line jsx-a11y/role-supports-aria-props
    React.createElement("div", {
      className: hiddenStyle,
      "aria-hidden": true,
      role: "none"
    }, columns.map(function (column, i) {
      return /*#__PURE__*/React.createElement(MeasureColumn, {
        key: column.title + i,
        column: column,
        rows: rows,
        isSelectable: isSelectable,
        onLayout: handleDimensionsChange,
        columnIndex: i,
        sampleIndexes: sampleIndexes
      });
    }))
  );
}