package com.red.circle.other.app.command.game.roompk;


import com.google.common.collect.Lists;
import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.clientobject.game.GameRoomPkWinnerCO;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.infra.database.mongo.entity.live.RoomProfile;
import com.red.circle.other.infra.database.mongo.service.live.RoomProfileManagerService;
import com.red.circle.other.infra.database.rds.entity.game.GameRoomPkWinnerRecord;
import com.red.circle.other.infra.database.rds.service.game.GameRoomPkWinnerRecordService;
import com.red.circle.other.inner.enums.game.GamePkTypeEnum;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * 房间PK - 最新的十位优胜者.
 *
 * @author pengshigang on 2021/9/26
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class GameRoomPkWinnerListCmdExe {

  private final UserProfileGateway userProfileGateway;
  private final UserProfileAppConvertor userProfileAppConvertor;
  private final RoomProfileManagerService roomProfileManagerService;
  private final GameRoomPkWinnerRecordService gameRoomPkWinnerRecordService;

  public List<GameRoomPkWinnerCO> execute(AppExtCommand cmd) {

    List<GameRoomPkWinnerRecord> listWinner = getWinnerRecordList(cmd);

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

    Map<Long, UserProfileDTO> mapUser = getMapUser(listWinner);
    Map<Long, RoomProfile> mapRoom = getMapRoomProfile(listWinner);

    return listWinner.stream().map(winner -> {

      if (Objects.equals(winner.getPkType(), GamePkTypeEnum.ROOM_VS_ROOM.name())) {

        RoomProfile room = mapRoom.get(winner.getUserId());
        if (Objects.isNull(room)) {
          return null;
        }

        return new GameRoomPkWinnerCO()
            .setId(winner.getId())
            .setWinnerUserId(winner.getUserId())
            .setWinnerCover(room.getRoomCover())
            .setIntegral(winner.getIntegral())
            .setPkType(winner.getPkType());
      }

      UserProfileDTO user = mapUser.get(winner.getUserId());
      if (Objects.isNull(user)) {
        return null;
      }

      return new GameRoomPkWinnerCO()
          .setId(winner.getId())
          .setWinnerUserId(winner.getUserId())
          .setWinnerCover(user.getUserAvatar())
          .setIntegral(winner.getIntegral())
          .setPkType(winner.getPkType());
    }).filter(Objects::nonNull).collect(Collectors.toList());

  }

  private List<GameRoomPkWinnerRecord> getWinnerRecordList(AppExtCommand cmd) {
    return gameRoomPkWinnerRecordService.listTop10(cmd.getReqSysOrigin().getOrigin());
  }

  private Map<Long, UserProfileDTO> getMapUser(List<GameRoomPkWinnerRecord> listWinner) {
    return userProfileAppConvertor.toMapUserProfileDTO(userProfileGateway.mapByUserIds(
        listWinner.stream()
            .filter(
                record -> !Objects.equals(record.getPkType(), GamePkTypeEnum.ROOM_VS_ROOM.name()))
            .map(GameRoomPkWinnerRecord::getUserId).collect(Collectors.toSet())));
  }

  private Map<Long, RoomProfile> getMapRoomProfile(List<GameRoomPkWinnerRecord> listWinner) {
    return roomProfileManagerService.mapProfileByRoomIds(
        listWinner.stream()
            .filter(
                record -> Objects.equals(record.getPkType(), GamePkTypeEnum.ROOM_VS_ROOM.name()))
            .map(GameRoomPkWinnerRecord::getUserId).collect(Collectors.toSet()));
  }


}
