package com.red.circle.other.app.command.team;

import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.common.business.dto.cmd.app.AppIdLongCmd;
import com.red.circle.common.business.enums.SendPropsOrigin;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.other.infra.common.props.PropsSendCommon;
import com.red.circle.other.infra.database.mongo.dto.team.TeamBillMemberTarget;
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamBillCycle;
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamMemberTarget;
import com.red.circle.other.infra.database.mongo.service.team.TeamBillCycleUtils;
import com.red.circle.other.infra.database.mongo.service.team.team.TeamBillCycleService;
import com.red.circle.other.infra.database.mongo.service.team.team.TeamMemberTargetService;
import com.red.circle.other.inner.model.cmd.material.PrizeDescribe;
import com.red.circle.other.inner.model.cmd.material.PrizeDescribeRewardCmd;
import com.red.circle.other.inner.asserts.team.TeamErrorCode;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.wallet.inner.model.enums.GoldOrigin;
import java.util.Objects;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * 领取团队政策道具奖励.
 *
 * @author pengliang on 2023/1/9
 */
@Component
@RequiredArgsConstructor
public class TeamPolicyPropsRewardExe {

  private final RedisService redisService;
  private final PropsSendCommon propsSendCommon;
  private final TeamBillCycleService teamBillCycleService;
  private final TeamMemberTargetService teamMemberTargetService;

  public void execute(AppIdLongCmd cmd) {
    String key = "TeamPolicyPropsReward:" + cmd.getReqUserId();
    ResponseAssert.isTrue(CommonErrorCode.REQUEST_LIMITING, redisService.lock(key, 60 * 3));
    TeamMemberTarget target = teamMemberTargetService.getByTimeId(cmd.getId());
    ResponseAssert.notNull(TeamErrorCode.UNCLAIMABLE, target);
    ResponseAssert.notNull(TeamErrorCode.UNCLAIMABLE, target.getSettlementResult());
    ResponseAssert.notNull(TeamErrorCode.UNCLAIMABLE,
        target.getSettlementResult().getPropsRewards());
    ResponseAssert.isFalse(TeamErrorCode.UNCLAIMABLE,
        Objects.equals(target.getSettlementResult().getPropsReceived(), Boolean.TRUE));

    TeamBillCycle teamBillCycle = teamBillCycleService.getTeamBill(target.getTeamId(),
        target.getBillBelong());
    ResponseAssert.notNull(CommonErrorCode.RECEIVE_FAIL, teamBillCycle.getSettleResult());
    ResponseAssert.notNull(CommonErrorCode.RECEIVE_FAIL,
        teamBillCycle.getSettleResult().getPolicy());

    TeamBillMemberTarget billMemberTarget = TeamBillCycleUtils.calculatorPolicyTarget(target,
        teamBillCycle.getSettleResult().getPolicy());
    ResponseAssert.notNull(CommonErrorCode.RECEIVE_FAIL, billMemberTarget);
    ResponseAssert.isTrue(CommonErrorCode.RECEIVE_FAIL,
        CollectionUtils.isNotEmpty(billMemberTarget.getPropsRewards()));

    propsSendCommon.send(new PrizeDescribeRewardCmd()
        .setAcceptUserId(cmd.getReqUserId())
        .setOrigin(SendPropsOrigin.HOST_AGENT_SYSTEM_REWARD)
        .setSysOrigin(SysOriginPlatformEnum.valueOf(cmd.requireReqSysOrigin()))
        .setTrackId(teamBillCycle.getId())
        .setPrizes(billMemberTarget.getPropsRewards().stream()
            .map(product -> new PrizeDescribe()
                .setTrackId(teamBillCycle.getId())
                .setType(product.getType())
                .setDetailType(product.getDetailType())
                .setContent(product.getContent())
                .setQuantity(product.getQuantity())
                .setRemark(GoldOrigin.HOST_AGENT_SYSTEM_REWARD.getDesc())
            ).filter(Objects::nonNull).collect(Collectors.toList()))
    );

    teamMemberTargetService.updateTargetPropsReceivedTrue(target.getId());
    redisService.unlock(key);
  }
}
