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.enums.WeekLeaderboardEnum;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.clientobject.activity.UserRankCO;
import com.red.circle.other.app.dto.clientobject.activity.WeekStarGiftUserRankCO;
import com.red.circle.other.app.dto.cmd.activity.WeekStarRankingQueryCmd;
import com.red.circle.other.domain.enums.VipAbilityType;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.infra.database.cache.service.other.EnumConfigCacheService;
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.utils.UserIdEncryptUtils;
import com.red.circle.other.inner.enums.config.EnumConfigKey;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.num.NumUtils;

import java.util.*;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;

/**
 * 礼物-周星排行榜数据查询.
 *
 * @author pengliang on 2021/4/20
 */
@Component
@RequiredArgsConstructor
public class WeekStarGiftRankingQueryExe {

  private final UserProfileGateway userProfileGateway;
  private final UserProfileAppConvertor userProfileAppConvertor;
  private final WeekStarGiftCountService weekStarGiftCountService;
  private final EnumConfigCacheService enumConfigCacheService;

  public WeekStarGiftUserRankCO execute(WeekStarRankingQueryCmd cmd) {
    WeekStarGiftUserRankCO result = new WeekStarGiftUserRankCO()
        .setGiftId(cmd.getGiftId())
        .setRankUsers(leaderboard(cmd, cmd.getCurrent(), cmd.getSize()));
    return result;
  }

  /**
   * 将 WeekStarGiftCount 转换为 UserRankCO.
   */
  private UserRankCO convertToUserRankCO(WeekStarGiftCount weekStarGiftCount) {
    if (Objects.isNull(weekStarGiftCount)) {
      return null;
    }
    
    // 获取用户信息
    Map<Long, UserProfileDTO> userProfileMap = userProfileAppConvertor.toMapUserProfileDTO(
        userProfileGateway.mapByUserIds(Set.of(weekStarGiftCount.getUserId()))
    );
    
    UserProfileDTO userProfile = userProfileMap.get(weekStarGiftCount.getUserId());
    if (Objects.isNull(userProfile)) {
      return null;
    }
    
    return new UserRankCO()
        .setUserId(userProfile.getId())
        .setAccount(userProfile.getAccount())
        .setUserAvatar(userProfile.getUserAvatar())
        .setRank(weekStarGiftCount.getRank())
        .setUserNickname(userProfile.getUserNickname())
        .setQuantity(NumUtils.formatLong(weekStarGiftCount.getQuantity()))
        .setCountryCode(userProfile.getCountryCode())
        .setCountryName(userProfile.getCountryName());
  }


  private PageResult<UserRankCO> leaderboard(WeekStarRankingQueryCmd cmd, Integer current, Integer size) {
    PageResult<WeekStarGiftCount> pageResult = listLeaderboard(cmd,current,size);

    if (CollectionUtils.isEmpty(pageResult.getRecords())) {
      return null;
    }

    List<WeekStarGiftCount> weekStarGiftCounts = (List<WeekStarGiftCount>) pageResult.getRecords();

    Set<Long> userIds = getUserIds(weekStarGiftCounts);
    Map<Long, UserProfileDTO> userProfileMap = userProfileAppConvertor.toMapUserProfileDTO(
        userProfileGateway.mapByUserIds(userIds)
    );
    Set<Long> invisibleUserIds = userProfileGateway.filterUsersByVipAbility(userIds, VipAbilityType.MYSTERIOUS_INVISIBILITY);

    List<UserRankCO> list = weekStarGiftCounts.stream()
        .map(item -> {
          UserProfileDTO userProfile = userProfileMap.get(item.getUserId());
          if (Objects.isNull(userProfile)) {
            return null;
          }
          if (invisibleUserIds.contains(item.getUserId())) {
            return new UserRankCO()
                .setUserId(null)
                .setEncryptedId(UserIdEncryptUtils.encrypt(userProfile.getId()))
                .setAccount(null)
                .setUserAvatar(enumConfigCacheService.getValue(EnumConfigKey.USER_YINSHEN_COVER, userProfile.getSysOriginChild()))
                .setRank(item.getRank())
                .setUserNickname("****")
                .setQuantity(NumUtils.formatLong(item.getQuantity()))
                .setCountryCode(null)
                .setCountryName(null);
          }
          return new UserRankCO()
              .setUserId(userProfile.getId())
              .setAccount(userProfile.getAccount())
              .setUserAvatar(userProfile.getUserAvatar())
              .setRank(item.getRank())
              .setUserNickname(userProfile.getUserNickname())
              .setQuantity(NumUtils.formatLong(item.getQuantity()))
              .setCountryCode(userProfile.getCountryCode())
              .setCountryName(userProfile.getCountryName());
        })
        .filter(Objects::nonNull)
        .toList();

    PageResult<UserRankCO> result = new PageResult<>();
    result.setTotal(pageResult.getTotal());
    result.setRecords(list);
    result.setSize(pageResult.getSize());
    return result;
  }

  private PageResult<WeekStarGiftCount> listLeaderboard(WeekStarRankingQueryCmd cmd, Integer current, Integer size) {
    if (Objects.equals(cmd.getType(), WeekLeaderboardEnum.THIS_WEEK)) {
      return weekStarGiftCountService
        .listThisWeekTopV2(cmd.getReqSysOrigin().getOrigin(), PageRequest.of(current - 1, size));

    }
    if (Objects.equals(cmd.getType(), WeekLeaderboardEnum.LAST_WEEK)) {
      return weekStarGiftCountService
          .listLastWeekTopV2(cmd.getReqSysOrigin().getOrigin(), PageRequest.of(current - 1, size));
    }

    return PageResult.newPageResult(20);
  }

  public UserRankCO myRank(WeekStarRankingQueryCmd cmd) {
    if (Objects.equals(cmd.getType(), WeekLeaderboardEnum.THIS_WEEK)) {
      WeekStarGiftCount myThisWeekRank = weekStarGiftCountService.getMyThisWeekRank(cmd.getReqSysOrigin().getOrigin(), cmd.getReqUserId());
      if (Objects.isNull(myThisWeekRank)) {
        myThisWeekRank = new  WeekStarGiftCount();
        myThisWeekRank.setRank(0);
        myThisWeekRank.setUserId(cmd.getReqUserId());
        myThisWeekRank.setQuantity(0L);
      }
      return convertToUserRankCO(myThisWeekRank);
    }
    if (Objects.equals(cmd.getType(), WeekLeaderboardEnum.LAST_WEEK)) {
      WeekStarGiftCount myLastWeekRank = weekStarGiftCountService.getMyLastWeekRank(
          cmd.getReqSysOrigin().getOrigin(),
          cmd.getReqUserId()
      );
      if (Objects.isNull(myLastWeekRank)) {
        myLastWeekRank = new  WeekStarGiftCount();
        myLastWeekRank.setRank(0);
        myLastWeekRank.setUserId(cmd.getReqUserId());
        myLastWeekRank.setQuantity(0L);
      }

      return convertToUserRankCO(myLastWeekRank);
    }
    return null;
  }


  private Set<Long> getUserIds(List<WeekStarGiftCount> weekStarGiftCounts) {

    return weekStarGiftCounts.stream().map(WeekStarGiftCount::getUserId)
        .collect(Collectors.toSet());
  }

}
