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


import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.red.circle.common.business.core.enums.GameStateEnum;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.common.business.dto.cmd.RoomIdLastIdCmd;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.clientobject.game.GameRoomPkStartedListCO;
import com.red.circle.other.app.dto.clientobject.game.GameRoomPkUserCO;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.infra.database.cache.service.other.GameRoomPkCacheService;
import com.red.circle.other.infra.database.rds.entity.game.GameRoomPkRecord;
import com.red.circle.other.infra.database.rds.service.game.GameRoomPkRecordService;
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.*;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * 房间PK - 已开始的PK列表.
 *
 * @author pengshigang on 2021/9/25
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class GameRoomPkStartedListCmdExe {

  private final UserProfileGateway userProfileGateway;
  private final GameRoomPkCacheService gameRoomPkCacheService;
  private final UserProfileAppConvertor userProfileAppConvertor;
  private final GameRoomPkRecordService gameRoomPkRecordService;

  public Set<GameRoomPkStartedListCO> execute(RoomIdLastIdCmd cmd) {

    List<GameRoomPkRecord> pkList = listStarted(cmd);

    GameRoomPkRecord ownRoomPkRecord = getByRoomIdByStatus(cmd);
    if (Objects.nonNull(ownRoomPkRecord)) {
      pkList.add(0, ownRoomPkRecord);
    }

    GameRoomPkRecord ownUserPkRecord = getByUserIdByStatus(cmd);
    if (Objects.nonNull(ownUserPkRecord) && Objects.isNull(ownRoomPkRecord)) {
      pkList.add(0, ownUserPkRecord);
    }

    return pkList.stream().map(pk -> {
      GameRoomPkUserCO pkCO = gameRoomPkCacheService.getRoomPk(pk.getId(), GameRoomPkUserCO.class);
      if (Objects.isNull(pkCO)) {
        return null;
      }
      return new GameRoomPkStartedListCO()
          .setId(pk.getId())
          .setOverTime(pk.getEndTime().getTime())
          .setSponsorUserId(pkCO.getSponsorUserId())
          .setSponsorRoomId(pkCO.getSponsorRoomId())
          .setSponsorCover(pkCO.getSponsorCover())
          .setSponsorName(pkCO.getSponsorName())
          .setSponsorUserAccount(pkCO.getSponsorUserAccount())
          .setRecipientUserId(pkCO.getRecipientUserId())
          .setSponsorUserRegion(pkCO.getSponsorUserRegion())
          .setRecipientRoomId(pkCO.getRecipientRoomId())
          .setRecipientCover(pkCO.getRecipientCover())
          .setRecipientName(pkCO.getRecipientName())
          .setRecipientUserAccount(pkCO.getRecipientUserAccount())
          .setPkType(pk.getPkType());

    }).filter(Objects::nonNull).collect(Collectors.toSet());
  }

  private Map<Long, UserProfileDTO> mapUserByData(List<GameRoomPkRecord> pkList) {

    Set<Long> userIds = Optional.of(pkList.stream()
        .filter(
            record -> !Objects.equals(record.getPkType(), GamePkTypeEnum.ROOM_VS_ROOM.name()))
        .map(GameRoomPkRecord::getSponsorUserId)
        .collect(Collectors.toSet())).orElse(Sets.newHashSet());

    userIds.addAll(pkList.stream()
        .filter(
            record -> !Objects.equals(record.getPkType(), GamePkTypeEnum.ROOM_VS_ROOM.name()))
        .map(GameRoomPkRecord::getRecipientUserId)
        .collect(Collectors.toSet()));

    if (CollectionUtils.isEmpty(userIds)) {
      return Maps.newHashMap();
    }

    return userProfileAppConvertor.toMapUserProfileDTO(userProfileGateway.mapByUserIds(userIds));
  }

  private GameRoomPkRecord getByUserIdByStatus(RoomIdLastIdCmd cmd) {
    return gameRoomPkRecordService
        .getByUserIdByStatus(cmd.requiredReqUserId(), GameStateEnum.STARTED);
  }

  private GameRoomPkRecord getByRoomIdByStatus(RoomIdLastIdCmd cmd) {
    return gameRoomPkRecordService
        .getByRoomIdByStatus(cmd.getRoomId(), GameStateEnum.STARTED);
  }

  private List<GameRoomPkRecord> listStarted(RoomIdLastIdCmd cmd) {
    return gameRoomPkRecordService
        .listByLastIdByStatus(cmd.getLastId(),
            SysOriginPlatformEnum.valueOf(cmd.getReqSysOrigin().getOrigin()), GameStateEnum.STARTED,
            cmd.getRoomId(), cmd.requiredReqUserId());
  }


}
