import { GenericError } from '#interfaces/error/generic';

/**
 * Throws a 403 GenericError if `ownerId` does not match `requestingUserId`
 * AND the requesting user is not an admin or system_admin.
 *
 * @param ownerId        - The owner field from the DB record (e.g. file.owner_user_id or record.created_by)
 * @param requestingUserId - req.user.id
 * @param userRoles      - req.user.roles (string array)
 * @param resourceName   - Human-readable resource name for error messages
 *
 * @example
 * assertOwnership(file.owner_user_id, req.user.id, req.user.roles ?? [], 'file');
 */
export function assertOwnership(
	ownerId: string | null | undefined,
	requestingUserId: string | null | undefined,
	userRoles: string[],
	resourceName = 'resource',
): void {
	const isAdmin = userRoles.includes('admin') || userRoles.includes('system_admin');
	if (isAdmin) return; // Admins bypass ownership checks

	if (!requestingUserId) {
		throw new GenericError('UNAUTHORIZED');
	}

	if (!ownerId || ownerId !== requestingUserId) {
		throw new GenericError(
			'FORBIDDEN',
			{ resourceName },
			{
				vi: `Bạn không có quyền thao tác ${resourceName} này`,
				en: `You do not have permission to access this ${resourceName}`,
			},
		);
	}
}

/**
 * Returns true if the requesting user owns the resource OR is an admin.
 * Use this for read-only ownership checks where throwing is not desired.
 */
export function isOwnerOrAdmin(
	ownerId: string | null | undefined,
	requestingUserId: string | null | undefined,
	userRoles: string[],
): boolean {
	const isAdmin = userRoles.includes('admin') || userRoles.includes('system_admin');
	if (isAdmin) return true;
	if (!requestingUserId || !ownerId) return false;
	return ownerId === requestingUserId;
}
