package com.red.circle.other.app.listener.gift.strategy;

import com.alibaba.fastjson.JSON;
import com.red.circle.common.business.core.enums.ReceiptType;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.common.business.enums.DiamondOrigin;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.mq.business.model.event.gift.OfflineProcessGiftEvent;
import com.red.circle.other.domain.gateway.user.ability.UserRegionGateway;
import com.red.circle.other.domain.model.user.ability.RegionConfig;
import com.red.circle.other.infra.database.mongo.entity.gift.GiftAcceptUser;
import com.red.circle.other.infra.database.mongo.entity.gift.GiftGiveRunningWater;
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamMember;
import com.red.circle.other.infra.database.mongo.service.gift.GiftGiveRunningWaterService;
import com.red.circle.other.infra.database.mongo.service.team.team.TeamMemberService;
import com.red.circle.other.infra.database.rds.service.gift.GiftWallService;
import com.red.circle.other.inner.endpoint.sys.EnumConfigClient;
import com.red.circle.other.inner.enums.material.GiftCurrencyType;
import com.red.circle.other.inner.enums.material.GiftTabEnum;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.num.ArithmeticUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import com.red.circle.wallet.inner.endpoint.diamond.SalaryDiamondBalanceClient;
import com.red.circle.wallet.inner.endpoint.diamond.SalaryDiamondRunningWaterClient;
import com.red.circle.wallet.inner.endpoint.wallet.WalletDiamondClient;
import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient;
import com.red.circle.wallet.inner.model.cmd.DiamondReceiptCmd;
import com.red.circle.wallet.inner.model.cmd.GoldReceiptCmd;
import com.red.circle.wallet.inner.model.cmd.UserSalaryDiamondCmd;
import com.red.circle.wallet.inner.model.dto.UserSalaryDiamondRunningWaterDTO;
import com.red.circle.wallet.inner.model.enums.GoldOrigin;

import java.math.BigDecimal;
import java.util.Objects;

import com.red.circle.wallet.inner.model.enums.UserBankWaterEvent;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * 接收奖品策略.
 *
 * @author pengliang on 2022/7/26
 */
@Slf4j
@Service("GIFT_PRIZE_ACCEPT_EVENT_LISTENER")
@RequiredArgsConstructor
public class GiftPrizeAcceptStrategy implements GiftStrategy {

  private final GiftWallService giftWallService;
  private final WalletGoldClient walletGoldClient;
  private final WalletDiamondClient walletDiamondClient;
  private final GiftGiveRunningWaterService giftGiveRunningWaterService;


  private final SalaryDiamondBalanceClient salaryDiamondBalanceClient;
  private final SalaryDiamondRunningWaterClient salaryDiamondRunningWaterClient;
  private final UserRegionGateway userRegionGateway;
  private final TeamMemberService teamMemberService;
  private final EnumConfigClient enumConfigClient;

  @Override
  public void processor(OfflineProcessGiftEvent event) {
    log.warn("【接收礼物奖品】入参---{}", JSON.toJSONString(event));
    GiftGiveRunningWater runningWater = giftGiveRunningWaterService.getByIdPrimary(
        event.getRunningWaterId());

    if (Objects.isNull(runningWater)) {
      log.warn("【接收礼物奖品】没有找到流水信息，忽律处理");
      return;
    }

//    giftGiveRunningWaterService.addLog(runningWater.getId(), "开始：接收奖品策略");

    runningWater.getAcceptUsers().forEach(accept -> {

      // 记录礼物墙
      giftWallService.incrGiftWall(accept.getAcceptUserId(),
          runningWater.getGiftId(),
          (long) runningWater.getGiftValue().getQuantity());

      if (ArithmeticUtils.lteZero(accept.getAcceptAmount())) {
        return;
      }

      // 当前礼物是否为幸运礼物
        boolean isLuckyGift = runningWater.getGiftValue().getGiftType()
          .contains(GiftTabEnum.LUCKY_GIFT.name());
        boolean isMagicGift = runningWater.getGiftValue().getGiftType()
              .contains(GiftTabEnum.MAGIC.name());
        // 发送金币
        if (GiftCurrencyType.GOLD.eq(runningWater.getGiftValue().getCurrencyType())
                && !isLuckyGift
                && !isMagicGift) {

          Long consumeId = walletGoldClient.changeBalance(GoldReceiptCmd.builder()
              .appIncome()
              .eventId(event.getTrackId())
              .userId(accept.getAcceptUserId())
              .sysOrigin(runningWater.getSysOrigin())
              .origin(
                  GoldOrigin.ACCEPT_GIFT + "_" + runningWater.getGiftValue().getGiftType())
              .originDescribe("[" + runningWater.getGiftValue().getGiftType() + "]"
                  + GoldOrigin.ACCEPT_GIFT.getDesc())
              .closeDelayAsset()
              .amount(accept.getAcceptAmount())
              .build()).getBody().getAssetRecordId();

          giftGiveRunningWaterService.updateAcceptUserReceiptId(runningWater.getId(),
              accept.getAcceptUserId(), consumeId);
        }
    });

//    giftGiveRunningWaterService.addLog(runningWater.getId(),"结束：接收奖品策略(礼物墙、积分/钻石发放)");
  }

