import { onBeforeUnmount } from "vue";

/**
 * 自动添加和清除timer
 */
export function useTimers() {
  const mixin__intervals: number[] = [];
  const mixin__timeouts: number[] = [];
  const atTime = new Date().toLocaleTimeString();
  const atUrl = window.location.pathname;

  /**
   * 会在 beforeDestory 中自动清除
   * @param {function} fn 要执行的函数
   * @param {number} interval 执行间隔ms
   *
   * @returns intervalId 供主动清除
   */
  // eslint-disable-next-line @typescript-eslint/ban-types
  function addInterval(fn: Function, interval: number) {
    const i = setInterval(fn, interval);
    mixin__intervals.push(i);
    logger({
      cnl: ["server", "console"],
      // pgu: "AUTO",
      lvl: "debug",
      act: "addInterval",
      ext: {
        atTime,
        atUrl,
        i,
        mixin__intervals: mixin__intervals.toString(),
        mixin__timeouts: mixin__timeouts.toString(),
      },
    });

    return i;
  }
  /**
   * 会在 beforeDestory 中自动清除
   * @param {function} fn 要执行的函数
   * @param {number} timeout 触发时间ms
   *
   * * @returns timeoutId 供主动清除
   */
  // eslint-disable-next-line @typescript-eslint/ban-types
  function addTimeout(fn: Function, timeout: number) {
    const i = setTimeout(fn, timeout);
    mixin__timeouts.push(i);

    logger({
      cnl: ["server", "console"],
      // pgu: "AUTO",
      lvl: "debug",
      act: "addTimeout",
      ext: {
        atTime,
        atUrl,
        i,
        mixin__intervals: mixin__intervals.toString(),
        mixin__timeouts: mixin__timeouts.toString(),
      },
    });

    return i;
  }

  onBeforeUnmount(() => {
    if (mixin__intervals.length === 0 && mixin__timeouts.length === 0) return;
    logger({
      cnl: ["server", "console"],
      // pgu: "AUTO",
      lvl: "debug",
      act: "clearTimers",
      ext: {
        atTime,
        atUrl,
        mixin__intervals: mixin__intervals.toString(),
        mixin__timeouts: mixin__timeouts.toString(),
      },
    });
    for (const i of mixin__intervals) {
      clearInterval(i);
    }
    for (const i of mixin__timeouts) {
      clearTimeout(i);
    }
  });

  return {
    addInterval,
    addTimeout,
  };
}
