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

import com.google.common.collect.Lists;
import com.red.circle.common.business.core.enums.GameStateEnum;
import com.red.circle.common.business.dto.cmd.app.AppIdLongCmd;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.clientobject.game.GameIndoorTeamPkTopThreeFansCO;
import com.red.circle.other.app.dto.clientobject.game.GameUserCO;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.infra.database.cache.key.GameListKeys;
import com.red.circle.other.infra.database.cache.service.other.GameRoomPkCacheService;
import com.red.circle.other.infra.database.rds.entity.game.GameIndoorTeamPkRecord;
import com.red.circle.other.infra.database.rds.service.game.GameIndoorTeamPkRecordService;
import com.red.circle.other.infra.enums.game.GamePkBelongTeamEnum;
import com.red.circle.other.inner.asserts.GameErrorCode;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * 房间内团队PK双方前三名支持者信息 - 基本信息.
 *
 * @author pengshigang on 2022/3/4
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class GameTeamPkTopThreeFansCmdExe {

  private final UserProfileGateway userProfileGateway;
  private final GameRoomPkCacheService gameRoomPkCacheService;
  private final UserProfileAppConvertor userProfileAppConvertor;
  private final GameIndoorTeamPkRecordService gameIndoorTeamPkRecordService;

  public GameIndoorTeamPkTopThreeFansCO execute(AppIdLongCmd cmd) {

    GameIndoorTeamPkRecord pkRecord = gameIndoorTeamPkRecordService.getById(cmd.getId());
    checkState(pkRecord);

    String redTeam = GamePkBelongTeamEnum.RED_TEAM.name();
    String blueTeam = GamePkBelongTeamEnum.BLUE_TEAM.name();

    return new GameIndoorTeamPkTopThreeFansCO()
        .setRedTeamFans(buildFans(pkRecord, redTeam))
        .setBlueTeamFans(buildFans(pkRecord, blueTeam))
        .setRedTeamScore(gameRoomPkCacheService.getBelongTeamIntegral(pkRecord.getId(),
            redTeam))
        .setBlueTeamScore(gameRoomPkCacheService.getBelongTeamIntegral(pkRecord.getId(),
            blueTeam));

  }

  /**
   * 获得粉丝列表
   *
   * @param pkRecord pk记录
   * @param team     归属团队
   */
  private List<GameUserCO> buildFans(GameIndoorTeamPkRecord pkRecord, String team) {
    return Optional.ofNullable(
            gameRoomPkCacheService.getBelongTeamFanTopThreeUserIds(pkRecord.getId(), team))
        .map(userIds -> userIds.stream().map(userId -> {
          Long score = gameRoomPkCacheService
              .getBelongTeamFansIntegral(pkRecord.getId(), team, userId);
          UserProfileDTO userProfile = userProfileAppConvertor.toUserProfileDTO(
              userProfileGateway.getByUserId(Long.valueOf(
                  userId)));
          if (Objects.isNull(userProfile)) {
            return null;
          }
          return new GameUserCO()
              .setUserId(userProfile.getId())
              .setUserNickname(userProfile.getUserNickname())
              .setUserSex(userProfile.getUserSex())
              .setUserAvatar(userProfile.getUserAvatar())
              .setAccount(userProfile.getAccount())
              .setTotal(String.valueOf(score));
        }).filter(Objects::nonNull).toList())
        .orElse(Lists.newArrayList());
  }

  private void checkState(GameIndoorTeamPkRecord pkRecord) {
    ResponseAssert.notNull(GameErrorCode.GAME_NOT_EXIST, pkRecord);
    ResponseAssert.isTrue(GameErrorCode.GAME_NOT_EXIST,
        Objects.equals(pkRecord.getGameStatus(), GameStateEnum.WAITING.name()) ||
            Objects.equals(pkRecord.getGameStatus(), GameStateEnum.STARTED.name()));
  }

  private String getKey(Long pkId, String team) {
    return GameListKeys.INDOOR_TEAM_PK_GIFT_SCORE.getKey(pkId + team + "-FANS");
  }
}