  /**
   * yolo钻石工资统计
   *
   * @param runningWater
   * @param acceptUsers
   */
  private void yoloSalaryDiamondCount(GiftGiveRunningWater runningWater, GiftAcceptUser acceptUsers) {
    log.warn("yolo钻石入账1:{}\n{}", runningWater, acceptUsers);
    if (!Objects.equals(runningWater.getSysOrigin(), SysOriginPlatformEnum.YOLO.name())) {
      // 如果不是YOLO就停止入账
      return;
    }
    if (acceptUsers.getAcceptAmount().compareTo(BigDecimal.ZERO) <= 0) {
      log.warn("小于0不入账:{}", acceptUsers.getAcceptAmount());
      return;
    }
    /*if (Objects.equals(salaryDiamondRunningWaterClient.existsTrackId(acceptUsers.getAcceptUserId(), UserBankWaterEvent.ACCEPT_GIFTS.name(), runningWater.getId().toString()).getBody(),
            Boolean.TRUE)) {
      log.warn("重复处理:{}", runningWater.getId());
      return;
    }*/
//    RegionConfig sendRegion = getUserRegion(acceptAnchorUser.getAcceptUserId());
//    BigDecimal ratio = getAssistGiftToOtherGoldRatio(sendRegion.getId());
//
//    log.warn("yolo钻石入账2:{}\n{}", sendRegion, ratio);

    /*BigDecimal quantity = runningWater.getGiftValue().getUnitPrice()
            .multiply(new BigDecimal(runningWater.getGiftValue().getQuantity()))
            .multiply(acceptUsers.getPercentage()).setScale(0, RoundingMode.DOWN);*/

    salaryDiamondBalanceClient.changeSalaryBalanceAsync(new UserSalaryDiamondCmd()
            .setUserId(acceptUsers.getAcceptUserId())
            .setQuantity(acceptUsers.getAcceptAmount())
            .setSysOrigin(runningWater.getSysOrigin()));

    TeamMember sendMember = teamMemberService.getByMemberId(acceptUsers.getAcceptUserId());
    Long teamId = 0L;
    if (Objects.nonNull(sendMember)) {
      teamId = sendMember.getTeamId();
    }
    salaryDiamondRunningWaterClient.addAsync(new UserSalaryDiamondRunningWaterDTO()
            .setId(IdWorkerUtils.getId())
            .setUserId(acceptUsers.getAcceptUserId())
            .setTeamId(teamId)
            .setSysOrigin(runningWater.getSysOrigin())
            .setType(ReceiptType.INCOME.getType())
            .setTrackId(runningWater.getId()+"")
            .setAmount(acceptUsers.getAcceptAmount())
            .setSalaryEvent(UserBankWaterEvent.ACCEPT_GIFTS.name())
            .setEventDesc(UserBankWaterEvent.ACCEPT_GIFTS.getDescribe())
            .setRemark(UserBankWaterEvent.ACCEPT_GIFTS.getDescribe())
            .setBalance(
                    ResponseAssert.requiredSuccess(
                            salaryDiamondBalanceClient.getBalance(acceptUsers.getAcceptUserId())).getBalance())
            .setCreateTime(TimestampUtils.now())
            .setCreateUser(0L)
            .setCreateUserOrigin(0)
    );
  }

  private RegionConfig getUserRegion(Long userId) {
    return userRegionGateway.getRegionConfigByUserId(userId);
  }

  /**
   * 赠送礼物给别人返还金币比例.
   */
  private BigDecimal getAssistGiftToOtherGoldRatio(String regionId) {
    return userRegionGateway.getAssistGiftToOtherGoldRatio(regionId);
  }

  /**
   * 赠送礼物给别人返还金币比例.
   */
  private BigDecimal getAssistGiftToOwnGoldRatio(String regionId) {
    return userRegionGateway.getAssistGiftToOwnGoldRatio(regionId);
  }
}
