package com.red.circle.other.app.command.activity.query;

import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.other.app.convertor.material.GiftAppConvertor;
import com.red.circle.other.app.dto.clientobject.activity.LastWeekStarGiftUserRankCO;
import com.red.circle.other.app.dto.clientobject.gift.GiftConfigCO;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.infra.database.mongo.entity.activity.WeekStarGiftCount;
import com.red.circle.other.infra.database.mongo.service.activity.WeekStarGiftCountService;
import com.red.circle.other.infra.database.rds.service.gift.GiftConfigService;
import com.red.circle.other.infra.database.rds.service.sys.WeekStarGiftService;
import com.red.circle.other.infra.database.rds.service.sys.WeekStarGroupService;
import com.red.circle.other.inner.enums.activity.WeekStarGiftTypeEnum;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.num.NumUtils;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * 周星奖励配置-奖励池.
 *
 * @author pengshigang on 2021/6/24
 */
@Service
@RequiredArgsConstructor
public class LastWeekFirstPlaceQueryExe {

  private final GiftConfigService giftConfigService;
  private final UserProfileGateway userProfileGateway;
  private final GiftAppConvertor appGiftConfigMapper;
  private final WeekStarGiftService weekStarGiftService;
  private final WeekStarGroupService weekStarGroupService;
  private final WeekStarGiftCountService weekStarGiftCountService;


  public List<LastWeekStarGiftUserRankCO> execute(AppExtCommand cmd) {

    return Optional.ofNullable(listLastWeeksGift(cmd))
        .map(giftConfigs -> giftConfigs.stream()
            .map(gift -> {
              LastWeekStarGiftUserRankCO user = leaderboard(cmd.getReqSysOrigin().getOrigin(),
                  gift.getId());
              if (Objects.isNull(user)) {
                return null;
              }
              user.setGiftUrl(gift.getGiftPhoto());
              return user;
            }).filter(Objects::nonNull).toList()
        ).orElseGet(Lists::newArrayList);
  }

  private List<GiftConfigCO> listLastWeeksGift(AppExtCommand cmd) {
    return Optional.ofNullable(getGiftConfig(cmd))
        .map(this::sortedGiftGoldsAsc)
        .orElse(Lists.newArrayList());
  }

  private List<GiftConfigCO> sortedGiftGoldsAsc(List<GiftConfigCO> giftConfigs) {
    return giftConfigs.stream()
        .sorted(Comparator.comparing(GiftConfigCO::getGiftCandy)).collect(Collectors.toList());
  }

  private List<GiftConfigCO> getGiftConfig(AppExtCommand cmd) {
    return weekStarGroupService.getByTypeOne(cmd.requireReqSysOriginEnum(),
            WeekStarGiftTypeEnum.LAST_WEEK)
        .map(weekStarGroup -> appGiftConfigMapper.toGiftConfigCO(giftConfigService
            .listByIds(weekStarGiftService.listGiftIdsByGroupId(weekStarGroup.getId())))
        ).orElseGet(Lists::newArrayList);
  }


  private LastWeekStarGiftUserRankCO leaderboard(String sysOrigin, Long giftId) {

    List<WeekStarGiftCount> weekStarGiftCounts = weekStarGiftCountService
        .listLastWeekTop(sysOrigin, giftId, 1);

    if (CollectionUtils.isEmpty(weekStarGiftCounts)) {
      return null;
    }

    UserProfile baseInfo = userProfileGateway.getByUserId(weekStarGiftCounts.get(0).getUserId());
    if (Objects.isNull(baseInfo)) {
      return new LastWeekStarGiftUserRankCO().setGiftId(giftId);
    }

    return new LastWeekStarGiftUserRankCO()
        .setUserId(baseInfo.getId())
        .setGiftId(giftId)
        .setUserAvatar(baseInfo.getUserAvatar())
        .setUserNickname(baseInfo.getUserNickname())
        .setQuantity(NumUtils.formatLong(weekStarGiftCounts.get(0).getQuantity()))
        .setCountryCode(baseInfo.getCountryCode())
        .setCountryName(baseInfo.getCountryName());
  }


}
