"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.ToolbarResponsiveState = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _bexCore = require("@wix/bex-core");
var _mobx = require("mobx");
var _ToolbarResponsivePriorityState = require("./ToolbarResponsivePriorityState");
var _computeResponsiveTargetState = require("./computeResponsiveTargetState");
var _toolbarResponsiveConstants = require("./toolbarResponsiveConstants");
// Buffer (in px) added to the expand threshold to prevent flickering near the
// expand/collapse boundary. Tuned to ~2-3x the inter-element gap (SP2 = 12px) --
// large enough to absorb measurement rounding and flex reflow, small enough that
// the dead zone per group isn't visually noticeable during gradual resizing.
const EXPAND_THRESHOLD_BUFFER = 30;
class ToolbarResponsiveState {
  get container() {
    return this.toolbar.toolbar.container;
  }
  constructor(params) {
    (0, _defineProperty2.default)(this, "actions", void 0);
    (0, _defineProperty2.default)(this, "search", void 0);
    (0, _defineProperty2.default)(this, "filters", void 0);
    (0, _defineProperty2.default)(this, "_groups", void 0);
    (0, _defineProperty2.default)(this, "_shouldOverflow", false);
    (0, _defineProperty2.default)(this, "_measurementElement", null);
    (0, _defineProperty2.default)(this, "_contentElement", null);
    // Width of non-group content that is removed from the DOM during overflow
    // (e.g., tableGridSwitchButton). Must be accounted for in the exit-overflow
    // calculation to prevent flicker.
    (0, _defineProperty2.default)(this, "_overflowHiddenContentWidth", 0);
    (0, _defineProperty2.default)(this, "toolbar", void 0);
    (0, _defineProperty2.default)(this, "leftGroupState", null);
    (0, _defineProperty2.default)(this, "_recomputeThrottled", void 0);
    (0, _defineProperty2.default)(this, "_rafId", 0);
    this.toolbar = params.toolbar;
    this.actions = new _ToolbarResponsivePriorityState.ToolbarResponsivePriorityState({
      responsive: this
    });
    this.filters = new _ToolbarResponsivePriorityState.ToolbarResponsivePriorityState({
      responsive: this
    });
    this.search = new _ToolbarResponsivePriorityState.ToolbarResponsivePriorityState({
      responsive: this,
      expandedWidth: _toolbarResponsiveConstants.SEARCH_EXPANDED_WIDTH,
      collapsedWidth: _toolbarResponsiveConstants.SEARCH_COLLAPSED_WIDTH
    });
    this._groups = [this.actions, this.filters, this.search];
    (0, _mobx.makeObservable)(this, {
      _shouldOverflow: _mobx.observable.ref,
      _overflowHiddenContentWidth: _mobx.observable.ref,
      responsiveDisabled: _mobx.computed,
      _applyTargetState: _mobx.action
    });
  }
  get responsiveDisabled() {
    const {
      toolbar: {
        toolbar: {
          _syncedProps
        }
      },
      container: {
        internalExperiments
      }
    } = this;
    return !(_syncedProps != null && _syncedProps.useResponsiveLayout) || !(internalExperiments != null && internalExperiments.enabled('specs.cairo.EnableResponsiveToolbar11420'));
  }
  _scheduleRecompute() {
    var _this$_recomputeThrot;
    if (this.responsiveDisabled) {
      return;
    }
    (_this$_recomputeThrot = this._recomputeThrottled) == null || _this$_recomputeThrot.call(this);
  }
  _computeResponsiveInput() {
    var _this$leftGroupState;
    const el = this._measurementElement;
    const contentEl = this._contentElement;
    if (!el || !contentEl) {
      return null;
    }

    // The left group (title/tabs/views) has flex:1 and absorbs freed space when
    // right-side items shrink. Account for its excess width so the algorithm sees
    // the true available space and can expand items back when the container grows.
    const leftGroupExcess = ((_this$leftGroupState = this.leftGroupState) == null ? void 0 : _this$leftGroupState.getExcessWidth()) ?? 0;
    const containerWidth = el.clientWidth + leftGroupExcess;
    const contentWidth = contentEl.scrollWidth;
    const groups = this._groups.map(g => ({
      expandedWidth: g.expandedWidth,
      collapsedWidth: g.collapsedWidth,
      currentlyShrunk: g._shouldShrink
    }));

    // When overflowing, the overflowable groups are removed from the DOM and
    // replaced by the overflow button. Compute groupsTotal to reflect what the
    // algorithm expects (all groups at their current widths) so that
    // availableWidth = containerWidth - nonGroupContent is accurate.
    let groupsTotal;
    if (this._shouldOverflow) {
      // contentWidth includes the overflow button but not the overflowable groups.
      // groupsTotal must match: only non-overflowed groups + overflow button.
      const overflowableIndices = ToolbarResponsiveState._overflowableGroupIndices;
      const nonOverflowedTotal = groups.reduce((sum, g, i) => overflowableIndices.includes(i) ? sum : sum + (g.currentlyShrunk ? g.collapsedWidth : g.expandedWidth), 0);
      groupsTotal = nonOverflowedTotal + _toolbarResponsiveConstants.OVERFLOW_BUTTON_WIDTH;
    } else {
      groupsTotal = groups.reduce((sum, g) => sum + (g.currentlyShrunk ? g.collapsedWidth : g.expandedWidth), 0);
    }

    // nonGroupContent that is hidden during overflow but would reappear on exit.
    // Must be added back so the algorithm doesn't overestimate available space.
    const hiddenContentAdjustment = this._shouldOverflow ? this._overflowHiddenContentWidth : 0;
    return {
      availableWidth: containerWidth - (contentWidth - groupsTotal) - hiddenContentAdjustment,
      groups
    };
  }

