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

import com.red.circle.external.inner.endpoint.message.OfficialNoticeClient;
import com.red.circle.external.inner.model.cmd.message.notice.official.NoticeExtTemplateTypeCmd;
import com.red.circle.external.inner.model.enums.message.OfficialNoticeTypeEnum;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.framework.core.response.ResponseErrorCode;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.cmd.team.DbInviteMessageProcessCmd;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.infra.database.mongo.entity.team.bd.BdInviteAgentMessage;
import com.red.circle.other.infra.database.mongo.entity.team.bd.MessageInviteGroup;
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamApplicationProcessApproval;
import com.red.circle.other.infra.database.mongo.service.team.bd.BdInviteAgentMessageService;
import com.red.circle.other.infra.database.mongo.service.team.team.TeamApplicationProcessApprovalService;
import com.red.circle.other.infra.database.rds.entity.team.BusinessDevelopmentBaseInfo;
import com.red.circle.other.infra.database.rds.entity.team.RoomBdLead;
import com.red.circle.other.infra.database.rds.service.team.BusinessDevelopmentBaseInfoService;
import com.red.circle.other.infra.database.rds.service.team.RoomBdLeadService;
import com.red.circle.other.infra.database.rds.service.team.UserHistoryIdentityService;
import com.red.circle.other.inner.asserts.user.UserErrorCode;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.other.inner.asserts.team.TeamErrorCode;
import com.red.circle.other.inner.enums.team.TeamAppProcessApprovalReason;
import com.red.circle.other.inner.enums.team.TeamApplicationType;
import com.red.circle.tool.core.collection.MapBuilder;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.json.JacksonUtils;
import com.red.circle.tool.core.text.StringUtils;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 处理bd leader邀请消息.
 *
 * @author pengshigang on 2023/4/10
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class BdLeaderInviteMessageProcessExe {

  private final RoomBdLeadService roomBdLeadService;
  private final UserProfileGateway userProfileGateway;
  private final OfficialNoticeClient officialNoticeClient;
  private final UserProfileAppConvertor userProfileAppConvertor;
  private final UserHistoryIdentityService userHistoryIdentityService;
  private final BdInviteAgentMessageService bdInviteAgentMessageService;
  private final BusinessDevelopmentBaseInfoService businessDevelopmentBaseInfoService;
  private final TeamApplicationProcessApprovalService teamApplicationProcessApprovalService;

  public void execute(DbInviteMessageProcessCmd cmd) {
    ResponseAssert.isTrue(ResponseErrorCode.REQUEST_PARAMETER_ERROR, cmd.getStatus() > 0);
    BdInviteAgentMessage message = bdInviteAgentMessageService.getById(cmd.getId());
    ResponseAssert.notNull(CommonErrorCode.NOT_FOUND_RECORD_INFO, message);

    ResponseAssert.isTrue(CommonErrorCode.NOT_FOUND_RECORD_INFO,
        Objects.equals(message.getGroup(), MessageInviteGroup.BD_LEADER_INVITE_BD.name()));

    ResponseAssert
        .isFalse(TeamErrorCode.USER_IS_BD,
            roomBdLeadService.checkBdLeader(cmd.requiredReqUserId()));

    ResponseAssert.isFalse(TeamErrorCode.USER_IS_BD,
        businessDevelopmentBaseInfoService.checkBD(cmd.requiredReqUserId()));

    ResponseAssert.isTrue(CommonErrorCode.INSUFFICIENT_PERMISSION,
        Objects.equals(message.getInviteUserId(), cmd.requiredReqUserId()));
    ResponseAssert.isTrue(TeamErrorCode.MESSAGE_PROCESSED, Objects.equals(message.getStatus(), 0));

    RoomBdLead roomBdLead = roomBdLeadService.getByUserId(message.getUserId());
    ResponseAssert.notNull(TeamErrorCode.USER_IS_NOT_BD, roomBdLead);

    ResponseAssert.isTrue(CommonErrorCode.OPERATING_FAILURE, bdInviteAgentMessageService.
        updateStatus(cmd.getId(), message.getStatus(), cmd.getStatus(),
            MessageInviteGroup.BD_LEADER_INVITE_BD.name()));

    if (Objects.equals(cmd.getStatus(), 1)) {

      // 创建BD
      businessDevelopmentBaseInfoService.add(new BusinessDevelopmentBaseInfo()
          .setSysOrigin(cmd.requireReqSysOrigin())
          .setBdLeadUserId(message.getUserId())
          .setUserId(cmd.requiredReqUserId())
          .setRegion(roomBdLead.getRegionId())
          .setContact(StringUtils.isBlank(cmd.getContact()) ? StringUtils.EMPTY : cmd.getContact())
      );

      teamApplicationProcessApprovalService.add(new TeamApplicationProcessApproval()
          .setSysOrigin(cmd.requireReqSysOrigin())
          .setType(TeamApplicationType.BD)
          .setReason(TeamAppProcessApprovalReason.ACCEPT_BD_INVITE)
          .setAssociateId(message.getUserId())
          .setBeProcessUserId(message.getInviteUserId())
          .setCreateTime(TimestampUtils.now())
          .setCreateUser(cmd.requiredReqUserId())
          .setCreateUserOrigin(0)
      );

      userHistoryIdentityService.saveBd(cmd.requiredReqUserId());
      sendMessage(message, OfficialNoticeTypeEnum.AGREE_BD_LEADER_INVITE_AGENT);
      return;
    }

    sendMessage(message, OfficialNoticeTypeEnum.REFUSE_BD_LEADER_INVITE_AGENT);
  }

  private void sendMessage(BdInviteAgentMessage message, OfficialNoticeTypeEnum noticeTypeEnum) {
    UserProfileDTO userProfile = userProfileAppConvertor.toUserProfileDTO(
        userProfileGateway.getByUserId(message.getInviteUserId())
    );
    ResponseAssert.notNull(UserErrorCode.USER_INFO_NOT_FOUND, userProfile);
    NoticeExtTemplateTypeCmd userProfile1 = NoticeExtTemplateTypeCmd.builder()
        .toAccount(message.getUserId())
        .noticeType(noticeTypeEnum)
        .templateParam(MapBuilder.builder()
            .put("userProfile", String.format("%s(%s)", userProfile.getUserNickname(),
                userProfile.actualAccount()))
            .build())
        .build();
    officialNoticeClient.send(NoticeExtTemplateTypeCmd.builder()
        .toAccount(message.getUserId())
        .noticeType(noticeTypeEnum)
        .templateParam(MapBuilder.builder()
            .put("userProfile", String.format("%s(%s)", userProfile.getUserNickname(),
                userProfile.actualAccount()))
            .build())
        .build());
  }

}
