import { forbidden } from "@/lib/api/errors";

/**
 * Role-Based Access Control (RBAC) helpers.
 *
 * @typedef {Object} Session
 * @property {"branch"|"admin"|"superadmin"|"dev"|string} role
 * @property {string=} branchId
 */

/**
 * Returns true if the given session is allowed to access the requested branch.
 *
 * Rules:
 * - No session => not allowed (caller should return 401)
 * - role "branch" => allowed only for session.branchId === branchId
 * - role "admin" / "superadmin" / "dev" => allowed for any branch
 *
 * @param {Session|null} session
 * @param {string} branchId
 * @returns {boolean}
 */
export function canAccessBranch(session, branchId) {
	if (!session) return false;
	if (!branchId) return false;

	if (session.role === "branch") {
		return session.branchId === branchId;
	}

	if (
		session.role === "admin" ||
		session.role === "superadmin" ||
		session.role === "dev"
	) {
		return true;
	}

	return false;
}

/**
 * Filters a list of branch IDs for a session.
 *
 * - No session => []
 * - role "branch" => [session.branchId] if present in branchIds, else []
 * - role "admin" / "superadmin" / "dev" => all branchIds
 *
 * @param {Session|null} session
 * @param {string[]} branchIds
 * @returns {string[]}
 */
export function filterBranchesForSession(session, branchIds) {
	if (!session) return [];
	if (!Array.isArray(branchIds)) return [];

	if (session.role === "branch") {
		const own = session.branchId;
		if (!own) return [];
		return branchIds.includes(own) ? [own] : [];
	}

	if (
		session.role === "admin" ||
		session.role === "superadmin" ||
		session.role === "dev"
	) {
		return branchIds;
	}

	return [];
}

/**
 * Returns true if the given session can manage users (RHL-012 capability).
 *
 * Rules:
 * - dev / superadmin => true
 * - admin / branch / unknown => false
 *
 * @param {Session|null} session
 * @returns {boolean}
 */
export function canManageUsers(session) {
	if (!session) return false;
	return session.role === "dev" || session.role === "superadmin";
}

/**
 * Guard helper for user-management endpoints (to be used in RHL-012).
 *
 * Throws a standardized 403 error when the session lacks user-management permission.
 *
 * @param {Session|null} session
 * @returns {void}
 */
export function requireUserManagement(session) {
	if (!canManageUsers(session)) {
		throw forbidden("AUTH_FORBIDDEN_USER_MANAGEMENT", "Forbidden");
	}
}
