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

import com.red.circle.framework.mybatis.constant.PageConstant;
import com.red.circle.other.app.common.room.RoomRegionFilterCommon;
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.room.RegionSearchRoomQryCmd;
import com.red.circle.other.domain.model.user.ability.RegionConfig;
import com.red.circle.other.infra.database.mongo.entity.live.ActiveVoiceRoom;
import com.red.circle.other.infra.database.mongo.entity.live.RoomProfileManager;
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.tool.core.collection.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * 获取区域房间.
 *
 * @author pengliang on 2021/3/10
 */
@Component
@RequiredArgsConstructor
public class SearchRegionRoomQryExe {

  private final ActiveVoiceRoomService activeVoiceRoomService;
  private final RoomRegionFilterCommon roomRegionFilterCommon;
  private final RoomVoiceProfileCommon roomVoiceProfileCommon;
  private final RoomProfileManagerService roomProfileManagerService;

  public List<RoomVoiceProfileCO> execute(RegionSearchRoomQryCmd cmd) {
    boolean allRegionWhiteListUser = roomRegionFilterCommon.canViewAllRegions(cmd.requiredReqUserId());
    RegionConfig currentRegion = roomRegionFilterCommon.requireRegionConfig(cmd.requiredReqUserId());
    String currentRegionCode = currentRegion.getRegionCode();

    List<ActiveVoiceRoom> activeVoiceRooms = allRegionWhiteListUser
        ? activeVoiceRoomService.listDiscover(cmd.requireReqSysOrigin(), true, currentRegionCode, null,
            PageConstant.MAX_LIMIT_SIZE)
        : roomRegionFilterCommon.filterActiveVoiceRoomsByRegion(
            activeVoiceRoomService.listByRegion(cmd.requireReqSysOrigin(), currentRegionCode,
                PageConstant.MAX_LIMIT_SIZE),
            currentRegionCode
        );

    if (CollectionUtils.isNotEmpty(activeVoiceRooms) && activeVoiceRooms.size() >= 100) {
      return assemblyRoomVoiceProfile(activeVoiceRooms);
    }

    List<RoomProfileManager> fallbackRoomManagersSource = roomProfileManagerService.listSelectiveLimitByCountryCodes(
        cmd.requireReqSysOrigin(),
        allRegionWhiteListUser ? List.of() : roomRegionFilterCommon.listCountryCodes(currentRegion),
        activeVoiceRooms.stream().map(ActiveVoiceRoom::getId).collect(Collectors.toList()),
        PageConstant.MAX_LIMIT_SIZE
    );
    List<RoomProfileManager> fallbackRoomManagers = allRegionWhiteListUser
        ? fallbackRoomManagersSource
        : roomRegionFilterCommon.filterRoomProfileManagersByRegion(
            fallbackRoomManagersSource,
            currentRegionCode
        );

    if (CollectionUtils.isEmpty(activeVoiceRooms)) {
      return roomVoiceProfileCommon.listRoomVoiceProfilesV2(fallbackRoomManagers);
    }

    List<RoomVoiceProfileCO> roomVoiceProfiles = new ArrayList<>(assemblyRoomVoiceProfile(activeVoiceRooms));
    roomVoiceProfiles.addAll(roomVoiceProfileCommon.listRoomVoiceProfilesV2(fallbackRoomManagers));
    return roomVoiceProfiles.stream().limit(PageConstant.MAX_LIMIT_SIZE).toList();
  }

  private List<RoomVoiceProfileCO> assemblyRoomVoiceProfile(
          List<ActiveVoiceRoom> activeVoiceRooms) {
    return roomVoiceProfileCommon.toListRoomVoiceProfileCO(activeVoiceRooms);
  }

}
