package com.red.circle.other.app.common.live;

import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.live.inner.endpoint.LiveMicClient;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.gateway.user.ability.UserRegionGateway;
import com.red.circle.other.domain.gateway.user.ability.UserSVipGateway;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.infra.common.family.FamilyCommon;
import com.red.circle.other.infra.database.cache.service.other.HotRoomCacheService;
import com.red.circle.other.infra.database.cache.service.other.RoomManagerCacheService;
import com.red.circle.other.infra.database.mongo.entity.live.ActiveVoiceRoom;
import com.red.circle.other.infra.database.mongo.entity.live.RoomProfile;
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.entity.live.RoomTopFixed;
import com.red.circle.other.infra.database.mongo.entity.live.assist.FamilyProfile;
import com.red.circle.other.infra.database.mongo.service.live.ActiveVoiceRoomService;
import com.red.circle.other.infra.database.mongo.service.live.RoomProfileManagerService;
import com.red.circle.other.infra.database.mongo.service.live.RoomTopFixedService;
import com.red.circle.other.infra.database.mongo.service.user.status.OnlineUserService;
import com.red.circle.other.infra.database.rds.entity.family.FamilyMemberInfo;
import com.red.circle.other.infra.database.rds.service.family.FamilyMemberInfoService;
import com.red.circle.other.inner.asserts.user.UserErrorCode;
import com.red.circle.other.inner.enums.room.RoomEventEnum;
import com.red.circle.other.inner.model.dto.famliy.FamilyDetailsDTO;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
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/7/28
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class OnlineRoomCommon {

  private final FamilyCommon familyCommon;
  private final LiveMicClient liveMicClient;
  private final UserSVipGateway userSVipGateway;
  private final UserRegionGateway userRegionGateway;
  private final OnlineUserService onlineUserService;
  private final UserProfileGateway userProfileGateway;
  private final RoomTopFixedService roomTopFixedService;
  private final HotRoomCacheService hotRoomCacheService;
  private final ActiveVoiceRoomService activeVoiceRoomService;
  private final FamilyMemberInfoService familyMemberInfoService;
  private final RoomManagerCacheService roomManagerCacheService;
  private final RoomProfileManagerService roomProfileManagerService;

  /**
   * 刷新资料.
   *
   * @param roomId 房间id
   */
  public ActiveVoiceRoom addHeartbeatOnlineRoomProfileById(Long roomId) {
    RoomProfileManager activeVoiceRoom = roomProfileManagerService.getById(roomId);
    if (Objects.isNull(activeVoiceRoom) || !Objects.equals(activeVoiceRoom.getEvent(),
        RoomEventEnum.AVAILABLE.name())) {
      return null;
    }

    roomManagerCacheService.removeNumberPeople(activeVoiceRoom.getRoomAccount());
    return addActiveVoiceRoom(getActiveVoiceRoom(activeVoiceRoom));
  }

  /**
   * 添加在线房间.
   *
   * @param roomAccount 房间account
   */
  public ActiveVoiceRoom addOnlineRoomByAccount(String roomAccount) {
    RoomProfileManager activeVoiceRoom = roomProfileManagerService.getByRoomAccount(roomAccount);
    if (Objects.isNull(activeVoiceRoom) || !Objects.equals(activeVoiceRoom.getEvent(),
        RoomEventEnum.AVAILABLE.name())) {
      return null;
    }
    roomManagerCacheService.removeNumberPeople(activeVoiceRoom.getRoomAccount());
    return addActiveVoiceRoom(getActiveVoiceRoom(activeVoiceRoom));
  }


  private ActiveVoiceRoom addActiveVoiceRoom(ActiveVoiceRoom activeVoiceRoom) {
    if (Objects.isNull(activeVoiceRoom)) {
      return null;
    }

    activeVoiceRoomService.saveOrUpdate(activeVoiceRoom);
    return activeVoiceRoom;
  }

  private ActiveVoiceRoom getActiveVoiceRoom(RoomProfileManager room) {
    if (Objects.isNull(room)) {
      return null;
    }

    if (!Objects.equals(room.getEvent(), RoomEventEnum.AVAILABLE.name())) {
      return null;
    }

    UserProfile userProfile = userProfileGateway.getByUserId(room.getUserId());
    ResponseAssert.notNull(UserErrorCode.USER_INFO_NOT_FOUND, userProfile);

    if (!userProfile.checkAccountAvailable()) {
      return null;
    }

    // 房间上锁.
    Integer weights = StringUtils.isNotBlank(Optional.ofNullable(room.getSetting())
        .map(RoomSetting::getPassword)
        .orElse("")) ? 0 : 1;

    // String useLange = cacheUserProfileManagerService.getLanguage(room.getUserId());

    String roomOwnRegionCode = userRegionGateway.getRegionCode(room.getUserId());

//    ActiveVoiceRegion region = StringUtils.equalsIgnoreCase(useLange, "ar")
//        ? ActiveVoiceRegion.LANG_AR
//        : ActiveVoiceRegion.toRegion(userProfile.getCountryCode());

    RoomTopFixed roomTopFixed = roomTopFixedService.getByRoomId(room.getId());
    Integer roomTopFixedWeights = Optional.ofNullable(roomTopFixed)
        .map(fixed -> Objects.nonNull(fixed.getWeights()) ? fixed.getWeights() : 0)
        .orElse(0);

    boolean topRoomForeverOnline = Optional.ofNullable(roomTopFixed)
        .map(fixed -> Objects.equals(fixed.getForeverOnline(), Boolean.TRUE))
        .orElse(Boolean.FALSE);

    return new ActiveVoiceRoom()
        .setId(room.getId())
        .setTimeId(IdWorkerUtils.getId())
        .setSysOrigin(room.getSysOrigin())
        .setUserId(room.getUserId())
        .setRoomAccount(room.getRoomAccount())
        .setFixedWeights(roomTopFixedWeights)
        .setFamilyProfile(getFamilyProfile(room.getUserId()))
        .setRunGame(null)
        .setHot(
            Objects.nonNull(hotRoomCacheService.getAvailable(room.getSysOrigin(), room.getId())))
        .setCountryCode(StringUtils.toUpperCase(userProfile.getCountryCode()))
        .setCountryName(userProfile.getCountryName())
        // ALL所有、DEFAULT默认区域、其他根据语言分割.
        .setRegion(roomOwnRegionCode)
        .setExpiredTime(TimestampUtils.nowPlusMinutes(topRoomForeverOnline ? 60 : 3))
        .setCreateTime(TimestampUtils.now())
        .setUpdateTime(TimestampUtils.now())
        .setOnlineQuantity(getAvRoomOnlineMemberNum(room))
        .setWeights(weights)
        .setSuperVipLevel(Objects.toString(
            userSVipGateway.checkSVipIdentity(room.getUserId()))
        );
  }

  private FamilyProfile getFamilyProfile(Long userId) {
    FamilyMemberInfo memberInfo = familyMemberInfoService.getFamilyMemberByUserId(userId);

    if (Objects.isNull(memberInfo)) {
      return null;
    }

    FamilyDetailsDTO details = familyCommon.getFamilyDetails(memberInfo.getSysOrigin(),
        memberInfo.getFamilyId());
    if (Objects.isNull(details)) {
      return null;
    }
    return new FamilyProfile()
        .setId(details.getFamilyId())
        .setFamilyAccount(details.getFamilyAccount())
        .setFamilyName(details.getFamilyName())
        .setFamilyAvatar(details.getFamilyAvatar())
        .setBadgeCover(details.getBadgeCover())
        .setBadgeSource(details.getBadgeSvg());
  }

  private Long getAvRoomOnlineMemberNum(RoomProfile roomProfile) {
    //    Long numberPeople = roomManagerCacheService.getNumberPeople(activeVoiceRoom.getRoomAccount());
    //    if (Objects.nonNull(numberPeople)) {
    //      return numberPeople;
    //    }
    Long resultQuantity = liveMicClient.getLiveRoomUserSize(roomProfile.getId()).getBody();
    if (Objects.nonNull(resultQuantity)) {
      roomManagerCacheService.setNumberPeople(roomProfile.getRoomAccount(), resultQuantity);
      return resultQuantity;
    }

//    // 声网版本
//    if (Objects.equals(roomProfile.getSysOrigin(), SysOriginPlatformEnum.YOLO.name())) {
//      return Optional.ofNullable(liveMicClient.getLiveRoomUserSize(roomProfile.getId()).getBody())
//          .orElse(1L);
//    }
//    if (Objects.equals(roomProfile.getSysOrigin(), SysOriginPlatformEnum.TARAB.name())) {
//      return Optional.ofNullable(liveMicClient.getLiveRoomUserSize(roomProfile.getId()).getBody())
//          .orElse(1L);
//    }
//    Long resultQuantity = onlineUserService.countSessionId(roomProfile.getId());
//    if (Objects.nonNull(resultQuantity)) {
//      roomManagerCacheService.setNumberPeople(roomProfile.getRoomAccount(), resultQuantity);
//      return resultQuantity;
//    }
    return 0L;
  }

}
