export type QueryParams = Record<string, string | number | boolean | undefined>;

const CommonUtil = {
  between(x: number, min: number, max: number) {
    return x >= min && x <= max;
  },
  futureDateByHours(hours: number): Date {
    return this.futureDateByMinutes(this.hoursToMinutes(hours));
  },
  futureDateByMinutes(minutes: number): Date {
    const MINUTES_EXTRA_PADDING = 1;
    const minutesInFuture = minutes + MINUTES_EXTRA_PADDING;
    return new Date(
      new Date().setMinutes(new Date().getMinutes() + minutesInFuture),
    );
  },
  futureDateBySeconds(secondsInFuture: number) {
    return new Date(
      new Date().setSeconds(new Date().getSeconds() + secondsInFuture),
    );
  },
  hoursToMinutes(hours: number) {
    return hours * 60;
  },
  minutesToMs: (minutes: number) => minutes * 60_000,
  minutesToSeconds(minutes: number) {
    return minutes * 60;
  },
  query: (params: QueryParams) =>
    Object.entries(params)
      .map(([paramKey, paramValue]) => {
        if (
          // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
          paramKey === undefined ||
          paramKey === "undefined" ||
          paramValue === undefined
        ) {
          return null;
        }
        const [key, value] = [
          encodeURIComponent(paramKey),
          encodeURIComponent(paramValue),
        ];
        return `${key}=${value}`;
      })
      .filter((value) => value !== null)
      .join("&"),
  random: (min: number, max: number) =>
    Math.floor(Math.random() * (max - min + 1) + min),
  async sleep(ms: number) {
    return new Promise((resolve) => setTimeout(resolve, ms));
  },
  async sleepRandom(ms: number) {
    return this.sleep(this.random(ms, ms + ms * 0.2));
  },
};

export default CommonUtil;
