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.external.inner.endpoint.message.ImMessageClient;
import com.red.circle.mq.business.model.event.user.CpApplyEvent;
import com.red.circle.mq.rocket.business.streams.CpApplySink;
import com.red.circle.other.app.common.cp.CpRelationC2cNoticeUtils;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.model.user.UserProfile;
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 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 ImMessageClient imMessageClient;
  private final UserProfileGateway userProfileGateway;
  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.WAIT.name())) {
            expire(cpApply);
          } else {
            log.info("[CP] skip expire cp apply, applyId={}, status={}", cpApply.getId(),
                cpApply.getStatus());
          }
        });
  }

  private void expire(CpApply cpApply) {
    boolean changed = cpApplyService.expireWaitById(cpApply.getId());
    if (changed) {
      sendExpiredNotice(cpApply);
    }
  }

  private void sendExpiredNotice(CpApply cpApply) {
    try {
      UserProfile senderProfile = userProfileGateway.getByUserId(cpApply.getSendApplyUserId());
      UserProfile acceptProfile = userProfileGateway.getByUserId(cpApply.getAcceptApplyUserId());
      if (Objects.isNull(senderProfile) || Objects.isNull(acceptProfile)) {
        log.info("[CP] skip expired c2c notice, applyId={}, senderProfile={}, acceptProfile={}",
            cpApply.getId(), Objects.nonNull(senderProfile), Objects.nonNull(acceptProfile));
        return;
      }
      imMessageClient.sendCustomMessage(
          CpRelationC2cNoticeUtils.buildExpiredToAcceptUser(cpApply, senderProfile, acceptProfile));
    } catch (Exception ex) {
      log.warn("[CP] send expired c2c notice failed, applyId={}, reason={}", cpApply.getId(),
          ex.getMessage(), ex);
    }
  }

}
