package com.red.circle.other.app.listener.user;

import com.red.circle.component.mq.MessageEventProcess;
import com.red.circle.component.mq.MessageEventProcessDescribe;
import com.red.circle.component.mq.config.RocketMqMessageListener;
import com.red.circle.component.mq.service.Action;
import com.red.circle.component.mq.service.ConsumerMessage;
import com.red.circle.component.mq.service.MessageListener;
import com.red.circle.mq.business.model.event.user.CpApplyEvent;
import com.red.circle.mq.rocket.business.streams.CpApplySink;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.json.JacksonUtils;
import com.red.circle.other.infra.database.rds.entity.user.user.CpApply;
import com.red.circle.other.infra.database.rds.service.user.user.CpApplyService;
import com.red.circle.other.infra.enums.user.user.CpApplyStatus;
import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient;
import com.red.circle.wallet.inner.model.cmd.GoldReceiptCmd;
import com.red.circle.wallet.inner.model.enums.GoldOrigin;
import java.util.List;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * cp申请处理.
 *
 * @author pengliang on 2021/7/14
 */
@Slf4j
@RequiredArgsConstructor
@RocketMqMessageListener(topic = "${rocketmq.topics.RC_DEFAULT_APP_DELAYED}", groupId = CpApplySink.INPUT, tag = CpApplySink.TAG)
public class CpApplyListener implements MessageListener {

  private final CpApplyService cpApplyService;
  private final WalletGoldClient walletGoldClient;
  private final MessageEventProcess messageEventProcess;

  @Override
  public Action consume(ConsumerMessage message) {
    return messageEventProcess.consume(
        MessageEventProcessDescribe.builder()
            .logTag("CP")
            .repeatConsumeTag("CpApply")
            .checkConsumeTag(CpApplySink.TAG)
            .message(message)
            .build(),
        CpApplyEvent.class,
        eventBody -> {

          CpApply cpApply = cpApplyService.getById(eventBody.getId());
          if (Objects.isNull(cpApply)) {
            log.warn("[CP]CpApplyListener.cpApply param error:{}", JacksonUtils.toJson(eventBody));
            return;
          }

          // 同意检测那些被拒绝都
          if (Objects.equals(cpApply.getStatus(), CpApplyStatus.AGREE.name())) {
            checkReimburse(eventBody, cpApply);
            return;
          }

          // 等待超时
          if (Objects.equals(cpApply.getStatus(), CpApplyStatus.WAIT.name())) {
            reimburse(eventBody, cpApply);
          }
        });
  }

  private void checkReimburse(CpApplyEvent param, CpApply cpApply) {
    List<CpApply> cpApplies = cpApplyService.listRefuse(cpApply.getAcceptApplyUserId());
    if (CollectionUtils.isEmpty(cpApplies)) {
      return;
    }
    cpApplies.forEach(apply -> reimburse(param, apply));
  }

  private void reimburse(CpApplyEvent param, CpApply cpApply) {
    walletGoldClient.changeBalance(GoldReceiptCmd.builder()
        .appIncome()
        .userId(cpApply.getSendApplyUserId())
        .eventId(cpApply.getId())
        .sysOrigin(param.getSysOrigin())
        .origin(GoldOrigin.CP_BUILD)
        .amount(cpApply.getApplyConsumeGold())
        .build());
    cpApplyService.changeStatusById(cpApply.getId(), CpApplyStatus.REIMBURSE);
  }

}
