import { useEffect, useState } from "react";

export interface ICountDown {
  m: number;
  s: number;
}
/**
 *
 * @param minutes how many minutes.
 * @param autoplay by default true. if you want play coundDown after an action, you can set it to false and manually play it.
 * @param onEnd you can pass a callback function that will trigger at the END.
 * @returns
 */

export function useCountDown(
  minutes: number,
  autoplay = true,
  onEnd = () => {}
) {
  const [countDown, setCountDown] = useState<ICountDown>({ m: minutes, s: 0 });
  const [stop, setStop] = useState<boolean>(!autoplay);

  useEffect(() => {
    const handler = setTimeout(() => {
      if (countDown.m !== 0 || countDown.s !== 0) {
        setCountDown(calculateCountDown(countDown));
      } else {
        onEnd();
      }
    }, 1000);

    return () => {
      clearTimeout(handler);
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [countDown]);

  const reset = () => {
    setCountDown({ m: minutes, s: 0 });
  };
  const pause = () => {
    setStop(true);
  };
  const play = () => {
    setStop(false);
    setCountDown({ ...countDown });
  };

  const calculateCountDown = (st: ICountDown): ICountDown => {
    if (stop) {
      return countDown;
    }
    const timeLeft = { m: 0, s: 0 };
    const remain = st.m * 60 + st.s - 1;
    if (remain > 0) {
      timeLeft.m = Math.floor(remain / 60);
      timeLeft.s = remain - timeLeft.m * 60;
      return timeLeft;
    } else {
      if (remain === 0 && countDown.s === 1) {
        return timeLeft;
      } else {
        return countDown;
      }
    }
  };

  return {
    value: `${countDown.m > 9 ? countDown.m : "0" + countDown.m}:${
      countDown.s > 9 ? countDown.s : "0" + countDown.s
    }`,
    reset,
    pause,
    play,
  };
}
