package com.red.circle.console.app.service.app.sys;

import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.common.business.enums.SendPropsOrigin;
import com.red.circle.console.app.common.sys.ActivitySourceGroupCommon;
import com.red.circle.console.app.convertor.sys.ActivityConfigAppConvertor;
import com.red.circle.console.app.dto.clienobject.sys.ActivityConfigCO;
import com.red.circle.console.app.dto.clienobject.sys.ActivityConfigRewardsCO;
import com.red.circle.console.app.dto.clienobject.sys.ActivityRankCO;
import com.red.circle.console.app.dto.clienobject.sys.ActivityRankPreviewCO;
import com.red.circle.console.app.dto.clienobject.sys.ActivityRankUseCO;
import com.red.circle.console.app.dto.clienobject.sys.ActivityRankUserRewardCO;
import com.red.circle.console.app.dto.clienobject.sys.ActivityTemplateCO;
import com.red.circle.console.app.dto.cmd.app.sys.ActivityConfigBackConsoleQryCmd;
import com.red.circle.console.app.dto.cmd.app.sys.ActivityTemplateConsoleQryCmd;
import com.red.circle.console.infra.database.rds.entity.admin.User;
import com.red.circle.console.infra.database.rds.service.admin.UserService;
import com.red.circle.console.inner.error.ConsoleErrorCode;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.other.inner.endpoint.activity.PropsActivityClient;
import com.red.circle.other.inner.endpoint.material.gift.GiftConfigClient;
import com.red.circle.other.inner.endpoint.sys.SysActivityConfigClient;
import com.red.circle.other.inner.endpoint.user.user.WeekKingQueenClient;
import com.red.circle.other.inner.endpoint.user.user.api.WeekKingQueenClientApi;
import com.red.circle.other.inner.enums.activity.KingQueenType;
import com.red.circle.other.inner.model.cmd.activity.SendActivityRewardCmd;
import com.red.circle.other.inner.model.dto.material.GiftConfigDTO;
import com.red.circle.other.inner.model.dto.material.PropsActivityRewardConfigInfoDTO;
import com.red.circle.other.inner.model.dto.sys.*;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.DateFormatConstant;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import com.red.circle.tool.core.date.ZonedDateTimeUtils;
import com.red.circle.tool.core.num.NumUtils;
import com.red.circle.tool.core.regex.RegexConstant;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import com.red.circle.tool.core.text.StringUtils;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.other.inner.endpoint.user.user.UserProfileClient;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import static com.red.circle.common.business.core.enums.SysOriginPlatformEnum.LIKEI;

