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

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.cmd.activity.WeekKingQueenRankingQueryCmd;
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.WeekKingQueenCount;
import com.red.circle.other.infra.database.mongo.service.activity.WeekKingQueenCountService;
import com.red.circle.other.infra.utils.UserIdEncryptUtils;
import com.red.circle.other.inner.enums.config.EnumConfigKey;
import com.red.circle.other.inner.enums.activity.KingQueenType;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
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 java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;

/**
 * 国王/王后排行榜数据查询.
 *
 * @author pengliang on 2021/12/29
 */
@Component
@RequiredArgsConstructor
public class WeekKingQueenRankingQueryExe {

  private final UserProfileGateway userProfileGateway;
  private final UserProfileAppConvertor userProfileAppConvertor;
  private final WeekKingQueenCountService weekKingQueenCountService;
  private final EnumConfigCacheService enumConfigCacheService;

  public PageResult<UserRankCO> execute(WeekKingQueenRankingQueryCmd cmd) {
    Page<WeekKingQueenCount> kingQueenCountPage = pageWeekTop(cmd.getReqSysOrigin().getOrigin(),
        KingQueenType.valueOf(cmd.getKingQueenType()),
        Objects.equals(cmd.getType(), WeekLeaderboardEnum.THIS_WEEK) ? getThisWeekDate() : getLastWeekDate(),
        cmd.getCurrent(), cmd.getSize());

    List<WeekKingQueenCount> weekKingQueens = kingQueenCountPage.getContent();

    if (CollectionUtils.isEmpty(weekKingQueens)) {
      return null;
    }
    Set<Long> userIds = getUserIds(weekKingQueens);
    Map<Long, UserProfileDTO> userProfileMap = userProfileAppConvertor.toMapUserProfileDTO(
        userProfileGateway.mapByUserIds(userIds));
    Set<Long> invisibleUserIds = userProfileGateway.filterUsersByVipAbility(userIds, VipAbilityType.MYSTERIOUS_INVISIBILITY);

    List<UserRankCO> userRankList = weekKingQueens.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()))
                .setUserNickname("****")
                .setQuantity(NumUtils.formatLong(item.getQuantity()))
                .setRank(item.getRank())
                .setCountryName(null)
                .setCountryCode(null);
          }
          return new UserRankCO()
              .setUserId(userProfile.getId())
              .setAccount(userProfile.getAccount())
              .setUserAvatar(userProfile.getUserAvatar())
              .setUserNickname(userProfile.getUserNickname())
              .setQuantity(NumUtils.formatLong(item.getQuantity()))
              .setRank(item.getRank())
              .setCountryName(userProfile.getCountryName())
              .setCountryCode(userProfile.getCountryCode());
        }).filter(Objects::nonNull).toList();



    PageResult<UserRankCO> result = new PageResult<>();
    result.setTotal(kingQueenCountPage.getTotalElements());
    result.setCurrent(kingQueenCountPage.getNumber());
    result.setSize(kingQueenCountPage.getSize());
    result.setRecords(userRankList);

    return result;
  }


  private List<WeekKingQueenCount> listLeaderboard(WeekKingQueenRankingQueryCmd cmd) {
    if (Objects.equals(cmd.getType(), WeekLeaderboardEnum.THIS_WEEK)) {
      return weekKingQueenCountService
          .listThisWeekTop(cmd.getReqSysOrigin().getOrigin(),
              KingQueenType.valueOf(cmd.getKingQueenType()),
              cmd.getTopSize());
    }

    if (Objects.equals(cmd.getType(), WeekLeaderboardEnum.LAST_WEEK)) {
      return weekKingQueenCountService
          .listLastWeekTop(cmd.getReqSysOrigin().getOrigin(),
              KingQueenType.valueOf(cmd.getKingQueenType()),
              cmd.getTopSize());
    }

    return CollectionUtils.newArrayList();
  }

  private Page<WeekKingQueenCount> pageWeekTop(String sysOrigin, KingQueenType type, String group, Long current, Long size) {
    return weekKingQueenCountService.pageWeekQuery(sysOrigin, type, group, current, size);
  }

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

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


  private String getLastWeekDate() {
    return ZonedDateTimeUtils.format(ZonedDateTimeAsiaRiyadhUtils.getLastWeekMonday(),
        DateFormatConstant.yyyyMMdd);
  }


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


}
