import { ref, computed } from "vue";
import apiClient, { ensureCsrf, resetCsrf } from "../services/api.js";
import { useNavigation } from "./useNavigation.js";

/**
 * Session-based auth (BFF). No tokens in localStorage; session cookie is used.
 * Used by route guards and API interceptors for auth and forbidden behaviour.
 *
 * Auth state (user, permissions) is fetched from backend `/auth/me` endpoint.
 * Backend is the single source of truth for authentication and authorization.
 */
const user = ref(null);
/** @type {import('vue').Ref<string[]>} Permissions array fetched from backend `/auth/me` endpoint. Used for RBAC route guards and feature access. */
const permissions = ref([]);
/** @type {import('vue').Ref<string[]>} Role names from backend `/auth/me`. Used for profile display. */
const roles = ref([]);

export function useAuth() {
  const isAuthenticated = computed(() => Boolean(user.value));

  /**
   * Dev-only: log in as a test user via backend (session cookie set by backend).
   */
  async function devLogin(userId = 1) {
    await ensureCsrf();
    await apiClient.post("/auth/dev-login", { user_id: userId });
    await fetchUser();
  }

  /**
   * Fetch current user and permissions from backend (session cookie sent automatically).
   * Backend `/auth/me` should return: { user: {...}, permissions: [...] }
   * _skipAuthRetry prevents the 401 interceptor from doing silent refresh / redirects.
   */
  async function fetchUser() {
    try {
      const { data } = await apiClient.get("/auth/me", {
        _skipAuthRetry: true,
      });
      user.value = data.user;
      permissions.value = data.permissions ?? data.user?.permissions ?? [];
      roles.value = data.roles ?? data.user?.roles ?? [];
      return data.user;
    } catch {
      user.value = null;
      permissions.value = [];
      roles.value = [];
      return null;
    }
  }

  /**
   * Logout: tell backend to destroy session and clear local state.
   */
  async function logout() {
    try {
      await ensureCsrf();
      await apiClient.post("/auth/logout");
    } catch (_) {
      // ignore
    }
    user.value = null;
    permissions.value = [];
    roles.value = [];
    useNavigation().resetNavigation();
    resetCsrf();
  }

  /**
   * Set user (e.g. after fetchUser from another place). Used by api interceptor if needed.
   */
  function setUser(u) {
    user.value = u;
  }

  return {
    user,
    isAuthenticated,
    permissions,
    roles,
    devLogin,
    fetchUser,
    logout,
    setUser,
  };
}
