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

import com.google.common.collect.Lists;
import com.red.circle.common.business.core.constant.KeywordConstant;
import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.common.business.enums.SVIPLevelEnum;
import com.red.circle.other.app.convertor.live.RoomProfileAppConvertor;
import com.red.circle.other.app.convertor.material.PropsMaterialAppConvertor;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.clientobject.game.GameTrumpetRecordCO;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.gateway.user.ability.UserSVipGateway;
import com.red.circle.other.infra.database.mongo.entity.game.trumpet.GameTrumpetCount;
import com.red.circle.other.infra.database.mongo.entity.live.RoomProfile;
import com.red.circle.other.infra.database.mongo.service.game.GameTrumpetCountService;
import com.red.circle.other.infra.database.mongo.service.live.RoomProfileManagerService;
import com.red.circle.other.inner.model.dto.live.RoomProfileDTO;
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.Component;

/**
 * <p>
 * 喇叭列表 前端控制器.
 * </p>
 *
 * @author pengshigang
 * @since 2022-8-9
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class GameTrumpetQueryExe {

  private final PropsMaterialAppConvertor propsMapper;
  private final UserSVipGateway userSVipGateway;
  private final UserProfileGateway userProfileGateway;
  private final RoomProfileAppConvertor roomProfileMapper;
  private final UserProfileAppConvertor userProfileAppConvertor;
  private final GameTrumpetCountService gameTrumpetCountService;
  private final RoomProfileManagerService roomProfileManagerService;

  public List<GameTrumpetRecordCO> execute(AppExtCommand cmd) {

    List<String> languages1 = List.of("ar", "tr");
    List<String> languages2 = List.of("bn", "fa", "hi", "in", "tl", "ur", "en");
    List<GameTrumpetCount> records = gameTrumpetCountService
        .listLatestTopSize(cmd.getReqSysOrigin().getOrigin(),
            languages1.contains(cmd.getReqLanguage()) ? languages1 : languages2, 50);

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

    Map<Long, UserProfileDTO> mapUser = getUserMap(records);

    Map<Long, RoomProfile> mapRoom = roomProfileManagerService
        .mapProfileByRoomIds(records.stream().map(GameTrumpetCount::getRoomId).collect(
            Collectors.toSet()));

    Map<Long, SVIPLevelEnum> superVipLevelEnumMap = userSVipGateway.checkSVipIdentity(
        records.stream().map(GameTrumpetCount::getUserId).collect(
            Collectors.toSet()));

    return records.stream().map(game -> {

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

          RoomProfile roomProfile = mapRoom.get(game.getRoomId());

          RoomProfileDTO roomProfileCO = new RoomProfileDTO();
          if (Objects.nonNull(roomProfile)) {
            roomProfileCO = roomProfileMapper.toRoomProfileDTO(roomProfile);
          }

          return new GameTrumpetRecordCO()
              .setId(game.getId())
              .setMessage(KeywordConstant.filter(game.getMessage()))
              .setRoomProfileCO(roomProfileCO)
              .setCreateTime(game.getCreateTime())
              .setUserSVipLevel(superVipLevelEnumMap.get(userProfile.getId()))
              .setUserProfileCO(userProfile)
              .setUseProps(
                  propsMapper.userUsePropsToPropsUserBackpackCOList(userProfile.getUseProps()));
        })
        .filter(Objects::nonNull)
        .toList();
  }

  private Map<Long, UserProfileDTO> getUserMap(List<GameTrumpetCount> records) {
    return userProfileAppConvertor.toMapUserProfileDTO(userProfileGateway.mapByUserIds(
        records.stream().map(GameTrumpetCount::getUserId).collect(Collectors.toSet())));
  }


}
