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

import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.other.app.dto.clientobject.activity.ActivityLeaderboardCO;
import com.red.circle.other.app.dto.clientobject.activity.ActivityLeaderboardCO.LeaderboardUserCO;
import com.red.circle.other.infra.database.mongo.entity.activity.RankQueenCount;
import com.red.circle.other.infra.database.mongo.entity.activity.RankQueenType;
import com.red.circle.other.infra.database.mongo.entity.live.RoomProfile;
import com.red.circle.other.infra.database.mongo.service.activity.RankCountService;
import com.red.circle.other.infra.database.mongo.service.live.RoomProfileManagerService;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.json.JacksonUtils;
import com.red.circle.tool.core.num.NumUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 房间礼物排行榜.
 *
 * @author pengliang on 2021/2/24
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class RoomGiftsLeaderboardQryExe {

  private final RankCountService rankCountService;
  private final RoomProfileManagerService roomProfileManagerService;

  public ActivityLeaderboardCO execute(AppExtCommand cmd) {
    List<RankQueenCount> hours = getListRank(cmd, RankQueenType.ROOM_RANK_HOUR,50);
    List<RankQueenCount> days = getListRank(cmd, RankQueenType.ROOM_RANK_DAY,50);
    List<RankQueenCount> weeks = getListRank(cmd, RankQueenType.ROOM_RANK_WEEK,50);
    List<RankQueenCount> months = getListRank(cmd, RankQueenType.ROOM_RANK_MONTH,50);

    Set<Long> roomIds = getAllUserIds(days, weeks, months, hours);
    if (CollectionUtils.isEmpty(roomIds)) {
      return ActivityLeaderboardCO.empty();
    }
    Map<Long, RoomProfile> roomProfileMap = roomProfileManagerService.mapProfileByRoomIds(roomIds);

    return new ActivityLeaderboardCO()
        .setHourly(toLeaderboardUserCO(hours, roomProfileMap))
        .setDaily(toLeaderboardUserCO(days, roomProfileMap))
        .setWeekly(toLeaderboardUserCO(weeks, roomProfileMap))
        .setMonthly(toLeaderboardUserCO(months, roomProfileMap));
  }

  public ActivityLeaderboardCO executeApp(AppExtCommand cmd) {

//    List<RankQueenCount> days = getListRank(cmd, RankQueenType.ROOM_RANK_DAY,3);
    List<RankQueenCount> weeks = getListRank(cmd, RankQueenType.ROOM_RANK_WEEK,3);
//    List<RankQueenCount> months = getListRank(cmd, RankQueenType.ROOM_RANK_MONTH,3);

    Set<Long> roomIds = getAllUserIds(null, weeks, null);
    if (CollectionUtils.isEmpty(roomIds)) {
      return ActivityLeaderboardCO.empty();
    }
    Map<Long, RoomProfile> roomProfileMap = roomProfileManagerService.mapProfileByRoomIds(roomIds);

    return new ActivityLeaderboardCO()
            .setDaily(toLeaderboardUserCO(null, roomProfileMap))
            .setWeekly(toLeaderboardUserCO(weeks, roomProfileMap))
            .setMonthly(toLeaderboardUserCO(null, roomProfileMap));
  }

  private Set<Long> getAllUserIds(List<RankQueenCount> days, List<RankQueenCount> weeks,
      List<RankQueenCount> months) {
    Set<Long> roomIds = getRoomIds(days);
    roomIds.addAll(getRoomIds(weeks));
    roomIds.addAll(getRoomIds(months));
    return roomIds;
  }

  private Set<Long> getAllUserIds(List<RankQueenCount> days, List<RankQueenCount> weeks,
                                  List<RankQueenCount> months, List<RankQueenCount> hours) {
    Set<Long> roomIds = getRoomIds(days);
    roomIds.addAll(getRoomIds(weeks));
    roomIds.addAll(getRoomIds(months));
    roomIds.addAll(getRoomIds(hours));
    return roomIds;
  }

  private List<LeaderboardUserCO> toLeaderboardUserCO(List<RankQueenCount> list,
      Map<Long, RoomProfile> roomProfileMap) {

    if (CollectionUtils.isEmpty(list)) {
      return CollectionUtils.newArrayList();
    }
    return list.stream().map(count -> {
      RoomProfile roomProfile = roomProfileMap.get(count.getBusinessId());
      if (Objects.isNull(roomProfile)) {
        log.warn("数据异常,找不到房间记录: {}", JacksonUtils.toJson(count));
        return null;
      }
      return new LeaderboardUserCO()
          .setId(roomProfile.getId())
          .setAvatar(roomProfile.getRoomCover())
          .setNickname(roomProfile.getRoomName())
          .setQuantity(count.getQuantity())
          .setQuantityFormat(NumUtils.formatLong(count.getQuantity()));
    }).filter(Objects::nonNull).collect(Collectors.toList());
  }

  private Set<Long> getRoomIds(List<RankQueenCount> counts) {
    if (CollectionUtils.isEmpty(counts)) {
      return CollectionUtils.newHashSet();
    }
    return counts.stream().map(RankQueenCount::getBusinessId).collect(Collectors.toSet());
  }

  private List<RankQueenCount> getListRank(AppExtCommand cmd, RankQueenType charmRankDay ,Integer size) {
    return Optional
        .ofNullable(rankCountService.listRank(cmd.requireReqSysOrigin(), charmRankDay, size))
        .orElseGet(CollectionUtils::newArrayList);
  }

}
