package com.red.circle.other.app.service.user.approve;

import com.red.circle.common.business.core.AppBusinessUtils;
import com.red.circle.common.business.core.enums.ApprovalStatusEnum;
import com.red.circle.common.business.core.enums.DataApprovalTypeEnum;
import com.red.circle.common.business.core.enums.OpUserType;
import com.red.circle.component.mq.MessageEvent;
import com.red.circle.component.mq.service.SenderService;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.mq.business.model.event.approval.ApprovalContentEvent;
import com.red.circle.mq.business.model.event.approval.ApprovalDynamicEvent;
import com.red.circle.mq.rocket.business.streams.ConsoleApprovalSink;
import com.red.circle.other.app.command.room.LiveVoicePublicRoomCreateCmdExe;
import com.red.circle.other.app.command.room.LiveVoiceRoomCreateCmdExe;
import com.red.circle.other.app.command.room.RoomEnterCmdExe;
import com.red.circle.other.app.command.room.query.*;
import com.red.circle.other.app.command.user.query.UserProfileUseSearchQryExe;
import com.red.circle.other.app.command.user.query.UserVoiceRoomAuthCheckQryExe;
import com.red.circle.other.app.common.room.RoomVoiceProfileCommon;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.clientobject.room.RoomVoiceProfileCO;
import com.red.circle.other.app.dto.cmd.room.RoomEntryCmd;
import com.red.circle.other.app.dto.cmd.room.SearchRoomAccountCmd;
import com.red.circle.other.app.dto.cmd.user.approve.AccountApproveCmd;
import com.red.circle.other.app.dto.cmd.user.user.AccountQryCmd;
import com.red.circle.other.app.service.room.LiveVoiceRoomService;
import com.red.circle.other.app.service.user.user.UserProfileService;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.gateway.user.UserRunProfileTransportGateway;
import com.red.circle.other.domain.gateway.user.ability.UserRegionGateway;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.infra.database.cache.service.other.EnumConfigCacheService;
import com.red.circle.other.infra.database.mongo.service.user.profile.UserSpecialIdService;
import com.red.circle.other.infra.database.rds.entity.approval.ApprovalUserSettingData;
import com.red.circle.other.infra.database.rds.service.approval.ApprovalUserSettingDataService;
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.model.dto.user.approve.UserProfileApproveDTO;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 用户资料审核服务 实现.
 *
 * @author pengliang on 2023/9/20
 */
@Service
@RequiredArgsConstructor
public class UserProfileApproveServiceImpl implements UserProfileApproveService {

  private static final Logger log = LoggerFactory.getLogger(UserProfileApproveServiceImpl.class);
  private final SenderService senderService;
  private final UserRegionGateway userRegionGateway;
  private final UserProfileService userProfileService;
  private final UserProfileGateway userProfileGateway;
  private final RoomVoiceProfileCommon roomVoiceProfileCommon;
  private final UserProfileAppConvertor userProfileAppConvertor;
  private final ApprovalUserSettingDataService approvalUserSettingDataService;
  private final EnumConfigCacheService enumConfigCacheService;


  @Override
  public UserProfileApproveDTO search(AccountQryCmd cmd) {


    UserProfileDTO userProfileDTO = userProfileService.getUserProfile(cmd);

    if (Objects.isNull(userProfileDTO)) {
      ResponseAssert.failure(UserErrorCode.USER_INFO_NOT_FOUND);
    }

    RoomVoiceProfileCO roomVoiceProfile = Optional.ofNullable(roomVoiceProfileCommon.getAvailableByRoomAccount(cmd.requireReqSysOriginEnum(), cmd.getAccount()))
            .filter(profile -> Objects.equals(profile.getSysOrigin(), cmd.requireReqSysOrigin()))
            .orElse(null);
    List<ApprovalUserSettingData> approvalUserSettingData = approvalUserSettingDataService.getListByUserId(userProfileDTO.getId());
    if (Objects.isNull(approvalUserSettingData)) {
      ResponseAssert.failure(UserErrorCode.USER_INFO_NOT_FOUND);
    }
    UserProfileApproveDTO.UserAvatarInfo userAvatarInfo = new UserProfileApproveDTO.UserAvatarInfo();
    userAvatarInfo.setAvatar(userProfileDTO.getUserAvatar());
    userAvatarInfo.setStatus(Objects.requireNonNull(approvalUserSettingData.stream().filter(item -> item.getApproveType().equals(DataApprovalTypeEnum.AVATAR.name())).findFirst().orElse(new ApprovalUserSettingData())).getApproveStatus());
    UserProfileApproveDTO.UserNicknameInfo userNicknameInfo = new UserProfileApproveDTO.UserNicknameInfo();
    userNicknameInfo.setNickname(userProfileDTO.getUserNickname());
    userNicknameInfo.setStatus(Objects.requireNonNull(approvalUserSettingData.stream().filter(item -> item.getApproveType().equals(DataApprovalTypeEnum.NICKNAME.name())).findFirst().orElse(new ApprovalUserSettingData())).getApproveStatus());
    UserProfileApproveDTO.RoomAvatarInfo rmAvatarInfo = new UserProfileApproveDTO.RoomAvatarInfo();
    UserProfileApproveDTO.RoomNicknameInfo rmNicknameInfo = new UserProfileApproveDTO.RoomNicknameInfo();
    if (Objects.nonNull(roomVoiceProfile)) {
      rmAvatarInfo.setAvatar(roomVoiceProfile.getRoomCover());
      rmAvatarInfo.setStatus(Objects.requireNonNull(approvalUserSettingData.stream().filter(item -> item.getApproveType().equals(DataApprovalTypeEnum.ROOM_AVATAR.name())).findFirst().orElse(new ApprovalUserSettingData())).getApproveStatus());
      rmNicknameInfo.setNickname(roomVoiceProfile.getRoomName());
      rmNicknameInfo.setStatus(Objects.requireNonNull(approvalUserSettingData.stream().filter(item -> item.getApproveType().equals(DataApprovalTypeEnum.ROOM_NICKNAME.name())).findFirst().orElse(new ApprovalUserSettingData())).getApproveStatus());
    }

    UserProfileApproveDTO userProfileApproveDTO = new UserProfileApproveDTO();
    userProfileApproveDTO.setAccount(cmd.getAccount());
    userProfileApproveDTO.setUserAvatarInfo(userAvatarInfo);
    userProfileApproveDTO.setUserNicknameInfo(userNicknameInfo);
    userProfileApproveDTO.setRoomAvatarInfo(rmAvatarInfo);
    userProfileApproveDTO.setRoomNicknameInfo(rmNicknameInfo);

    return userProfileApproveDTO;
  }

