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

import com.google.common.collect.Lists;
import com.red.circle.other.app.dto.clientobject.game.GameEggLotteryRecordCO;
import com.red.circle.other.app.dto.clientobject.game.GameEggRewardCO;
import com.red.circle.other.app.dto.cmd.game.GameEggLotteryPageCmd;
import com.red.circle.other.infra.database.rds.entity.game.GameUserLotteryRecord;
import com.red.circle.other.infra.database.rds.service.game.GameUserLotteryDetailsRecordService;
import com.red.circle.other.infra.database.rds.service.game.GameUserLotteryRecordService;
import com.red.circle.other.infra.enums.game.LotteryGameTypeEnum;
import com.red.circle.other.inner.model.dto.game.GameUserLotteryDetailsRecordDTO;
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 org.springframework.stereotype.Component;

/**
 * <p>
 * 砸金蛋抽奖记录.
 * </p>
 *
 * @author pengshigang
 * @since 2021-11-16
 */
@Component
@RequiredArgsConstructor
public class GameEggLotteryRecordExe {

  private final GameUserLotteryRecordService gameUserLotteryRecordService;
  private final GameUserLotteryDetailsRecordService gameUserLotteryDetailsRecordService;

  public List<GameEggLotteryRecordCO> execute(GameEggLotteryPageCmd cmd) {

    List<GameUserLotteryRecord> records = listByUserId(cmd);
    if (CollectionUtils.isEmpty(records)) {
      return Lists.newArrayList();
    }

    Map<Long, List<GameUserLotteryDetailsRecordDTO>> detailsRecordMap = getDetailsRecordMap(
        records);

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

      List<GameUserLotteryDetailsRecordDTO> detailsRecord = detailsRecordMap.get(record.getId());
      if (CollectionUtils.isEmpty(detailsRecord)) {
        return null;
      }
      return new GameEggLotteryRecordCO()
          .setEggList(detailsRecord.stream().map(details -> new GameEggRewardCO()
                  .setId(details.getId())
                  .setCover(details.getCover())
                  .setType(details.getType())
                  .setDetailType(details.getDetailType())
                  .setShredCount(details.getQuantity())
                  .setContent(details.getContent())
              ).toList()
          )
          .setCreateTime(record.getCreateTime());

    }).filter(Objects::nonNull).toList();

  }

  private Map<Long, List<GameUserLotteryDetailsRecordDTO>> getDetailsRecordMap(
      List<GameUserLotteryRecord> records) {
    return gameUserLotteryDetailsRecordService.mapByLotteryIds(
        records.stream().map(GameUserLotteryRecord::getId).collect(Collectors.toSet()));
  }

  private List<GameUserLotteryRecord> listByUserId(GameEggLotteryPageCmd cmd) {
    return gameUserLotteryRecordService
        .listByUserId(cmd.getReqUserId(), cmd.getSingle(), LotteryGameTypeEnum.EGG.name());
  }

}
