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

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.other.app.convertor.game.GameLuckyBoxConvertor;
import com.red.circle.other.app.dto.clientobject.game.GameLuckyBoxBountyConfigCO;
import com.red.circle.other.app.dto.clientobject.game.GameLuckyBoxBountyDetailsConfigCO;
import com.red.circle.other.infra.database.cache.service.other.GameNewLuckyBoxCacheService;
import com.red.circle.other.infra.database.rds.entity.game.GameLuckyBoxBountyConfig;
import com.red.circle.other.infra.database.rds.entity.game.GameLuckyBoxBountyDetailsConfig;
import com.red.circle.other.infra.database.rds.entity.gift.GiftConfig;
import com.red.circle.other.infra.database.rds.entity.props.PropsSourceRecord;
import com.red.circle.other.infra.database.rds.service.game.GameLuckyBoxBountyConfigService;
import com.red.circle.other.infra.database.rds.service.game.GameLuckyBoxBountyDetailsConfigService;
import com.red.circle.other.infra.database.rds.service.gift.GiftConfigService;
import com.red.circle.other.infra.database.rds.service.props.PropsSourceRecordService;
import com.red.circle.tool.core.collection.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * 获取赏金任务相关信息
 *
 * @author zongpubin on 2023/8/28
 */

@Component
@RequiredArgsConstructor
public class GameLuckyBoxBountyConfigQryExe {

  private final GiftConfigService giftConfigService;
  private final GameLuckyBoxConvertor gameLuckyBoxConvertor;
  private final PropsSourceRecordService propsSourceRecordService;
  private final GameNewLuckyBoxCacheService gameNewLuckyBoxCacheService;
  private final GameLuckyBoxBountyConfigService gameLuckyBoxBountyConfigService;
  private final GameLuckyBoxBountyDetailsConfigService gameLuckyBoxBountyDetailsConfigService;

  public List<GameLuckyBoxBountyConfigCO> execute(AppExtCommand cmd) {
    List<GameLuckyBoxBountyConfig> gameLuckyBoxBountyConfigs = gameLuckyBoxBountyConfigService.listBySysOrigin(
        cmd.requireReqSysOrigin());
    if (CollectionUtils.isEmpty(gameLuckyBoxBountyConfigs)) {
      return Lists.newArrayList();
    }
    Map<Long, GameLuckyBoxBountyConfig> bountyConfigMap = gameLuckyBoxBountyConfigService.getMap(
        cmd.requireReqSysOrigin());

    List<GameLuckyBoxBountyDetailsConfig> boxBountyDetailsConfig = gameLuckyBoxBountyDetailsConfigService.getBoxBountyDetailsConfig(
        cmd.requireReqSysOrigin());

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

    Map<Long, GiftConfig> longGiftConfigMap = giftConfigService.mapByIds(
        gameLuckyBoxBountyConfigs.stream().map(GameLuckyBoxBountyConfig::getGiftId).collect(
            Collectors.toSet()));

    Map<Long, PropsSourceRecord> propsSourceRecordMap = propsSourceRecordService.mapByIds(
        boxBountyDetailsConfig.stream()
            .map(GameLuckyBoxBountyDetailsConfig::getPropsId).collect(
                Collectors.toSet()));

    // 查询抽中目标礼物次数
    Integer luckyBoxAwardDayCount = gameNewLuckyBoxCacheService.getLuckyBoxAwardDay(
        cmd.requiredReqUserId());

    Integer luckyBoxAwardWeekCount = gameNewLuckyBoxCacheService.getLuckyBoxAwardWeek(
        cmd.requiredReqUserId());

    // 是否领取目标奖励
    List<Integer> receiveLuckyBoxAwardDay = gameNewLuckyBoxCacheService.getReceiveLuckyBoxAwardDay(
        cmd.requiredReqUserId());

    List<Integer> receiveLuckyBoxAwardWeek = gameNewLuckyBoxCacheService.getReceiveLuckyBoxAwardWeek(
        cmd.requiredReqUserId());

    Map<Long, List<GameLuckyBoxBountyDetailsConfigCO>> bountyDetailsConfigMap = Optional.ofNullable(
        boxBountyDetailsConfig).map(bountyDetailsConfigs -> bountyDetailsConfigs.stream().map(
            bountyDetailsConfig -> {
              GameLuckyBoxBountyDetailsConfigCO bountyDetailsConfigCO = gameLuckyBoxConvertor.toLuckyBoxBountyConfigDetailsCO(
                  bountyDetailsConfig);
              PropsSourceRecord sourceRecord = propsSourceRecordMap.get(
                  bountyDetailsConfigCO.getPropsId());

              bountyDetailsConfigCO.setCover(sourceRecord.getCover());
              bountyDetailsConfigCO.setSourceUrl(sourceRecord.getSourceUrl());
              bountyDetailsConfigCO.setAmount(sourceRecord.getAmount());
              bountyDetailsConfigCO.setReceived(Boolean.FALSE);

              GameLuckyBoxBountyConfig gameLuckyBoxBountyConfig = bountyConfigMap.get(
                  bountyDetailsConfigCO.getBountyId());

              if (Objects.equals("DAILY", gameLuckyBoxBountyConfig.getType())) {
                bountyDetailsConfigCO.setCompletedCount(luckyBoxAwardDayCount);
                if (CollectionUtils.isNotEmpty(receiveLuckyBoxAwardDay)
                    && receiveLuckyBoxAwardDay.contains(bountyDetailsConfigCO.getTargetQuantity())) {
                  bountyDetailsConfigCO.setReceived(Boolean.TRUE);
                }

              } else {
                bountyDetailsConfigCO.setCompletedCount(luckyBoxAwardWeekCount);
                if (CollectionUtils.isNotEmpty(receiveLuckyBoxAwardWeek)
                    && receiveLuckyBoxAwardWeek.contains(bountyDetailsConfigCO.getTargetQuantity())) {
                  bountyDetailsConfigCO.setReceived(Boolean.TRUE);
                }
              }

              return bountyDetailsConfigCO;
            })
        .collect(Collectors.groupingBy(GameLuckyBoxBountyDetailsConfigCO::getBountyId))).orElse(
        Maps.newHashMap());

    return gameLuckyBoxBountyConfigs.stream().map(boxBountyConfig ->
        new GameLuckyBoxBountyConfigCO()
            .setId(boxBountyConfig.getId())
            .setBountyDetailsConfigs(bountyDetailsConfigMap.get(boxBountyConfig.getId()))
            .setGiftId(boxBountyConfig.getGiftId())
            .setGiftType(boxBountyConfig.getGiftType())
            .setPhotoUrl(longGiftConfigMap.get(boxBountyConfig.getGiftId()).getGiftPhoto())
            .setType(boxBountyConfig.getType())
            .setSysOrigin(boxBountyConfig.getSysOrigin())
            .setCreateTime(boxBountyConfig.getCreateTime())
    ).collect(Collectors.toList());
  }
}
