/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 * @format
 */
'use strict';

import invariant from 'fbjs/lib/invariant';
export type ViewToken = {
  item: any,
  key: string,
  index: ?number,
  isViewable: boolean,
  section?: any,
};
export type ViewabilityConfigCallbackPair = {
  viewabilityConfig: ViewabilityConfig,
  onViewableItemsChanged: (info: {
    viewableItems: Array<ViewToken>,
    changed: Array<ViewToken>,
  }) => void,
};
export type ViewabilityConfig = {|
  /**
   * Minimum amount of time (in milliseconds) that an item must be physically viewable before the
   * viewability callback will be fired. A high number means that scrolling through content without
   * stopping will not mark the content as viewable.
   */
  minimumViewTime?: number,
  /**
   * Percent of viewport that must be covered for a partially occluded item to count as
   * "viewable", 0-100. Fully visible items are always considered viewable. A value of 0 means
   * that a single pixel in the viewport makes the item viewable, and a value of 100 means that
   * an item must be either entirely visible or cover the entire viewport to count as viewable.
   */
  viewAreaCoveragePercentThreshold?: number,
  /**
   * Similar to `viewAreaPercentThreshold`, but considers the percent of the item that is visible,
   * rather than the fraction of the viewable area it covers.
   */
  itemVisiblePercentThreshold?: number,
  /**
   * Nothing is considered viewable until the user scrolls or `recordInteraction` is called after
   * render.
   */
  waitForInteraction?: boolean,
|};

/**
 * A Utility class for calculating viewable items based on current metrics like scroll position and
 * layout.
 *
 * An item is said to be in a "viewable" state when any of the following
 * is true for longer than `minimumViewTime` milliseconds (after an interaction if `waitForInteraction`
 * is true):
 *
 * - Occupying >= `viewAreaCoveragePercentThreshold` of the view area XOR fraction of the item
 *   visible in the view area >= `itemVisiblePercentThreshold`.
 * - Entirely visible on screen
 */
declare class ViewabilityHelper {
  _config: ViewabilityConfig,
  _hasInteracted: boolean,
  _timers: Set<TimeoutID>,
  _viewableIndices: Array<number>,
  _viewableItems: Map<string, ViewToken>,
  constructor(config: ViewabilityConfig): any,
  dispose(): any,
  computeViewableItems(itemCount: number, scrollOffset: number, viewportHeight: number, getFrameMetrics: (index: number) => ?{
    length: number,
    offset: number,
  }, renderRange?: {
    first: number,
    last: number,
  }): Array<number>,
  onUpdate(itemCount: number, scrollOffset: number, viewportHeight: number, getFrameMetrics: (index: number) => ?{
    length: number,
    offset: number,
  }, createViewToken: (index: number, isViewable: boolean) => ViewToken, onViewableItemsChanged: ({
    viewableItems: Array<ViewToken>,
    changed: Array<ViewToken>,
  }) => void, renderRange?: {
    first: number,
    last: number,
  }): void,
  resetViewableIndices(): any,
  recordInteraction(): any,
  _onUpdateSync(viewableIndicesToCheck: any, onViewableItemsChanged: any, createViewToken: any): any,
}
declare function _isViewable(viewAreaMode: boolean, viewablePercentThreshold: number, top: number, bottom: number, viewportHeight: number, itemLength: number): boolean;
declare function _getPixelsVisible(top: number, bottom: number, viewportHeight: number): number;
declare function _isEntirelyVisible(top: number, bottom: number, viewportHeight: number): boolean;
export default ViewabilityHelper;