function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
// @ts-nocheck

import CustomError from "../errors/CustomError";
import ExceptionList from "../errors/ExceptionList";

/**
 * Helper class for computing viewable items based on the passed `viewabilityConfig`.
 * Note methods in this class will be invoked on every scroll and should be optimized for performance.
 */
class ViewabilityHelper {
  constructor(viewabilityConfig, viewableIndicesChanged) {
    /**
     * Viewable indices regardless of the viewability config
     */
    _defineProperty(this, "possiblyViewableIndices", []);
    _defineProperty(this, "hasInteracted", false);
    _defineProperty(this, "viewableIndices", []);
    _defineProperty(this, "lastReportedViewableIndices", []);
    _defineProperty(this, "viewabilityConfig", void 0);
    _defineProperty(this, "viewableIndicesChanged", void 0);
    _defineProperty(this, "timers", new Set());
    this.viewabilityConfig = viewabilityConfig;
    this.viewableIndicesChanged = viewableIndicesChanged;
  }
  dispose() {
    // Clean up on dismount
    this.timers.forEach(clearTimeout);
  }
  updateViewableItems(horizontal, scrollOffset, listSize, getLayout, viewableIndices) {
    var _this$viewabilityConf, _this$viewabilityConf2, _this$viewabilityConf3, _this$viewabilityConf4, _this$viewabilityConf5, _this$viewabilityConf6, _this$viewabilityConf9, _this$viewabilityConf10;
    if (viewableIndices !== undefined) {
      this.possiblyViewableIndices = viewableIndices;
    }
    if (((_this$viewabilityConf = this.viewabilityConfig) === null || _this$viewabilityConf === void 0 ? void 0 : _this$viewabilityConf.itemVisiblePercentThreshold) !== null && ((_this$viewabilityConf2 = this.viewabilityConfig) === null || _this$viewabilityConf2 === void 0 ? void 0 : _this$viewabilityConf2.itemVisiblePercentThreshold) !== undefined && ((_this$viewabilityConf3 = this.viewabilityConfig) === null || _this$viewabilityConf3 === void 0 ? void 0 : _this$viewabilityConf3.viewAreaCoveragePercentThreshold) !== null && ((_this$viewabilityConf4 = this.viewabilityConfig) === null || _this$viewabilityConf4 === void 0 ? void 0 : _this$viewabilityConf4.viewAreaCoveragePercentThreshold) !== undefined) {
      throw new CustomError(ExceptionList.multipleViewabilityThresholdTypesNotSupported);
    }
    if (((_this$viewabilityConf5 = (_this$viewabilityConf6 = this.viewabilityConfig) === null || _this$viewabilityConf6 === void 0 ? void 0 : _this$viewabilityConf6.waitForInteraction) !== null && _this$viewabilityConf5 !== void 0 ? _this$viewabilityConf5 : false) && !this.hasInteracted) {
      return;
    }
    const newViewableIndices = this.possiblyViewableIndices.filter(index => {
      var _this$viewabilityConf7, _this$viewabilityConf8;
      return this.isItemViewable(index, horizontal, scrollOffset, listSize, (_this$viewabilityConf7 = this.viewabilityConfig) === null || _this$viewabilityConf7 === void 0 ? void 0 : _this$viewabilityConf7.viewAreaCoveragePercentThreshold, (_this$viewabilityConf8 = this.viewabilityConfig) === null || _this$viewabilityConf8 === void 0 ? void 0 : _this$viewabilityConf8.itemVisiblePercentThreshold, getLayout);
    });
    this.viewableIndices = newViewableIndices;
    const minimumViewTime = (_this$viewabilityConf9 = (_this$viewabilityConf10 = this.viewabilityConfig) === null || _this$viewabilityConf10 === void 0 ? void 0 : _this$viewabilityConf10.minimumViewTime) !== null && _this$viewabilityConf9 !== void 0 ? _this$viewabilityConf9 : 250;
    // Setting default to 250. Default of 0 can impact performance when user scrolls fast.
    if (minimumViewTime > 0) {
      const timeoutId = setTimeout(() => {
        this.timers.delete(timeoutId);
        this.checkViewableIndicesChanges(newViewableIndices);
        this.timers.add(timeoutId);
      }, minimumViewTime);
    } else {
      this.checkViewableIndicesChanges(newViewableIndices);
    }
  }
  checkViewableIndicesChanges(newViewableIndices) {
    // Check if all viewable indices are still available (applicable if minimumViewTime > 0)
    const currentlyNewViewableIndices = newViewableIndices.filter(index => this.viewableIndices.includes(index));
    const newlyVisibleItems = currentlyNewViewableIndices.filter(index => !this.lastReportedViewableIndices.includes(index));
    const newlyNonvisibleItems = this.lastReportedViewableIndices.filter(index => !currentlyNewViewableIndices.includes(index));
    if (newlyVisibleItems.length > 0 || newlyNonvisibleItems.length > 0) {
      this.lastReportedViewableIndices = currentlyNewViewableIndices;
      this.viewableIndicesChanged(currentlyNewViewableIndices, newlyVisibleItems, newlyNonvisibleItems);
    }
  }
  isItemViewable(index, horizontal, scrollOffset, listSize, viewAreaCoveragePercentThreshold, itemVisiblePercentThreshold, getLayout) {
    const itemLayout = getLayout(index);
    if (itemLayout === undefined) {
      return false;
    }
    const itemTop = (horizontal ? itemLayout.x : itemLayout.y) - scrollOffset;
    const itemSize = horizontal ? itemLayout.width : itemLayout.height;
    const listMainSize = horizontal ? listSize.width : listSize.height;
    const pixelsVisible = Math.min(itemTop + itemSize, listMainSize) - Math.max(itemTop, 0);

    // Always consider item fully viewable if it is fully visible, regardless of the `viewAreaCoveragePercentThreshold`
    if (pixelsVisible === itemSize) {
      return true;
    }
    // Skip checking item if it's not visible at all
    if (pixelsVisible === 0) {
      return false;
    }
    const viewAreaMode = viewAreaCoveragePercentThreshold !== null && viewAreaCoveragePercentThreshold !== undefined;
    const percent = viewAreaMode ? pixelsVisible / listMainSize : pixelsVisible / itemSize;
    const viewableAreaPercentThreshold = viewAreaMode ? viewAreaCoveragePercentThreshold * 0.01 : (itemVisiblePercentThreshold !== null && itemVisiblePercentThreshold !== void 0 ? itemVisiblePercentThreshold : 0) * 0.01;
    return percent >= viewableAreaPercentThreshold;
  }
}
export default ViewabilityHelper;
//# sourceMappingURL=ViewabilityHelper.js.map