/**
 * 系统活动配置.
 *
 * @author pengliang on 2022/8/12
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysActivityConfigServiceImpl implements SysActivityConfigService {

  private final UserService userService;
  private final GiftConfigClient giftConfigClient;
  private final UserProfileClient userProfileClient;
  private final PropsActivityClient propsActivityClient;
  private final SysActivityConfigClient sysActivityConfigClient;
  private final ActivitySourceGroupCommon activitySourceGroupCommon;
  private final ActivityConfigAppConvertor activityConfigAppConvertor;
  private final WeekKingQueenClient weekKingQueenClient;

  @Override
  public List<ActivityTemplateCO> listTemplate(ActivityTemplateConsoleQryCmd query) {
    List<ActivityTemplateDTO> activityTemplates = ResponseAssert.requiredSuccess(
        sysActivityConfigClient.listActivityTemplate(query.getId(),
            query.getLastId(), query.getLimit()));
    if (CollectionUtils.isEmpty(activityTemplates)) {
      return Lists.newArrayList();
    }

    Map<Long, User> userMap = userService.mapBackUser(
        Stream.of(
            activityTemplates.stream().map(ActivityTemplateDTO::getCreateUser)
                .filter(Objects::nonNull)
                .collect(
                    Collectors.toSet()),
            activityTemplates.stream().map(ActivityTemplateDTO::getUpdateUser)
                .filter(Objects::nonNull)
                .collect(
                    Collectors.toSet())
        ).flatMap(Collection::stream).collect(Collectors.toSet())
    );

    return activityTemplates.stream().map(template ->
        new ActivityTemplateCO()
            .setTemplate(template)
            .setCreateUserName(Optional.ofNullable(userMap.get(template.getCreateUser()))
                .map(User::getNickname)
                .orElse(""))
            .setUpdateUserName(Optional.ofNullable(userMap.get(template.getUpdateUser()))
                .map(User::getNickname)
                .orElse(""))
    ).collect(Collectors.toList());
  }

  @Override
  public ActivityTemplateDTO getTemplateById(Long id) {
    return ResponseAssert.requiredSuccess(sysActivityConfigClient.getTemplateById(id));
  }

  @Override
  public List<ActivityTemplateValueDTO> listTemplateValue() {
    return ResponseAssert.requiredSuccess(sysActivityConfigClient.listValues());
  }

  @Override
  public void saveTemplate(ActivityTemplateDTO param) {
    param.setId(IdWorkerUtils.getId());
    sysActivityConfigClient.saveTemplate(param);
  }

  @Override
  public void updateTemplate(ActivityTemplateDTO param) {
    sysActivityConfigClient.updateTemplateById(param);
  }

  @Override
  public void updateTemplateName(ActivityTemplateDTO param) {
    sysActivityConfigClient.updateTemplateName(param.getId(), param.getName(),
        param.getUpdateUser());
  }

  @Override
  public void saveActivityConf(ActivityConfigDTO param) {
    param.setId(IdWorkerUtils.getId());
    sysActivityConfigClient.saveActivityConf(param);
  }

  @Override
  public void updateActivityConf(ActivityConfigDTO param) {
    ActivityConfigDTO activityConfig = ResponseAssert.requiredSuccess(
        sysActivityConfigClient.getActivityConfigById(param.getId()));
    ResponseAssert.notNull(ConsoleErrorCode.NOT_FOUND_RECORD, activityConfig);
    ResponseAssert.isTrue(ConsoleErrorCode.ACTIVITY_CLOSE,
        !Objects.equals(activityConfig.status(), 2));
    sysActivityConfigClient.updateSelectiveById(param);
  }

  @Override
  public List<ActivityConfigCO> listActivityConf(ActivityConfigBackConsoleQryCmd query) {
    List<ActivityConfigDTO> activityConfigs = ResponseAssert.requiredSuccess(
        sysActivityConfigClient.listActivityConf(
            activityConfigAppConvertor.toActivityConfigBackQryCmd(query)));

    if (CollectionUtils.isEmpty(activityConfigs)) {
      return Lists.newArrayList();
    }

    Map<Long, ActivityTemplateValueDTO> templateValueMap = ResponseAssert.requiredSuccess(
        sysActivityConfigClient.mapByIds(
            activityConfigs.stream().map(ActivityConfigDTO::getTemplateId).collect(
                Collectors.toSet())));

    Map<Long, User> userMap = userService.mapBackUser(
        Stream.of(
            activityConfigs.stream().map(ActivityConfigDTO::getCreateUser).filter(Objects::nonNull)
                .collect(
                    Collectors.toSet()),
            activityConfigs.stream().map(ActivityConfigDTO::getUpdateUser).filter(Objects::nonNull)
                .collect(
                    Collectors.toSet())
        ).flatMap(Collection::stream).collect(Collectors.toSet())
    );

    Map<Long, List<PropsActivityRewardConfigInfoDTO>> rewardMaps = activitySourceGroupCommon.mapSourceGroup(
        query.getSysOrigin(), getRewardGroupIds(activityConfigs));

    Map<Long, GiftConfigDTO> sysGiftConfigMap = ResponseAssert.requiredSuccess(
        giftConfigClient.mapByIds(
            activityConfigs.stream()
                .map(ActivityConfigDTO::getGiftIds)
                .filter(CollectionUtils::isNotEmpty)
                .flatMap(Collection::stream)
                .filter(Objects::nonNull)
                .map(Long::parseLong)
                .collect(Collectors.toSet())));

    return activityConfigs.stream().map(conf ->
        new ActivityConfigCO()
            .setConfig(conf)
            .setButOneRewards(getRewards(rewardMaps, conf.getButOneRewards()))
            .setButTwoRewards(getRewards(rewardMaps, conf.getButTwoRewards()))
            .setCreateUserName(Optional.ofNullable(userMap.get(conf.getCreateUser()))
                .map(User::getNickname)
                .orElse(""))
            .setUpdateUserName(Optional.ofNullable(userMap.get(conf.getUpdateUser()))
                .map(User::getNickname)
                .orElse(""))
            .setTemplateName(Optional.ofNullable(templateValueMap.get(conf.getTemplateId()))
                .map(ActivityTemplateValueDTO::getName)
                .orElse(""))
            .setGifts(Optional.ofNullable(conf.getGiftIds())
                .map(giftIds -> giftIds.stream()
                    .map(giftId -> sysGiftConfigMap.get(Long.parseLong(giftId)))
                    .collect(Collectors.toList()))
                .orElseGet(Lists::newArrayList))
            .setStatus(conf.status())
            .setCountDown(conf.countDown())
    ).collect(Collectors.toList());
  }

  @Override
  public ActivityRankPreviewCO getActivityRankRewardPreview(Long activityId) {
    ActivityConfigDTO activityConfig = ResponseAssert.requiredSuccess(
        sysActivityConfigClient.getActivityConfigById(activityId));
    ResponseAssert.notNull(ConsoleErrorCode.NOT_FOUND_RECORD, activityConfig);

    if (!Objects.equals(activityConfig.getAwardStatus(), Boolean.TRUE)) {
      return new ActivityRankPreviewCO()
          .setButOneRanks(getUserRankReward(SysActivityCountType.WEALTH, activityConfig))
          .setButTwoRanks(getUserRankReward(SysActivityCountType.CHARM, activityConfig))
          .setAwardStatus(activityConfig.getAwardStatus());
    }

    Map<Long, UserProfileDTO> userProfileMap = ResponseAssert.requiredSuccess(
        userProfileClient.mapByUserIds(
            Stream.of(getUserIds(activityConfig.getButOneRewards()),
                    getUserIds(activityConfig.getButTwoRewards()))
                .flatMap(Collection::stream).collect(Collectors.toSet())
        ));

    return new ActivityRankPreviewCO()
        .setButOneRanks(getHistoryRewards(activityConfig.getButOneRewards(), userProfileMap))
        .setButTwoRanks(getHistoryRewards(activityConfig.getButTwoRewards(), userProfileMap))
        .setAwardStatus(activityConfig.getAwardStatus());
  }

  private List<ActivityRankUserRewardCO> getHistoryRewards(List<ActivityConfigRewardsDTO> rewards,
      Map<Long, UserProfileDTO> userProfileMap) {
    if (CollectionUtils.isEmpty(rewards)) {
      return Lists.newArrayList();
    }
    return rewards.stream().map(reward -> new ActivityRankUserRewardCO()
        .setRankUsers(Optional.ofNullable(reward.getRankUsers())
            .map(users -> users.stream().map(user -> new ActivityRankUseCO()
                        .setUserProfile(userProfileMap.get(user.getUserId()))
                        .setQuantity(user.getQuantity())
                        .setQuantityFormat(NumUtils.formatLong(user.getQuantity()))
                    )
                    .collect(Collectors.toList())
            ).orElseGet(Lists::newArrayList)
        )
        .setReward(activityConfigAppConvertor.toActivityConfigRewardsCO(reward))
        .setStatus(reward.getStatus())
    ).collect(Collectors.toList());
  }

  private Set<Long> getUserIds(List<ActivityConfigRewardsDTO> activityAwards) {
    return Optional.ofNullable(activityAwards)
        .map(ranks -> ranks.stream().map(rank -> Optional.ofNullable(rank.getRankUsers())
                .map(rankUsers -> rankUsers.stream().map(ActivityAwardRankUserDTO::getUserId)
                    .collect(Collectors.toList()))
                .orElseGet(Lists::newArrayList))
            .flatMap(Collection::stream)
            .filter(Objects::nonNull)
            .collect(Collectors.toSet()))
        .orElseGet(Sets::newHashSet);
  }

  @Override
  public ActivityRankCO getActivityRank(Long activityId) {
    ResultResponse<PageResult<SysActivityCountDTO>> response = weekKingQueenClient.listRanking("LIKEI", KingQueenType.CHARM, getThisWeekDate(), 1L, 20L);
    ResultResponse<PageResult<SysActivityCountDTO>> response2 = weekKingQueenClient.listRanking("LIKEI", KingQueenType.WEALTH, getThisWeekDate(), 1L, 20L);
    List<SysActivityCountDTO> butOnes = (ArrayList) response.getBody().getRecords();
    List<SysActivityCountDTO> butTwos = (ArrayList) response2.getBody().getRecords();

    Map<Long, UserProfileDTO> userProfileMap = ResponseAssert.requiredSuccess(
        userProfileClient.mapByUserIds(
            Stream.of(butOnes, butTwos).flatMap(Collection::stream)
                .map(SysActivityCountDTO::getUserId)
                .collect(
                    Collectors.toSet())
        ));
    return new ActivityRankCO()
        .setButOneRanks(getActivityRankUse(butOnes, userProfileMap))
        .setButTwoRanks(getActivityRankUse(butTwos, userProfileMap));
  }

  private String getThisWeekDate() {
    return ZonedDateTimeUtils.format(ZonedDateTimeAsiaRiyadhUtils.nowWeekMonday(),
        DateFormatConstant.yyyyMMdd);
  }

  @Override
  public void sendActivityReward(Long activityId) {
    ActivityConfigDTO activityConfig = ResponseAssert.requiredSuccess(
        sysActivityConfigClient.getActivityConfigById(activityId));
    ResponseAssert.notNull(ConsoleErrorCode.NOT_FOUND_RECORD, activityConfig);
    ResponseAssert.isTrue(ConsoleErrorCode.ACTIVITY_REWARD_CLOSE,
        !Objects.equals(activityConfig.getAwardStatus(), Boolean.TRUE));

    List<ActivityRankUserRewardCO> butOneRewards = getUserRankReward(SysActivityCountType.WEALTH,
        activityConfig);
    List<ActivityRankUserRewardCO> butTwoRewards = getUserRankReward(SysActivityCountType.CHARM,
        activityConfig);

    List<ActivityConfigRewardsDTO> butOneCnfRewards = toActivityConfigRewards(butOneRewards);
    List<ActivityConfigRewardsDTO> butTwoCnfRewards = toActivityConfigRewards(butTwoRewards);

    sysActivityConfigClient.updateRewards(
        new ActivityConfigRewardsInfoDTO()
            .setActivityId(activityId)
            .setButOneCnfRewards(butOneCnfRewards)
            .setButTwoCnfRewards(butTwoCnfRewards)
    );

    sendActivityReward(activityId,
        activityConfig.getSysOrigin(),
        SysActivityCountType.WEALTH,
        butOneCnfRewards);

    sendActivityReward(activityId,
        activityConfig.getSysOrigin(),
        SysActivityCountType.CHARM,
        butTwoCnfRewards);

    sysActivityConfigClient.updateAwardStatusTrue(activityConfig.getId());
  }

  /**
   * 发送活动奖励.
   *
   * @param activityId 活动id
   * @param sysOrigin  系统
   * @param type       按钮类型
   * @param ranks      排行榜
   */
  private void sendActivityReward(Long activityId,
      String sysOrigin,
      SysActivityCountType type,
      List<ActivityConfigRewardsDTO> ranks) {
    if (CollectionUtils.isEmpty(ranks)) {
      return;
    }

    ranks.forEach(rank -> {
      if (CollectionUtils.isEmpty(rank.getRankUsers())) {
        return;
      }
      if (Objects.equals(rank.getStatus(), Boolean.TRUE)) {
        return;
      }
      rank.getRankUsers()
          .forEach(acceptUser -> {
            try {
              propsActivityClient.sendActivityReward(new SendActivityRewardCmd()
                  .setTrackId(activityId)
                  .setOrigin(SendPropsOrigin.ACTIVITY_REWARD)
                  .setSysOrigin(SysOriginPlatformEnum.valueOf(sysOrigin))
                  .setSourceGroupId(rank.getResourceGroupId())
                  .setAcceptUserId(acceptUser.getUserId())
              );

            } catch (Exception ex) {
              log.error("[活动奖品] 发送奖品异常:{}", Throwables.getStackTraceAsString(ex));
            }
          });

      if (Objects.equals(type, SysActivityCountType.WEALTH)) {
        sysActivityConfigClient.updateButOneRewardsStatusTrue(activityId,
            rank.getRewardId());
      }
      if (Objects.equals(type, SysActivityCountType.CHARM)) {
        sysActivityConfigClient.updateButTwoRewardsStatusTrue(activityId,
            rank.getRewardId());
      }
    });
  }


  private List<ActivityConfigRewardsDTO> toActivityConfigRewards(
      List<ActivityRankUserRewardCO> rankUserRewards) {
    if (CollectionUtils.isEmpty(rankUserRewards)) {
      return Lists.newArrayList();
    }
    return rankUserRewards.stream().map(rank -> new ActivityConfigRewardsDTO()
            .setRewardId(IdWorkerUtils.getId())
            .setRankRange(rank.getReward().getRankRange())
            .setResourceGroupId(rank.getReward().getResourceGroupId())
            .setRewards(Optional.ofNullable(rank.getReward().getRewards())
                .map(
                    rewards -> rewards.stream().map(item -> (Object) item).collect(Collectors.toList()))
                .orElseGet(Lists::newArrayList))
            .setRankUsers(Optional.ofNullable(rank.getRankUsers())
                .map(rankUsers -> rankUsers.stream()
                    .map(rankUser -> new ActivityAwardRankUserDTO()
                        .setUserId(rankUser.getUserProfile().getId())
                        .setQuantity(rankUser.getQuantity())
                    ).collect(Collectors.toList()))
                .orElseGet(Lists::newArrayList))
            .setStatus(Boolean.FALSE)
        )
        .collect(Collectors.toList());
  }

  private List<ActivityRankUseCO> getActivityRankUse(List<SysActivityCountDTO> counts,
      Map<Long, UserProfileDTO> userProfileMap) {
    return counts.stream().map(count -> new ActivityRankUseCO()
        .setUserProfile(
            userProfileMap.get(count.getUserId()))
        .setQuantity(count.getQuantity())
        .setQuantityFormat(NumUtils.formatLong(count.getQuantity()))
    ).collect(Collectors.toList());
  }

  private List<ActivityRankUserRewardCO> getUserRankReward(SysActivityCountType type,
      ActivityConfigDTO activityConfig) {
    List<SysActivityCountDTO> counts = ResponseAssert.requiredSuccess(
        sysActivityConfigClient.listRank(activityConfig.getId(), type.name(),
            20));
    if (Objects.equals(type, SysActivityCountType.WEALTH)) {
      return getActivityRankUserReward(activityConfig.getSysOrigin(),
          activityConfig.getButOneRewards(), counts);
    }

    if (Objects.equals(type, SysActivityCountType.CHARM)) {
      return getActivityRankUserReward(activityConfig.getSysOrigin(),
          activityConfig.getButTwoRewards(), counts);
    }

    return Lists.newArrayList();
  }

  private List<ActivityRankUserRewardCO> getActivityRankUserReward(
      String sysOrigin,
      List<ActivityConfigRewardsDTO> configRewards,
      List<SysActivityCountDTO> counts) {

    if (Objects.isNull(counts)) {
      counts = Lists.newArrayList();
    }

    if (CollectionUtils.isEmpty(configRewards)) {
      return Lists.newArrayList();
    }

    Map<Long, UserProfileDTO> userProfileMap = ResponseAssert.requiredSuccess(
        userProfileClient.mapByUserIds(
            counts.stream().map(SysActivityCountDTO::getUserId).collect(
                Collectors.toSet())));

    Map<Long, List<PropsActivityRewardConfigInfoDTO>> rewardMaps = activitySourceGroupCommon.mapSourceGroup(
        sysOrigin, configRewards.stream().map(ActivityConfigRewardsDTO::getResourceGroupId)
            .collect(Collectors.toSet()));

    List<ActivityRankUserRewardCO> rankUserRewards = Lists.newArrayList();
    for (ActivityConfigRewardsDTO rewards : configRewards) {
      if (StringUtils.isBlank(rewards.getRankRange())) {
        continue;
      }

      if (rewards.getRankRange().matches(RegexConstant.NUMBER)) {
        int rankIndex = Integer.parseInt(rewards.getRankRange()) - 1;
        if (rankIndex >= 0 && rankIndex < counts.size()) {
          SysActivityCountDTO sysActivityCount = counts.get(rankIndex);
          rankUserRewards.add(new ActivityRankUserRewardCO()
              .setRankUsers(List.of(
                      new ActivityRankUseCO()
                          .setUserProfile(userProfileMap.get(sysActivityCount.getUserId()))
                          .setQuantity(sysActivityCount.getQuantity())
                          .setQuantityFormat(NumUtils.formatLong(sysActivityCount.getQuantity()))
                  )
              )
              .setReward(getRewards(rewardMaps, rewards))
              .setStatus(Boolean.FALSE)
          );
          continue;
        }

        rankUserRewards.add(new ActivityRankUserRewardCO()
            .setRankUsers(null)
            .setReward(getRewards(rewardMaps, rewards))
            .setStatus(Boolean.FALSE)
        );
        continue;
      }

      List<Integer> range = Stream.of(rewards.getRankRange().split("~"))
          .filter(StringUtils::isNotBlank)
          .map(StringUtils::trim)
          .map(Integer::parseInt)
          .collect(Collectors.toList());

      if (CollectionUtils.isEmpty(range) || range.size() != 2) {
        rankUserRewards.add(new ActivityRankUserRewardCO()
            .setRankUsers(null)
            .setReward(getRewards(rewardMaps, rewards))
            .setStatus(Boolean.FALSE)
        );
        continue;
      }

      int size = range.get(1) - range.get(0);
      if (size <= 0) {
        rankUserRewards.add(new ActivityRankUserRewardCO()
            .setRankUsers(null)
            .setReward(getRewards(rewardMaps, rewards))
            .setStatus(Boolean.FALSE)
        );
        continue;
      }

      int skip = range.get(0) - 1;
      rankUserRewards.add(new ActivityRankUserRewardCO()
          .setRankUsers(counts.stream()
              .skip(Math.max(skip, 0))
              .limit(size + 1)
              .map(count ->
                  new ActivityRankUseCO()
                      .setUserProfile(userProfileMap.get(count.getUserId()))
                      .setQuantity(count.getQuantity())
                      .setQuantityFormat(NumUtils.formatLong(count.getQuantity()))
              ).collect(Collectors.toList()))
          .setReward(getRewards(rewardMaps, rewards))
          .setStatus(Boolean.FALSE)
      );
    }
    return rankUserRewards;
  }

  private List<ActivityConfigRewardsCO> getRewards(
      Map<Long, List<PropsActivityRewardConfigInfoDTO>> rewardMaps,
      List<ActivityConfigRewardsDTO> rewardGroup) {
    return Optional.ofNullable(rewardGroup)
        .map(rewards -> rewards.stream().map(reward -> new ActivityConfigRewardsCO()
            .setRankRange(reward.getRankRange())
            .setResourceGroupId(reward.getResourceGroupId())
            .setRewards(rewardMaps.get(reward.getResourceGroupId()))
        ).collect(Collectors.toList()))
        .orElseGet(Lists::newArrayList);
  }

  private ActivityConfigRewardsCO getRewards(
      Map<Long, List<PropsActivityRewardConfigInfoDTO>> rewardMaps,
      ActivityConfigRewardsDTO rewards) {
    return Optional.ofNullable(rewards)
        .map(reward -> new ActivityConfigRewardsCO()
            .setRankRange(reward.getRankRange())
            .setResourceGroupId(reward.getResourceGroupId())
            .setRewards(rewardMaps.get(reward.getResourceGroupId()))
        )
        .orElse(null);
  }

  private Set<Long> getRewardGroupIds(List<ActivityConfigDTO> activityConfigs) {
    return Stream.of(activityConfigs.stream().map(ActivityConfigDTO::getButOneRewards)
                .filter(CollectionUtils::isNotEmpty)
                .flatMap(Collection::stream)
                .map(ActivityConfigRewardsDTO::getResourceGroupId)
                .collect(Collectors.toSet()),
            activityConfigs.stream().map(ActivityConfigDTO::getButTwoRewards)
                .filter(CollectionUtils::isNotEmpty)
                .flatMap(Collection::stream)
                .map(ActivityConfigRewardsDTO::getResourceGroupId)
                .collect(Collectors.toSet()))
        .flatMap(Collection::stream)
        .collect(Collectors.toSet());
  }

}
