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

import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.common.business.enums.SendPropsOrigin;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.other.app.dto.cmd.game.GameEggExchangeCmd;
import com.red.circle.other.infra.common.activity.PropsActivitySendCommon;
import com.red.circle.other.infra.common.activity.send.SendRewardParam;
import com.red.circle.other.infra.database.mongo.entity.game.egg.GameEggStockConfig;
import com.red.circle.other.infra.database.mongo.service.game.GameEggStockConfigService;
import com.red.circle.other.infra.database.rds.entity.game.GameUserShardsBackpack;
import com.red.circle.other.infra.database.rds.entity.game.GameUserShardsExchangeRecord;
import com.red.circle.other.infra.database.rds.service.game.GameUserShardsBackpackService;
import com.red.circle.other.infra.database.rds.service.game.GameUserShardsExchangeRecordService;
import com.red.circle.other.inner.asserts.GameErrorCode;
import com.red.circle.other.inner.model.cmd.material.PrizeDescribe;
import java.util.List;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * <p>
 * 砸金蛋碎片兑换奖励.
 * </p>
 *
 * @author pengshigang
 * @since 2021-11-16
 */
@Component
@RequiredArgsConstructor
public class GameEggExchangeAwardExe {

  private final PropsActivitySendCommon sendPropsManager;
  private final GameEggStockConfigService gameEggStockConfigService;
  private final GameUserShardsBackpackService gameUserShardsBackpackService;
  private final GameUserShardsExchangeRecordService gameUserShardsExchangeRecordService;


  public Long execute(GameEggExchangeCmd cmd) {

    GameEggStockConfig config = getGameEggConfigCache(cmd);
    GameUserShardsBackpack shardsBackpack = getShardsBackpack(cmd);
    long exchangeSize = getExchangeSize(config, shardsBackpack);

    // 修改用户背包碎片数量
    ResponseAssert.isTrue(GameErrorCode.MISSING_FRAGMENTS_ERROR,
        gameUserShardsBackpackService.reduceShardsQuantity(shardsBackpack.getId(),
            exchangeSize * config.getFragmentsSize()));

    // 发送奖品
    sendPropsManager.sendGroup(SendRewardParam.builder()
            .acceptUserId(cmd.getReqUserId())
            .origin(SendPropsOrigin.EGG)
            .sysOrigin(SysOriginPlatformEnum.valueOf(cmd.getReqSysOrigin().getOrigin()))
            .trackId(cmd.getConfigId())
            .build(),
        getPrizeDescribes(config, shardsBackpack, exchangeSize));

    // 添加兑换记录
    gameUserShardsExchangeRecordService.save(new GameUserShardsExchangeRecord()
        .setUserId(cmd.getReqUserId())
        .setType(config.getSourceType())
        .setDetailType(config.getSourceDetailType())
        .setContent(
            Objects.toString(Objects.isNull(config.getSourceId()) ? config.getPrizeQuantity()
                : config.getSourceId()))
        .setQuantity((int) exchangeSize)
        .setCover(config.getSourceCover())
        .setSysOrigin(cmd.getReqSysOrigin().getOrigin())
    );

    return exchangeSize;
  }

  private List<PrizeDescribe> getPrizeDescribes(GameEggStockConfig config,
      GameUserShardsBackpack shardsBackpack, long exchangeSize) {
    PrizeDescribe prize = new PrizeDescribe()
        .setTrackId(shardsBackpack.getId())
        .setType(config.getSourceType())
        .setDetailType(config.getSourceDetailType())
        .setContent(Objects.isNull(config.getSourceId())
            ? config.getPrizeQuantity().toString()
            : config.getSourceId().toString())
        .setQuantity(config.getPrizeQuantity());
    List<PrizeDescribe> prizeDescribes = Lists.newArrayList();
    for (int index = 0; index < exchangeSize; index++) {
      prizeDescribes.add(prize);
    }
    return prizeDescribes;
  }

  private long getExchangeSize(GameEggStockConfig config, GameUserShardsBackpack shardsBackpack) {
    long exchangeSize = shardsBackpack.getQuantity() / config.getFragmentsSize();
    ResponseAssert.isTrue(GameErrorCode.MISSING_FRAGMENTS_ERROR, exchangeSize > 0);

    if (Objects.equals(config.getStockQuantity(), -1L)) {
      return exchangeSize;
    }
    return exchangeSize > config.getStockQuantity()
        ? config.getStockQuantity().intValue()
        : exchangeSize;
  }

  private GameEggStockConfig getGameEggConfigCache(GameEggExchangeCmd cmd) {
    GameEggStockConfig config = gameEggStockConfigService.getConfigById(
        cmd.getConfigId());
    ResponseAssert.notNull(GameErrorCode.SHARDS_INVALID_ERROR, config);
    ResponseAssert.isTrue(GameErrorCode.SHARDS_INVALID_ERROR,
        Objects.nonNull(config.getFragmentsSize()) && config.getFragmentsSize() > 0);
    ResponseAssert.isFalse(GameErrorCode.INVENTORY_SHORTAGE_ERROR,
        Objects.equals(config.getStockQuantity(), 0L));
    return config;
  }

  private GameUserShardsBackpack getShardsBackpack(GameEggExchangeCmd cmd) {

    GameUserShardsBackpack shardsBackpack = gameUserShardsBackpackService
        .getOneByConfigIdByUserId(cmd.getConfigId(), cmd.getReqUserId());

    ResponseAssert.notNull(GameErrorCode.MISSING_FRAGMENTS_ERROR, shardsBackpack);

    ResponseAssert.isTrue(GameErrorCode.MISSING_FRAGMENTS_ERROR,
        Objects.nonNull(shardsBackpack.getQuantity()) && shardsBackpack.getQuantity() > 0);

    return shardsBackpack;
  }


}