  // Indices of groups that can be absorbed into the overflow menu.
  // actions = 0, filters = 1 (search = 2 stays visible).

  _applyTargetState() {
    const input = this._computeResponsiveInput();
    if (!input) {
      return;
    }
    const result = (0, _computeResponsiveTargetState.computeResponsiveTargetState)({
      ...input,
      expandThresholdBuffer: EXPAND_THRESHOLD_BUFFER,
      currentlyOverflowing: this._shouldOverflow,
      overflowButtonWidth: _toolbarResponsiveConstants.OVERFLOW_BUTTON_WIDTH,
      overflowableGroupIndices: ToolbarResponsiveState._overflowableGroupIndices
    });
    this._groups.forEach((g, i) => {
      g._shouldShrink = result.groups[i].shouldShrink;
    });
    this._shouldOverflow = result.shouldOverflow;
  }
  init() {
    const {
      responsiveDisabled
    } = this;
    if (responsiveDisabled) {
      return () => {};
    }
    this._recomputeThrottled = this.container.lodash.throttle(() => {
      this._rafId = window.requestAnimationFrame(() => {
        (0, _mobx.runInAction)(() => this._applyTargetState());
      });
    }, 200);
    const containerEl = this.toolbar.toolbar.toolbarRect.element;
    if (!containerEl) {
      return () => {
        var _this$_recomputeThrot2;
        (_this$_recomputeThrot2 = this._recomputeThrottled) == null || _this$_recomputeThrot2.cancel();
      };
    }
    const disposers = [(0, _bexCore.addResizeObserver)(containerEl, this._recomputeThrottled)];
    return () => {
      var _this$_recomputeThrot3;
      disposers.forEach(d => d == null ? void 0 : d());
      (_this$_recomputeThrot3 = this._recomputeThrottled) == null || _this$_recomputeThrot3.cancel();
      cancelAnimationFrame(this._rafId);
    };
  }
}
exports.ToolbarResponsiveState = ToolbarResponsiveState;
(0, _defineProperty2.default)(ToolbarResponsiveState, "_overflowableGroupIndices", [0, 1]);
//# sourceMappingURL=ToolbarResponsiveState.js.map