import { getLoginURLNext, shouldUseSSO } from "@/router/utils";
import { useCourseSessionsStore } from "@/stores/courseSessions";
import { useUserStore } from "@/stores/user";
import type { NavigationGuard, RouteLocationNormalized } from "vue-router";

export const updateLoggedIn: NavigationGuard = async () => {
  const loggedIn = getCookieValue("loginStatus") === "true";
  const userStore = useUserStore();

  userStore.$patch({ loggedIn });
  if (loggedIn && !userStore.id) {
    await userStore.fetchUser();
  }
};

export const redirectToLoginIfRequired: NavigationGuard = (to, from, next) => {
  const user = useUserStore();

  // redirect guests to /start if they access /
  if (!user.loggedIn && to.path === "/") {
    return next("/start");
  }

  if (loginRequired(to) && !user.loggedIn) {
    const loginURL = getLoginURLNext();
    if (shouldUseSSO()) {
      // Redirect to SSO login page, handled by the server
      window.location.href = loginURL;
    } else {
      // Handle local login with Vue router
      next(loginURL);
    }
  } else {
    // If login is not required or user is already logged in, continue with the navigation
    next();
  }
};

export const getCookieValue = (cookieName: string): string => {
  // https://stackoverflow.com/questions/5639346/what-is-the-shortest-function-for-reading-a-cookie-by-name-in-javascript
  const cookieValue = document.cookie.match(
    "(^|[^;]+)\\s*" + cookieName + "\\s*=\\s*([^;]+)"
  );
  if (!cookieValue) {
    return "";
  }
  return cookieValue.pop() || "";
};

const loginRequired = (to: RouteLocationNormalized) => {
  return !to.meta?.public;
};

export const expertRequired: NavigationGuard = (to: RouteLocationNormalized) => {
  const courseSessionsStore = useCourseSessionsStore();
  if (courseSessionsStore.currentCourseSessionHasCockpit) {
    return true;
  } else {
    const courseSlug = to.params.courseSlug as string;
    return `/course/${courseSlug}/learn`;
  }
};

export async function handleCurrentCourseSession(to: RouteLocationNormalized) {
  // register after login hooks
  const userStore = useUserStore();
  if (userStore.loggedIn) {
    const courseSessionsStore = useCourseSessionsStore();
    if (to.params.courseSlug) {
      courseSessionsStore._currentCourseSlug = to.params.courseSlug as string;
    } else {
      courseSessionsStore._currentCourseSlug = "";
    }
    if (!courseSessionsStore.loaded) {
      await courseSessionsStore.loadCourseSessionsData();
    }
  }
}

export async function handleCourseSessionAsQueryParam(to: RouteLocationNormalized) {
  /**
   * switch to course session with id from query param `courseSessionId` if it
   * is present and valid.
   */
  // register after login hooks
  const userStore = useUserStore();
  if (userStore.loggedIn) {
    const courseSessionsStore = useCourseSessionsStore();
    if (!courseSessionsStore.loaded) {
      await courseSessionsStore.loadCourseSessionsData();
    }

    if (to.query.courseSessionId) {
      const { courseSessionId, ...restOfQuery } = to.query;
      const switchSuccessful = courseSessionsStore.switchCourseSessionById(
        courseSessionId.toString()
      );
      if (switchSuccessful) {
        return {
          path: to.path,
          query: restOfQuery,
          replace: true,
        };
      } else {
        // courseSessionId is invalid for current user -> redirect to home
        return {
          path: "/",
        };
      }
    }
  }
}
