export function buildCumulativeOffsets(heights: number[]): number[] {
  const offsets = new Array(heights.length + 1);
  offsets[0] = 0;
  for (let i = 0; i < heights.length; i++) {
    offsets[i + 1] = offsets[i] + heights[i];
  }
  return offsets;
}

export function findVisibleRange(
  cumulativeOffsets: number[],
  itemCount: number,
  scrollTop: number,
  viewportHeight: number,
  buffer = 4,
) {
  if (!cumulativeOffsets.length || itemCount === 0 || viewportHeight <= 0) {
    return { start: 0, end: 0 };
  }

  let lo = 0;
  let hi = itemCount - 1;
  while (lo < hi) {
    const mid = (lo + hi) >>> 1;
    if (cumulativeOffsets[mid + 1] < scrollTop) {
      lo = mid + 1;
    } else {
      hi = mid;
    }
  }
  const start = Math.max(0, lo - buffer);

  const endScroll = scrollTop + viewportHeight;
  lo = start;
  hi = itemCount - 1;
  while (lo < hi) {
    const mid = (lo + hi) >>> 1;
    if (cumulativeOffsets[mid] < endScroll) {
      lo = mid + 1;
    } else {
      hi = mid;
    }
  }

  return {
    start,
    end: Math.min(itemCount, lo + buffer),
  };
}
