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


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.other.app.dto.cmd.task.DailyTasksEventCmd;
import com.red.circle.other.infra.database.cache.service.other.EnumConfigCacheService;
import com.red.circle.other.infra.database.mongo.service.task.DailyTaskStorageService;
import com.red.circle.other.infra.enums.task.DailyTaskStorageStatus;
import com.red.circle.other.inner.enums.config.TaskRewardTypeEnum;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import com.red.circle.other.inner.asserts.user.UserErrorCode;
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.enums.GoldOrigin;
import java.math.BigDecimal;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * 领取奖励.
 *
 * @author pengliang on 2021/5/8
 */
@Component
@RequiredArgsConstructor
public class VoiceTaskReceiveTaskRewardsCmdExe {

  private final WalletGoldClient walletGoldClient;
  private final WalletDiamondClient walletDiamondClient;
  private final EnumConfigCacheService enumConfigCacheService;
  private final DailyTaskStorageService dailyTaskStorageService;

  public void execute(DailyTasksEventCmd cmd) {

    DailyTaskStorageStatus storageStatus = getTaskStatus(cmd);

    if (Objects.equals(storageStatus, DailyTaskStorageStatus.UNDONE)) {
      // 4016 当前任务未完成
      ResponseAssert.failure(UserErrorCode.INCOMPLETE_TASK);
      return;
    }

    if (Objects.equals(storageStatus, DailyTaskStorageStatus.RECEIVED)) {
      // 4017 已领取奖励
      ResponseAssert.failure(UserErrorCode.AWARD_RECEIVED);
      return;
    }

    sendReward(cmd);
    changeStatusReceived(cmd);
  }

  private void sendReward(DailyTasksEventCmd cmd) {
    if (Objects.equals(TaskRewardTypeEnum.GOLD.name(), cmd.getRewardTypeName())) {
      sendGoldReward(cmd);
      return;
    }
    sendDiamondReward(cmd);
  }

  private void sendGoldReward(DailyTasksEventCmd cmd) {
    walletGoldClient.changeBalance(GoldReceiptCmd.builder()
        .appIncome()
        .userId(cmd.requiredReqUserId())
        .eventId(IdWorkerUtils.getIdStr())
        .sysOrigin(cmd.requireReqSysOrigin())
        .origin(GoldOrigin.DAILY_TASK)
        .amount(getDiamondQuantity(cmd))
        .build());
  }

  private void sendDiamondReward(DailyTasksEventCmd cmd) {
    walletDiamondClient.changeBalanceAsync(
        new DiamondReceiptCmd()
            .setConsumeId(IdWorkerUtils.getIdStr())
            .setSysOrigin(SysOriginPlatformEnum.valueOf(cmd.getReqSysOrigin().getOrigin()))
            .setTrackId(IdWorkerUtils.getId())
            .setUserId(cmd.getReqUserId())
            .setOriginUserId(0L)
            .setOrigin(DiamondOrigin.DAILY_TASK)
            .setType(ReceiptType.INCOME)
            .setAmount(getDiamondQuantity(cmd))
            .setCreateTime(TimestampUtils.convert(cmd.getReqTime()))
    );
  }

  private void changeStatusReceived(DailyTasksEventCmd cmd) {
    dailyTaskStorageService.changeStatusReceived(cmd.getReqUserId(), cmd.getEventName());
  }

  private BigDecimal getDiamondQuantity(DailyTasksEventCmd cmd) {
    return enumConfigCacheService.getValueBigDecimal(cmd.getEvent(), cmd.requireReqSysOrigin());
  }

  private DailyTaskStorageStatus getTaskStatus(DailyTasksEventCmd cmd) {
    return dailyTaskStorageService
        .getTaskStatus(cmd.getReqUserId(), cmd.getEventName());
  }

}
