import { DEFAULT_MEMBERSHIP_LIMIT, SEAT_RESOURCE_TYPES } from "./entitlement-constants.js";
import { getLogger } from "../utils/logger.js";
import { dalCountMembersByRoleBucket, dalGetServiceAccountUserId, dalResolveEntitlement, dalSumSeatEntitlements } from "../data-access/runtime/entitlements.js";
import { withEntitlementLock } from "./entitlement-lock.js";
import { APIError } from "better-auth/api";

//#region src/auth/entitlements.ts
const logger = getLogger("entitlements");
function roleMatchesAdminBucket(role) {
	return role === "owner" || role === "admin";
}
function resourceTypeForRole(role) {
	return roleMatchesAdminBucket(role) ? SEAT_RESOURCE_TYPES.ADMIN : SEAT_RESOURCE_TYPES.MEMBER;
}
async function resolveEntitlement(db, orgId, resourceType) {
	return dalResolveEntitlement(db, orgId, resourceType);
}
async function countSeatsByRole(db, orgId, role) {
	return dalCountMembersByRoleBucket(db, orgId, roleMatchesAdminBucket(role), await dalGetServiceAccountUserId(db, orgId));
}
async function enforcePerRoleSeatLimit(db, orgId, role, onceVerified) {
	const resourceType = resourceTypeForRole(role);
	await withEntitlementLock(db, orgId, resourceType, async (limit, tx) => {
		if (limit !== null) {
			const current = await countSeatsByRole(tx, orgId, role);
			if (current >= limit) {
				const bucket = roleMatchesAdminBucket(role) ? "Admin" : "Member";
				logger.info({
					orgId,
					role,
					bucket,
					currentCount: current,
					maxValue: limit,
					action: "enforce"
				}, `${bucket} seat limit reached (${current}/${limit})`);
				throw new APIError("PAYMENT_REQUIRED", {
					message: `${bucket} seat limit reached (${current}/${limit})`,
					code: "ENTITLEMENT_LIMIT_REACHED",
					resourceType,
					current,
					limit
				});
			}
		}
		if (onceVerified) await onceVerified();
	});
}
async function resolveTotalMembershipLimit(db, orgId, hasServiceAccount) {
	const sum = await dalSumSeatEntitlements(db, orgId);
	const base = sum === null ? DEFAULT_MEMBERSHIP_LIMIT : sum;
	return hasServiceAccount ? base + 1 : base;
}

//#endregion
export { DEFAULT_MEMBERSHIP_LIMIT, SEAT_RESOURCE_TYPES, countSeatsByRole, enforcePerRoleSeatLimit, resolveEntitlement, resolveTotalMembershipLimit, roleMatchesAdminBucket };