import { act } from '@testing-library/react';
import { setImmediate } from 'timers';

export async function flush(iterations = 5) {
  for (let i = 0; i < iterations; i++) {
    await act(async () => {
      await new Promise((resolve) => setImmediate(resolve));
      jest.runOnlyPendingTimers();
    });
  }
}

export async function flushPromise<T>(promise: T, iterations = 3) {
  for (let i = 0; i < iterations; i++) {
    await act(async () => {
      await new Promise((resolve) => setImmediate(resolve));
      jest.runOnlyPendingTimers();
    });
  }

  return promise;
}

export async function flushImmediate<T>(promise: T, iterations = 3) {
  for (let i = 0; i < iterations; i++) {
    await act(async () => {
      await new Promise((resolve) => setImmediate(resolve));
      jest.runAllImmediates();
    });
  }

  return promise;
}

export async function advance<T>(ms: number, promise?: T) {
  await act(async () => {
    await new Promise((resolve) => setImmediate(resolve));
    jest.advanceTimersByTime(ms);
    await promise;
  });
}
