import { computed, ref } from "vue";

import { resetNavigation } from "./useNavigation.js";
import { api, ensureCsrf, resetCsrfState } from "../services/api";
import { normalizePermissionList } from "../utils/permissionList";

const userRef = ref(null);

const initialized = ref(false);

export async function hydrateUser() {
  await ensureCsrf();
  try {
    const { data } = await api.get("/api/user");
    userRef.value = data;
  } catch {
    userRef.value = null;
  }
  initialized.value = true;
}

export function useAuth() {
  const user = computed(() => userRef.value);
  const permissions = computed(() =>
    normalizePermissionList(user.value?.permissions),
  );
  const roles = computed(() => {
    const raw = user.value?.roles;
    if (raw == null) {
      return [];
    }
    if (Array.isArray(raw)) {
      return raw.filter((item) => typeof item === "string");
    }
    if (typeof raw === "object") {
      return Object.values(raw).filter((item) => typeof item === "string");
    }
    return [];
  });

  async function logout() {
    try {
      await ensureCsrf();
      await api.post("/logout");
    } catch {
      // session may already be expired
    } finally {
      userRef.value = null;
      resetNavigation();
      resetCsrfState();
      initialized.value = true;
    }
  }

  return {
    user,
    permissions,
    roles,
    logout,
    initialized,
    isAuthenticated: computed(() => Boolean(user.value)),
  };
}

export function setUser(next) {
  userRef.value = next;
}

export { userRef };
