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

import com.google.common.collect.Lists;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.mybatis.constant.PageConstant;
import com.red.circle.other.app.common.room.RoomVoiceProfileCommon;
import com.red.circle.other.app.dto.clientobject.room.RoomVoiceProfileCO;
import com.red.circle.other.app.dto.cmd.family.FamilyOnlineRoomQueryCmd;
import com.red.circle.other.infra.common.family.FamilyCommon;
import com.red.circle.other.infra.database.mongo.entity.live.ActiveVoiceRoom;
import com.red.circle.other.infra.database.mongo.service.live.ActiveVoiceRoomService;
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.FamilyErrorCode;
import com.red.circle.tool.core.collection.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * <p>
 * 家族在线房间.
 * </p>
 *
 * @author pengshigang
 * @since 2021-07-23
 */
@Component
@RequiredArgsConstructor
public class FamilyOnlineRoomExe {

  private final FamilyCommon familyCommon;
  private final RoomVoiceProfileCommon roomVoiceProfileCommon;
  private final ActiveVoiceRoomService activeVoiceRoomService;
  private final FamilyMemberInfoService familyMemberInfoService;

  public List<RoomVoiceProfileCO> execute(FamilyOnlineRoomQueryCmd cmd) {
    ResponseAssert.isTrue(FamilyErrorCode.NOT_EXIST_FAMILY_INFO_DATA,
        familyCommon.isExistFamilyById(cmd.getFamilyId()));

    List<ActiveVoiceRoom> activeVoiceRooms = getActiveVoiceRooms(cmd);

    if (CollectionUtils.isEmpty(activeVoiceRooms)) {
      return Lists.newArrayList();
    }

    return getProfileCO(cmd, listRoomVoiceProfileCO(activeVoiceRooms));
  }

  private List<RoomVoiceProfileCO> getProfileCO(FamilyOnlineRoomQueryCmd cmd,
      List<RoomVoiceProfileCO> profiles) {

    Map<Long, FamilyMemberInfo> mapFamilyMember = mapUserIdMember(cmd, profiles);
    if (CollectionUtils.isEmpty(mapFamilyMember) || CollectionUtils.isEmpty(profiles)) {
      return Lists.newArrayList();
    }

    List<RoomVoiceProfileCO> rooms = Lists.newArrayList();

    for (RoomVoiceProfileCO room : profiles) {
      FamilyMemberInfo familyMemberInfo = mapFamilyMember.get(room.getUserId());

      if (!isAdd(rooms, familyMemberInfo)) {
        break;
      }
      rooms.add(room);
    }
    return rooms;
  }

  private boolean isAdd(List<RoomVoiceProfileCO> rooms, FamilyMemberInfo familyMemberInfo) {
    return rooms.size() <= 20 && Objects.nonNull(familyMemberInfo) && Objects
        .nonNull(familyMemberInfo.getId());
  }

  private List<RoomVoiceProfileCO> listRoomVoiceProfileCO(List<ActiveVoiceRoom> activeVoiceRooms) {
    return roomVoiceProfileCommon.listRoomVoiceProfilesV2(
        activeVoiceRooms.stream().map(ActiveVoiceRoom::getId).collect(
            Collectors.toSet()));
  }

  private Map<Long, FamilyMemberInfo> mapUserIdMember(FamilyOnlineRoomQueryCmd cmd,
      List<RoomVoiceProfileCO> activeVoiceRooms) {
    return familyMemberInfoService.mapUserIdBaseInfo(cmd.getFamilyId(),
        activeVoiceRooms.stream().map(RoomVoiceProfileCO::getUserId).collect(Collectors.toSet()));
  }

  private List<ActiveVoiceRoom> getActiveVoiceRooms(FamilyOnlineRoomQueryCmd cmd) {
    return activeVoiceRoomService.listByFamilyId(cmd.getFamilyId(), PageConstant.MAX_LIMIT_SIZE);
  }


}
