import type { Router } from "vue-router";
import { isNavigationFailure } from "vue-router";
import { useAuthStore } from "@/stores/auth";
import { resolveDocumentTitle } from "./title";

const CHUNK_RELOAD_KEY = "hwlab:v03:chunk-reload-at";
const CHUNK_RELOAD_WINDOW_MS = 10_000;

export function isChunkLoadError(error: unknown): boolean {
  const message = error instanceof Error ? error.message : String(error ?? "");
  return /Loading chunk|Loading CSS chunk|Failed to fetch dynamically imported module|Importing a module script failed|dynamically imported module/u.test(message);
}

export function shouldReloadForChunkError(now = Date.now(), storage: Pick<Storage, "getItem" | "setItem"> = window.sessionStorage): boolean {
  const lastReload = Number(storage.getItem(CHUNK_RELOAD_KEY) ?? 0);
  if (Number.isFinite(lastReload) && now - lastReload < CHUNK_RELOAD_WINDOW_MS) return false;
  storage.setItem(CHUNK_RELOAD_KEY, String(now));
  return true;
}

export function installChunkRecovery(router: Router): void {
  router.onError((error) => {
    if (!isChunkLoadError(error)) return;
    if (typeof window === "undefined") return;
    if (shouldReloadForChunkError()) window.location.reload();
  });
}

export function installRouterGuards(router: Router): void {
  router.beforeEach(async (to) => {
    const auth = useAuthStore();
    if (!auth.checked) await auth.bootstrap();
    if (to.meta.requiresAuth !== false && auth.authState === "login") return { name: "Login", query: { redirect: to.fullPath } };
    if (to.meta.requiresAdmin === true && !auth.isAdmin) return { name: "Dashboard", query: { blocked: "admin_required" } };
    return true;
  });

  router.afterEach((to, _from, failure) => {
    if (failure && isNavigationFailure(failure)) return;
    document.title = resolveDocumentTitle(to.meta.title);
  });

  installChunkRecovery(router);
}