  @Override
  public void approve(AccountApproveCmd cmd) {
    UserProfileDTO userProfileDTO = this.executeUserProfile(cmd);

    if (Objects.isNull(userProfileDTO)) {
      ResponseAssert.failure(UserErrorCode.USER_INFO_NOT_FOUND);
    }
    String reviewUserWhitelist = enumConfigCacheService.getValue(EnumConfigKey.REVIEW_USER_WHITELIST, cmd.getReqSysOrigin().getOrigin());
    List<String> whiteIds = Arrays.asList(reviewUserWhitelist.split(","));
    UserProfile userProfile = userProfileGateway.getByUserId(cmd.getReqUserId());

    if (Objects.isNull(userProfile)) {
      log.error("请求用户不存在{}", cmd.getReqUserId());
      return;
    }
    if (!whiteIds.contains(userProfile.getAccount())) {
      log.error("请求用户不在白名单{}", cmd.getReqUserId());
      return;
    }
    if(ApprovalStatusEnum.getApprovalVal(cmd.getStatus()) == null) {
      return;
    }

    approvalUserSettingDataService.updateApprovalStatus(userProfileDTO.getId(), DataApprovalTypeEnum.getApprovalVal(cmd.getApproveType()), ApprovalStatusEnum.getApprovalVal(cmd.getStatus()), cmd.getReqUserId());
    senderService.sendEventMessage(MessageEvent.builder()
            .consumeId(IdWorkerUtils.getIdStr())
            .tag(ConsoleApprovalSink.TAG)
            .body(new ApprovalDynamicEvent()
                    .setOpsUserId(cmd.getReqUserId())
                    .setOpUserType(OpUserType.APP)
                    .setApprovalType(DataApprovalTypeEnum.valueOf(cmd.getApproveType()))
                    .setOriginType(Boolean.FALSE)
                    .setApprovalId(IdWorkerUtils.getId())
                    .setApprovalUserId(cmd.getReqUserId())
                    .setApprovalStatus(ApprovalStatusEnum.getApprovalVal(cmd.getStatus()))
                    .setWaitApprovalUser(Collections.singletonList(new ApprovalContentEvent()
                            .setContent(userProfileDTO.getUserAvatar())
                            .setContentId(userProfileDTO.getId())
                            .setUserId(userProfileDTO.getId())
                            .setTags("Pass,label=Normal,score=0")))).build());
  }

  public UserProfileDTO executeUserProfile(AccountApproveCmd cmd) {
    UserProfile userProfile = userProfileGateway.getByAccount(cmd.requireReqSysOrigin(),
            cmd.getAccount());
    ResponseAssert.notNull(UserErrorCode.USER_INFO_NOT_FOUND, userProfile);

    if (!AppBusinessUtils.eqSysOrigin(cmd.requireReqSysOrigin())
            || Objects.equals(userProfile.getDel(), Boolean.TRUE)) {
      return null;
    }

    UserProfileDTO userProfileDTO = userProfileAppConvertor.toUserProfileDTO(userProfile);
    if (userRegionGateway.checkBusinessRegion(cmd.getReqUserId(), userProfileDTO.getId())) {
      return userProfileDTO;
    }
    return null;
  }

}
