import Vue from "vue";

// const ignoreComponents = [undefined, "transition", "router-link", "Bar"];

// const ignoreComponentsNameRegexArray = [/^El[A-Z].*/, /^fa-.*/];

// const groupCollapsed = true;

// const RENDER_DURATION = 1 * 1000;

export default function ({
  ignoreComponents = [undefined, "transition", "router-link", "Bar"],
  ignoreComponentsNameRegexArray = [/^El[A-Z].*/, /^fa-.*/],
  groupCollapsed = true,
  RENDER_DURATION = 1 * 1000,
}) {
  function getParentNumber(that) {
    let parentNumber = 0;
    while (that) {
      if (that.$parent) {
        parentNumber++;
        that = that.$parent;
      } else {
        break;
      }
    }
    return parentNumber;
  }

  function componentNameMatch(name) {
    if (ignoreComponents.includes(name)) {
      return true;
    } else {
      let match = false;
      for (const regex of ignoreComponentsNameRegexArray) {
        if (regex.test(name)) {
          match = true;
          break;
        }
      }
      return match;
    }
  }

  const injectMethods = [
    { name: "beforeCreate", style: "color: green" },
    { name: "created", style: "color: green" },
    { name: "beforeMount", style: "color: green" },
    { name: "mounted", style: "color: green" },
    { name: "beforeUpdate", style: "color: #0000aa" },
    { name: "updated", style: "color: #0000aa" },
    { name: "beforeDestroy", style: "color: red; font-weight: bold" },
    { name: "destroyed", style: "color: red; font-weight: bold" },
  ];

  const injectRouterMethods = [
    {
      name: "beforeRouteEnter",
      style: ["background: #aaa", "color: #0000aa;"],
    },
    {
      name: "beforeRouteUpdate",
      style: ["background: #aaa", "color: #0000aa;"],
    },
    {
      name: "beforeRouteLeave",
      style: ["background: #aaa", "color: #0000aa;"],
    },
  ];

  let lifeCycleMixins = {};

  let startLogging = false;
  let loggingTime = Date.now();

  for (const m of injectMethods) {
    lifeCycleMixins[m.name] = function () {
      const parentNumber = getParentNumber(this);
      if (!componentNameMatch(this.$options.name)) {
        if (!startLogging) {
          startLogging = true;
          if (groupCollapsed) {
            console.groupCollapsed("Vue lifecyle logs");
          } else {
            console.group("Vue lifecyle logs");
          }

          loggingTime = Date.now();
        }
        console.log(
          "--".repeat(parentNumber) + `${this.$options.name} %c ${m.name}`,
          m.style
        );
      }
    };
  }

  for (const m of injectRouterMethods) {
    lifeCycleMixins[m.name] = function (to, from, next) {
      if (!startLogging) {
        startLogging = true;
        if (groupCollapsed) {
          console.groupCollapsed("Vue lifecyle logs");
        } else {
          console.group("Vue lifecyle logs");
        }

        loggingTime = Date.now();
      }

      console.log(
        "%c " +
          from.fullPath +
          " --> " +
          to.fullPath +
          (this ? ` (${this.$options.name}) ` : " ") +
          `%c ${m.name}`,
        ...m.style
      );

      next();
    };
  }

  // setInterval(
  //   () => console.log("----------------------Vue lifecyle logs----------------"),
  //   10 * 1000
  // );
  setInterval(() => {
    if (startLogging && Date.now() - loggingTime > RENDER_DURATION) {
      console.groupEnd();
      startLogging = false;
    }
  }, 1 * 100);

  Vue.mixin({
    ...lifeCycleMixins,
  });
}
