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

import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
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.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.cmd.team.DbLeaderInviteBdCmd;
import com.red.circle.other.app.util.OfficialNoticeUtils;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.infra.database.cache.service.other.EnumConfigCacheService;
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.service.team.bd.BdInviteAgentMessageService;
import com.red.circle.other.infra.database.rds.entity.team.BusinessDevelopmentBaseInfo;
import com.red.circle.other.infra.database.rds.service.sys.AdministratorService;
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.inner.asserts.user.UserErrorCode;
import com.red.circle.other.inner.enums.config.EnumConfigKey;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.other.inner.asserts.team.TeamErrorCode;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.json.JacksonUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import com.red.circle.tool.core.text.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 验证是否可以发出BD邀请
 *
 * @author pengshigang on 2023/4/10
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class BdLeaderInviteBdExe {

  private final RoomBdLeadService roomBdLeadService;
  private final UserProfileGateway userProfileGateway;
  private final OfficialNoticeClient officialNoticeClient;
  private final UserProfileAppConvertor userProfileAppConvertor;
  private final BdInviteAgentMessageService bdInviteAgentMessageService;
  private final BusinessDevelopmentBaseInfoService businessDevelopmentBaseInfoService;
  private final AdministratorService administratorService;

  public void execute(DbLeaderInviteBdCmd cmd) {

    // 权限不足
    ResponseAssert.isTrue(CommonErrorCode.INSUFFICIENT_PERMISSION,
        roomBdLeadService.checkBdLeader(cmd.requiredReqUserId()));

    // 权限不足
    ResponseAssert.isFalse(TeamErrorCode.USER_IS_ALREADY_A_BDLEADER,
        roomBdLeadService.checkBdLeader(cmd.getInviteUserId()));

    ResponseAssert.isFalse(TeamErrorCode.USER_IS_ALREADY_A_BD,
            businessDevelopmentBaseInfoService.checkBD(cmd.getInviteUserId()));

      ResponseAssert.isFalse(TeamErrorCode.USER_IS_A_ADMIN,
              administratorService.existsAdmin(cmd.getInviteUserId()));


      // 权限不足
    BusinessDevelopmentBaseInfo bd = getDevelopmentBaseInfoServiceByUserId(cmd);
    ResponseAssert.isFalse(CommonErrorCode.INSUFFICIENT_PERMISSION, Objects.nonNull(bd)
        && Objects.nonNull(bd.getBdLeadUserId()));

    // 消息已发送
    ResponseAssert.isFalse(TeamErrorCode.MESSAGE_PROCESSED,
        bdInviteAgentMessageService.existsWaitMessage(cmd.requiredReqUserId(),
            cmd.getInviteUserId(), MessageInviteGroup.BD_LEADER_INVITE_BD.name()));

    String messageId = IdWorkerUtils.getIdStr();
    bdInviteAgentMessageService.add(new BdInviteAgentMessage()
        .setId(messageId)
        .setSysOrigin(cmd.requireReqSysOrigin())
        .setUserId(cmd.requiredReqUserId())
        .setInviteUserId(cmd.getInviteUserId())
        .setMessage(cmd.getMessage())
        .setGroup(MessageInviteGroup.BD_LEADER_INVITE_BD.name())
        .setCreateTime(TimestampUtils.now())
        .setUpdateTime(TimestampUtils.now())
        .setStatus(0)
        .setExpiredTime(TimestampUtils.nowPlusDays(2))
    );

    UserProfileDTO userProfile = userProfileAppConvertor.toUserProfileDTO(
        userProfileGateway.getByUserId(cmd.requiredReqUserId())
    );

    officialNoticeClient.send(NoticeExtTemplateTypeCmd.builder()
        .toAccount(cmd.getInviteUserId())
        .noticeType(OfficialNoticeTypeEnum.BD_LEADER_INVITE_BD)
        .templateParam(OfficialNoticeUtils.buildUserProfile(userProfile))
        .expand(messageId)
        .build()
    );

  }

  public void executeBdleader(DbLeaderInviteBdCmd cmd) {

    // 权限不足
    ResponseAssert.isTrue(CommonErrorCode.INSUFFICIENT_PERMISSION,
        roomBdLeadService.checkBdLeader(cmd.requiredReqUserId()));

    // 权限不足
    ResponseAssert.isFalse(TeamErrorCode.USER_IS_ALREADY_A_BDLEADER,
        roomBdLeadService.checkBdLeader(cmd.getInviteUserId()));

      ResponseAssert.isFalse(TeamErrorCode.USER_IS_A_ADMIN,
              administratorService.existsAdmin(cmd.getInviteUserId()));


    List<Long> bdUserIds = businessDevelopmentBaseInfoService.listBdUserIdsByLeaderId(cmd.requiredReqUserId());
    ResponseAssert.isFalse(CommonErrorCode.INSUFFICIENT_PERMISSION, bdUserIds.contains(cmd.getInviteUserId()));

      // 消息已发送
    ResponseAssert.isFalse(TeamErrorCode.MESSAGE_PROCESSED,
        bdInviteAgentMessageService.existsWaitMessage(cmd.requiredReqUserId(),
            cmd.getInviteUserId(), MessageInviteGroup.BD_LEADER_INVITE_BD_LEADER.name()));

    String messageId = IdWorkerUtils.getIdStr();
    bdInviteAgentMessageService.add(new BdInviteAgentMessage()
        .setId(messageId)
        .setSysOrigin(cmd.requireReqSysOrigin())
        .setUserId(cmd.requiredReqUserId())
        .setInviteUserId(cmd.getInviteUserId())
        .setMessage(cmd.getMessage())
        .setGroup(MessageInviteGroup.BD_LEADER_INVITE_BD_LEADER.name())
        .setCreateTime(TimestampUtils.now())
        .setUpdateTime(TimestampUtils.now())
        .setStatus(0)
        .setExpiredTime(TimestampUtils.nowPlusDays(2))
    );

    UserProfileDTO userProfile = userProfileAppConvertor.toUserProfileDTO(
        userProfileGateway.getByUserId(cmd.requiredReqUserId())
    );

    officialNoticeClient.send(NoticeExtTemplateTypeCmd.builder()
        .toAccount(cmd.getInviteUserId())
        .noticeType(OfficialNoticeTypeEnum.BD_LEADER_INVITE_BD_LEADER)
        .templateParam(OfficialNoticeUtils.buildUserProfile(userProfile))
        .expand(messageId)
        .build()
    );

  }

  private BusinessDevelopmentBaseInfo getDevelopmentBaseInfoServiceByUserId(
      DbLeaderInviteBdCmd cmd) {
    return businessDevelopmentBaseInfoService.getByUserId(cmd.getInviteUserId());
  }

}
