public Mono<UpdateResult> authAndUpdateGroupMember(
            @NotNull Long requesterId,
            @NotNull Long groupId,
            @NotNull Long memberId,
            @Nullable String name,
            @Nullable @ValidGroupMemberRole GroupMemberRole role,
            @Nullable Date muteEndDate) {
        try {
            Validator.notNull(memberId, "memberId");
            DataValidator.validGroupMemberRole(role);
        } catch (ResponseException e) {
            return Mono.error(e);
        }
        if (role == GroupMemberRole.OWNER) {
            return Mono.error(ResponseException.get(ResponseStatusCode.ILLEGAL_ARGUMENT,
                    "Cannot update a group member's role to OWNER"));
        }
        Mono<Void> checkIfAuthorized;
        if (role != null) {
            // TODO: we should check if the group is active and not
            // deleted consistently.
            checkIfAuthorized = groupService.isGroupActiveAndNotDeleted(groupId)
                    .flatMap(isGroupActiveAndNotDeleted -> {
                        if (isGroupActiveAndNotDeleted) {
                            return isOwner(requesterId, groupId, false).flatMap(isOwner -> isOwner
                                    ? Mono.empty()
                                    : Mono.error(ResponseException.get(
                                            ResponseStatusCode.NOT_GROUP_OWNER_TO_UPDATE_GROUP_MEMBER_ROLE)));
                        }
                        return Mono.error(ResponseException.get(
                                ResponseStatusCode.UPDATE_GROUP_MEMBER_ROLE_OF_NONEXISTENT_GROUP));
                    });
        } else if (name != null || muteEndDate != null) {
            if (muteEndDate != null) {
                if (requesterId.equals(memberId)) {
                    return Mono.error(ResponseException.get(ResponseStatusCode.ILLEGAL_ARGUMENT,
                            "Cannot mute oneself"));
                }
                // Note that we need to check the requester's role first to avoid exposing
                // the target member's information if the requester is not a group member.
                checkIfAuthorized = groupService.queryGroupTypeIfActiveAndNotDeleted(groupId)
                        .switchIfEmpty(Mono.defer(() -> Mono.error(ResponseException
                                .get(ResponseStatusCode.MUTE_GROUP_MEMBER_OF_NONEXISTENT_GROUP))))
                        .flatMap(groupType -> queryGroupMemberRole(requesterId, groupId, false)
                                .switchIfEmpty(Mono.defer(() -> Mono.error(ResponseException.get(
                                        ResponseStatusCode.NOT_GROUP_OWNER_OR_MANAGER_TO_MUTE_GROUP_MEMBER))))
                                .flatMap(requesterRole -> queryGroupMemberRole(memberId,
                                        groupId,
                                        false)
                                        .switchIfEmpty(Mono.defer(() -> Mono.error(ResponseException
                                                .get(ResponseStatusCode.MUTE_NONEXISTENT_GROUP_MEMBER))))
                                        .flatMap(targetMemberRole -> {
                                            if (requesterRole.getNumber() >= targetMemberRole
                                                    .getNumber()) {
                                                return Mono.error(ResponseException.get(
                                                        ResponseStatusCode.MUTE_GROUP_MEMBER_WITH_ROLE_EQUAL_TO_OR_HIGHER_THAN_REQUESTER));
                                            }
                                            if (name == null) {
                                                return ResponseExceptionPublisherPool.ok();
                                            }
                                            return switch (groupType
                                                    .getMemberInfoUpdateStrategy()) {
                                                case OWNER -> isOwner(requesterRole)
                                                        ? Mono.empty()
                                                        : Mono.error(ResponseException.get(
                                                                ResponseStatusCode.NOT_GROUP_OWNER_TO_UPDATE_GROUP_MEMBER_INFO));
                                                case OWNER_MANAGER ->
                                                    isOwnerOrManager(requesterRole)
                                                            ? Mono.empty()
                                                            : Mono.error(ResponseException.get(
                                                                    ResponseStatusCode.NOT_GROUP_OWNER_OR_MANAGER_TO_UPDATE_GROUP_MEMBER_INFO));
                                                case OWNER_MANAGER_MEMBER ->
                                                    isOwnerOrManagerOrMember(requesterRole)
                                                            ? Mono.empty()
                                                            : Mono.error(ResponseException.get(
                                                                    ResponseStatusCode.NOT_GROUP_MEMBER_TO_UPDATE_GROUP_MEMBER_INFO));
                                                case ALL -> Mono.empty();
                                            };
                                        })));
            } else {
                checkIfAuthorized = groupService.queryGroupTypeIfActiveAndNotDeleted(groupId)
                        .switchIfEmpty(Mono.error(ResponseException.get(
                                ResponseStatusCode.UPDATE_GROUP_MEMBER_INFO_OF_NONEXISTENT_GROUP)))
                        .flatMap(groupType -> isGroupMember(groupId, memberId, false)
                                .flatMap(isTargetGroupMember -> {
                                    if (isTargetGroupMember) {
                                        return Mono.empty();
                                    }
                                    return Mono.error(ResponseException.get(
                                            ResponseStatusCode.UPDATE_INFO_OF_NONEXISTENT_GROUP_MEMBER));
                                })
                                .then(Mono.defer(() -> {
                                    if (groupType.getSelfInfoUpdatable()
                                            && requesterId.equals(memberId)) {
                                        return Mono.empty();
                                    }
                                    return switch (groupType.getMemberInfoUpdateStrategy()) {
                                        case OWNER -> isOwner(requesterId, groupId, false)
                                                .flatMap(isOwner -> isOwner
                                                        ? Mono.empty()
                                                        : Mono.error(ResponseException.get(
                                                                ResponseStatusCode.NOT_GROUP_OWNER_TO_UPDATE_GROUP_MEMBER_INFO)));
                                        case OWNER_MANAGER ->
                                            isOwnerOrManager(requesterId, groupId, false)
                                                    .flatMap(isOwnerOrManager -> isOwnerOrManager
                                                            ? Mono.empty()
                                                            : Mono.error(ResponseException.get(
                                                                    ResponseStatusCode.NOT_GROUP_OWNER_OR_MANAGER_TO_UPDATE_GROUP_MEMBER_INFO)));
                                        case OWNER_MANAGER_MEMBER ->
                                            isOwnerOrManagerOrMember(requesterId, groupId, false)
                                                    .flatMap(isMember -> isMember
                                                            ? Mono.empty()
                                                            : Mono.error(ResponseException.get(
                                                                    ResponseStatusCode.NOT_GROUP_MEMBER_TO_UPDATE_GROUP_MEMBER_INFO)));
                                        case ALL -> Mono.empty();
                                    };
                                })));
            }
        } else {
            return OperationResultPublisherPool.ACKNOWLEDGED_UPDATE_RESULT;
        }
        return checkIfAuthorized.then(
                updateGroupMember(groupId, memberId, name, role, null, muteEndDate, null, false));
    }
@return Possible codes: {@link ResponseStatusCode#OK}
        {@link ResponseStatusCode#SEND_MESSAGE_TO_MUTED_GROUP}
        {@link ResponseStatusCode#SEND_MESSAGE_TO_INACTIVE_GROUP}
        {@link ResponseStatusCode#MUTED_GROUP_MEMBER_SEND_MESSAGE}
turms-service/src/main/java/im/turms/service/domain/group/service/GroupMemberService.java