package com.red.circle.wallet.app.command.diamond;

import com.red.circle.common.business.core.enums.OpUserType;
import com.red.circle.common.business.core.enums.ReceiptType;
import com.red.circle.common.business.enums.DiamondOrigin;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import com.red.circle.tool.core.tuple.PennyAmount;
import com.red.circle.wallet.app.common.DiamondRegionCommon;
import com.red.circle.wallet.app.dto.clientobject.DiamondConfigCO;
import com.red.circle.wallet.app.dto.cmd.DiamondExchangeGoldCmd;
import com.red.circle.wallet.domain.gateway.WalletDiamondGateway;
import com.red.circle.wallet.domain.gateway.WalletGoldGateway;
import com.red.circle.wallet.domain.wallet.DiamondReceipt;
import com.red.circle.wallet.domain.wallet.WalletReceipt;
import com.red.circle.wallet.domain.wallet.WalletReceiptHistory;
import com.red.circle.wallet.inner.error.WalletErrorCode;
import com.red.circle.wallet.inner.model.enums.GoldOrigin;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 钻石兑换金币.
 *
 * @author pengshigang on 2023/7/21
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class DiamondExchangeGoldGoldCmdExe {

  private final WalletGoldGateway walletGoldGateway;
  private final DiamondRegionCommon diamondRegionCommon;
  private final WalletDiamondGateway walletDiamondGateway;

  public BigDecimal execute(DiamondExchangeGoldCmd cmd) {
    DiamondConfigCO diamondConfig = diamondRegionCommon.getDiamondRegionConfig(
        cmd.requiredReqUserId());

    ResponseAssert.notNull(CommonErrorCode.REGION_NOT_SUPPORTED_ERROR, diamondConfig);

    ResponseAssert.isTrue(CommonErrorCode.REGION_NOT_SUPPORTED_ERROR,
        Objects.nonNull(diamondConfig.getDiamondEqGold())
            && diamondConfig.getDiamondEqGold().compareTo(BigDecimal.ZERO) > 0);

    ResponseAssert.isTrue(CommonErrorCode.REGION_NOT_SUPPORTED_ERROR,
        Objects.nonNull(diamondConfig.getMinExchangeDiamond())
            && diamondConfig.getMinExchangeDiamond() > 0);

    // 获得金币数量
    BigDecimal gold = cmd.getExchangeQuantity().multiply(diamondConfig.getDiamondEqGold())
        .setScale(0, RoundingMode.DOWN);
    ResponseAssert.isTrue(WalletErrorCode.INSUFFICIENT_BALANCE,
        gold.compareTo(BigDecimal.ZERO) > 0);
    Long waterId = IdWorkerUtils.getId();
    WalletReceiptHistory receipt = walletDiamondGateway.changeBalance(
        new DiamondReceipt()
            .setConsumeId(Objects.toString(waterId))
            .setTrackId(waterId)
            .setUserId(cmd.requiredReqUserId())
            .setSysOrigin(cmd.requireReqSysOriginEnum())
            .setOriginUserId(cmd.requiredReqUserId())
            .setOrigin(DiamondOrigin.DIAMOND_EXCHANGE_GOLD.name())
            .setOriginDesc(DiamondOrigin.DIAMOND_EXCHANGE_GOLD.getDesc())
            .setAmount(cmd.getExchangeQuantity())
            .setType(ReceiptType.EXPENDITURE)
            .setCreateTime(TimestampUtils.now())
    );

    // 将兑换的金币插入用户金币钱包
    changeGoldBalance(cmd, gold);

    return receipt.getBalance();
  }

  private void changeGoldBalance(DiamondExchangeGoldCmd cmd, BigDecimal gold) {
    WalletReceipt walletReceipt = new WalletReceipt()
        .setReqTraceId(cmd.getReqTraceId())
        .setReceiptType(ReceiptType.INCOME)
        .setUserId(cmd.requiredReqUserId())
        .setSysOrigin(cmd.requireReqSysOrigin())
        .setEventType(Objects.toString(GoldOrigin.DIAMOND_EXCHANGE_GOLD))
        .setEventDesc(GoldOrigin.DIAMOND_EXCHANGE_GOLD.getDesc())
        .setEventId(Objects.toString(cmd.requiredReqUserId()))
        .setAmount(PennyAmount.ofDollar(gold))
        .setOpUserType(OpUserType.APP)
        .setCreateTime(cmd.reqTimeElseNow());
    walletGoldGateway.changeBalance(walletReceipt);
  }


}
