import { defineNuxtPlugin } from "#app";
import { useAuth } from "~/composables/useAuth";
import { useNotificationUnreadCount } from "~/composables/useWorkpulseNotifications";
import {
  installWorkpulseTokenStorageSync,
  readWorkpulseAccessToken,
  readWorkpulseRefreshToken
} from "~/utils/workpulse-session-user";

/**
 * Hydrate auth from localStorage before layout/route guards render,
 * avoiding a false "logged out" frame that traps users on "Redirecting to login...".
 */
/** Refresh access token ~4 menit sebelum kadaluarsa default BE (15 menit). */
const ACCESS_REFRESH_INTERVAL_MS = 11 * 60 * 1000;

export default defineNuxtPlugin({
  name: "workpulse-auth-init",
  enforce: "pre",
  setup() {
    const { initAuth, initTokensFromSession, isAuthenticated, refreshAccessToken } = useAuth();
    const { applyPermissions } = useWorkpulsePermissions();
    const { getMe } = useWorkpulseMe();
    initAuth();
    initTokensFromSession();
    const { refresh } = useNotificationUnreadCount();

    const reconcileSession = async () => {
      if (!isAuthenticated.value) return;
      const hasAccess = !!readWorkpulseAccessToken();
      const hasRefresh = !!readWorkpulseRefreshToken();
      if (!hasAccess && hasRefresh) {
        await refreshAccessToken();
      } else if (!hasAccess && !hasRefresh) {
        await refreshAccessToken();
      }
      // Jangan paksa logout otomatis di sini:
      // pada tab baru, sessionStorage bisa kosong sementara sesi utama di tab lain masih valid.
      if (!readWorkpulseAccessToken() && !readWorkpulseRefreshToken()) return;
      void refresh();
    };
    void reconcileSession();

    const removeStorageSync = installWorkpulseTokenStorageSync(() => {
      initTokensFromSession();
      if (!isAuthenticated.value) return;
      if (!readWorkpulseAccessToken() && readWorkpulseRefreshToken()) {
        void refreshAccessToken();
      }
    });

    const hydratePermissions = async () => {
      if (!isAuthenticated.value) return;
      if (!readWorkpulseAccessToken()) return;
      const me = await getMe();
      if (me.ok && me.data) {
        applyPermissions(me.data.permissions, me.data.role);
      }
    };
    void hydratePermissions();

    if (!import.meta.client) return;

    const tickRefresh = () => {
      if (!isAuthenticated.value) return;
      if (!readWorkpulseAccessToken() && !readWorkpulseRefreshToken()) return;
      void refreshAccessToken();
    };

    tickRefresh();

    const intervalId = window.setInterval(tickRefresh, ACCESS_REFRESH_INTERVAL_MS);

    const onVisible = () => {
      if (document.visibilityState === "visible") tickRefresh();
    };
    document.addEventListener("visibilitychange", onVisible);

    return () => {
      window.clearInterval(intervalId);
      document.removeEventListener("visibilitychange", onVisible);
      removeStorageSync();
    };
  }
});