package com.red.circle.live.app.command.user.qry;

import com.red.circle.common.business.dto.cmd.app.AppRoomIdCmd;
import com.red.circle.live.app.convertor.LiveMicAppConvertor;
import com.red.circle.live.app.dto.clientobject.LiveMicUserCO;
import com.red.circle.live.domain.gateway.LiveMicrophoneGateway;
import com.red.circle.live.domain.live.LiveMicUser;
import com.red.circle.live.domain.online.LiveRoomUser;
import com.red.circle.live.infra.database.cache.service.LiveMicUserCacheService;
import com.red.circle.tool.core.collection.CollectionUtils;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * 房间在线用户.
 *
 * @author pengliang on 2023/12/11
 */
@Component
@RequiredArgsConstructor
public class LiveOnlineUserQryExe {

  private static final Logger log = LoggerFactory.getLogger(LiveOnlineUserQryExe.class);
  private final LiveMicAppConvertor liveMicAppConvertor;
  private final LiveMicUserCacheService liveMicUserCacheService;
  private final LiveMicrophoneGateway liveMicrophoneGateway;

  public List<LiveMicUserCO> execute(AppRoomIdCmd cmd) {
    List<LiveRoomUser> liveRoomUsers = liveMicUserCacheService.listUser(cmd.getRoomId());

    if (CollectionUtils.isEmpty(liveRoomUsers)) {
      return CollectionUtils.newArrayList();
    }

    return listLiveMicUser(cmd, liveRoomUsers);
  }

  private List<LiveMicUserCO> listLiveMicUser(AppRoomIdCmd cmd,
      List<LiveRoomUser> liveRoomUsers) {
    List<LiveRoomUser> roomUsers = liveRoomUsers.stream()
        .filter(user -> !user.checkInactiveExpire())
        .sorted(Comparator.comparing(LiveRoomUser::getWeights, Comparator.reverseOrder()))
        .toList();

    Map<Long, LiveMicUser> longLiveMicUserMap = liveMicrophoneGateway.mapLiveMicUser(
        cmd.getRoomId(),
        roomUsers.stream().map(LiveRoomUser::getUserId).collect(Collectors.toSet())
    );
    //log.warn("longLiveMicUserMap {}", longLiveMicUserMap);

    return roomUsers.stream()
        .map(roomUser -> liveMicAppConvertor.toLiveMicUserCO(
            longLiveMicUserMap.get(roomUser.getUserId())))
        .filter(Objects::nonNull)
        .toList();
  }

}
