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

import com.alibaba.fastjson.JSON;
import com.red.circle.common.business.core.ReplaceString;
import com.red.circle.common.business.core.SensitiveWordFilter;
import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.component.core.i18n.I18nMessageUtils;
import com.red.circle.external.inner.endpoint.message.ImGroupClient;
import com.red.circle.external.inner.model.cmd.message.CreateGroupCmd;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.live.inner.endpoint.LiveMicClient;
import com.red.circle.mq.business.model.event.room.RoomVoiceCreateSuccessEvent;
import com.red.circle.mq.rocket.business.producer.RoomMqMessageService;
import com.red.circle.other.app.convertor.live.RoomProfileAppConvertor;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.clientobject.room.RoomVoiceProfileCO;
import com.red.circle.other.domain.gateway.props.PropsNobleVipGateway;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
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.entity.live.RoomCounter;
import com.red.circle.other.infra.database.mongo.entity.live.RoomProfileManager;
import com.red.circle.other.infra.database.mongo.entity.live.RoomSetting;
import com.red.circle.other.infra.database.mongo.service.live.RoomProfileManagerService;
import com.red.circle.other.infra.database.rds.entity.live.RoomMember;
import com.red.circle.other.infra.database.rds.entity.sys.SysCountryCode;
import com.red.circle.other.infra.database.rds.service.live.RoomMemberService;
import com.red.circle.other.infra.database.rds.service.sys.SysCountryCodeService;
import com.red.circle.other.inner.asserts.DynamicErrorCode;
import com.red.circle.other.inner.asserts.RoomErrorCode;
import com.red.circle.other.inner.asserts.user.UserErrorCode;
import com.red.circle.other.inner.enums.config.EnumConfigKey;
import com.red.circle.other.inner.enums.live.RoomUserRolesEnum;
import com.red.circle.other.inner.enums.room.RoomEventEnum;
import com.red.circle.other.inner.model.dto.material.props.PropsNobleVipAbilityDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import com.red.circle.tool.core.text.StringPool;
import com.red.circle.tool.core.text.StringUtils;
import java.util.Objects;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 房间语音创建.
 *
 * @author pengliang on 2021/02/20
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class LiveVoiceRoomCreateCmdExe {

  private final LiveMicClient liveMicClient;
  private final ImGroupClient imGroupClient;
  private final RoomMemberService roomMemberService;
  private final UserProfileGateway userProfileGateway;
  private final RoomMqMessageService roomMqMessageService;
  private final PropsNobleVipGateway propsNobleVipGateway;
  private final SysCountryCodeService sysCountryCodeService;
  private final UserProfileAppConvertor userProfileAppConvertor;
  private final RoomProfileAppConvertor roomProfileAppConvertor;
  private final RoomProfileManagerService roomProfileManagerService;
  private final EnumConfigCacheService enumConfigCacheService;

  public RoomVoiceProfileCO execute(AppExtCommand cmd) {
    // 房间已存在
    ResponseAssert.isFalse(RoomErrorCode.ROOM_EXISTS,
        roomProfileManagerService.existsUserRoom(cmd.requiredReqUserId()));

    return saveRoomProfileReturnResult(cmd);
  }

  private RoomVoiceProfileCO saveRoomProfileReturnResult(AppExtCommand cmd) {
    UserProfile userProfile = userProfileGateway.getByUserId(cmd.requiredReqUserId());

    return getRoomVoiceProfile(userProfile, createRoom(userProfile, cmd));
  }

  private RoomVoiceProfileCO getRoomVoiceProfile(UserProfile userProfile,
      RoomProfileManager roomProfile) {
    // 没有找到用户信息
    ResponseAssert.notNull(UserErrorCode.USER_INFO_NOT_FOUND, userProfile);
    SysCountryCode sysCountryCode = sysCountryCodeService.getByCode(roomProfile.getCountryCode());
    RoomVoiceProfileCO roomVoiceProfile = roomProfileAppConvertor.toRoomVoiceProfileCO(roomProfile);
    roomVoiceProfile.setCountryCode(roomProfile.getCountryCode());
    roomVoiceProfile.setCountryName(roomProfile.getCountryName());
    roomVoiceProfile.setNationalFlag(Objects.nonNull(sysCountryCode.getNationalFlag())?sysCountryCode.getNationalFlag():null);
    roomVoiceProfile.setUserProfile(userProfileAppConvertor.toUserProfileDTO(userProfile));
    roomVoiceProfile.putExistsPassword(Boolean.FALSE);
    roomVoiceProfile.putRoomMemberQuantity(1);
    roomVoiceProfile
        .putRoomDefaultSetting(
            roomProfileAppConvertor.toRoomSettingCO(RoomSetting.createDefaultRoomSetting()));
    return roomVoiceProfile;
  }

  private RoomProfileManager createRoom(UserProfile userProfile, AppExtCommand cmd) {

    if (SensitiveWordFilter.checkSensitiveWord(userProfile.getUserNickname())){
      ResponseAssert.isTrue(DynamicErrorCode.SENSITIVE_WORD_ERROR, false);
    }
    RoomProfileManager roomProfile = new RoomProfileManager();
    roomProfile.setId(IdWorkerUtils.getId());
    roomProfile.setRoomAccount(userProfile.getAccount());
    roomProfile.setUserId(userProfile.getId());
    roomProfile.setRoomCover(getRoomCover(userProfile));
    roomProfile.setRoomName("room" + userProfile.getAccount());
    roomProfile.setRoomDesc(I18nMessageUtils.get("ROOM_DESC.body"));
    roomProfile.setEvent(RoomEventEnum.WAITING_CONFIRMED.name());
    roomProfile.setSysOrigin(cmd.requireReqSysOrigin());
    roomProfile.setCountryCode(userProfile.getCountryCode());
    roomProfile.setCountryName(userProfile.getCountryName());
    roomProfile.setDel(Boolean.FALSE);
    roomProfile.setSetting(createRoomSetting(userProfile));
    roomProfile.setCustomizeSetting(CollectionUtils.newHashMap());
    roomProfile.setUseBadges(CollectionUtils.newArrayList());
    roomProfile.setCounter(new RoomCounter()
        .setAdminCount(0)
        .setMemberCount(1)
    );
    roomProfile.setCreateTime(TimestampUtils.now());
    roomProfile.setUpdateTime(TimestampUtils.now());
    roomProfileManagerService.create(roomProfile);

    // 添加房间角色
    roomMemberService.save(new RoomMember()
        .setRoomId(roomProfile.getId())
        .setUserId(roomProfile.getUserId())
        .setRoles(RoomUserRolesEnum.HOMEOWNER.name())
        .setSysOrigin(cmd.requireReqSysOrigin())
    );

    roomMqMessageService
        .createVoiceRoomSuccess(toRoomVoiceCreateSuccessEvent(roomProfile, cmd));

    // 创建麦克风记录
    liveMicClient.create(roomProfile.getId(), roomProfile.getSetting().getMikeSize());

    // 创建群聊
    Boolean isSuccess = imGroupClient.createAVChatRoomGroup(new CreateGroupCmd()
        .setOwnerAccount(Objects.toString(roomProfile.getUserId()))
        .setGroupId(roomProfile.getRoomAccount())
        .setFaceUrl(roomProfile.getRoomCover())
        .setName(roomProfile.getRoomName())
    ).getBody();

    if (!Objects.equals(isSuccess, Boolean.TRUE)) {
      log.warn("创建群聊失败: {}", roomProfile.getUserId());
    }
    return roomProfile;
  }

  private RoomSetting createRoomSetting(UserProfile userProfile) {
    RoomSetting settingV2 = RoomSetting.createDefaultRoomSetting();
    settingV2.setMaxAdmin(getVipMaxAdminMemberSize(userProfile.getId(), settingV2.getMaxAdmin()));
    return settingV2;
  }

  private Integer getVipMaxAdminMemberSize(Long userId, Integer defaultSize) {
    return Optional.ofNullable(
            propsNobleVipGateway.getUserMaxAbilityDTO(userId))
        .map(PropsNobleVipAbilityDTO::getAdminNumber)
        .orElse(defaultSize);
  }

  public RoomVoiceCreateSuccessEvent toRoomVoiceCreateSuccessEvent(RoomProfileManager roomProfile,
      AppExtCommand cmd) {
    RoomVoiceCreateSuccessEvent event = roomProfileAppConvertor
        .toRoomVoiceCreateSuccessEvent(roomProfile);
    event.setSysOrigin(cmd.requireReqSysOrigin());
    return event;
  }

  private String getRoomCover(UserProfile userProfile) {
      return enumConfigCacheService.getValue(EnumConfigKey.DEFAULT_ROOM_COVER, userProfile.getOriginSys());
  }
}
