package com.red.circle.live.app.service;

import com.red.circle.component.redis.service.RedisService;
import com.red.circle.live.domain.gateway.LiveMicrophoneGateway;
import com.red.circle.live.domain.live.LiveMicrophone;
import com.red.circle.live.infra.database.cache.service.LiveMicCacheService;
import com.red.circle.live.infra.database.cache.service.LiveMicUserCacheService;
import com.red.circle.live.infra.database.cache.service.LiveMusicHeartbeatService;
import com.red.circle.live.infra.database.cache.service.UserAgoraTokenCacheService;
import com.red.circle.tool.core.collection.CollectionUtils;
import java.util.List;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * 声网状态反向清理业务麦位和房间在线缓存.
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AgoraMicStateCleanupService {

  private final LiveMicCacheService liveMicCacheService;
  private final LiveMicUserCacheService liveMicUserCacheService;
  private final LiveMusicHeartbeatService liveMusicHeartbeatService;
  private final LiveMicrophoneGateway liveMicrophoneGateway;
  private final UserAgoraTokenCacheService userAgoraTokenCacheService;
  private final RedisService redisService;

  public boolean cleanupUser(Long roomId, Long userId, String reason) {
    if (Objects.isNull(roomId) || Objects.isNull(userId)) {
      return false;
    }

    boolean micChanged = false;
    List<LiveMicrophone> liveMicrophones = liveMicCacheService.listLiveMicrophone(roomId, userId);
    if (CollectionUtils.isNotEmpty(liveMicrophones)) {
      for (LiveMicrophone mic : liveMicrophones) {
        if (Objects.isNull(mic) || Objects.isNull(mic.getMicIndex())) {
          continue;
        }
        final boolean[] removed = {false};
        liveMicrophoneGateway.tryMicOpsLock(roomId, mic.getMicIndex(), () -> {
          liveMicCacheService.goDown(roomId, mic.getMicIndex());
          removed[0] = true;
        });
        micChanged = micChanged || removed[0];
      }
    }

    liveMicUserCacheService.removeUser(roomId, userId);
    redisService.delete("IN_ROOM:" + userId);
    userAgoraTokenCacheService.remove(userId, roomId);

    if (micChanged) {
      notifyMicChanged(roomId, reason);
    }

    log.warn("声网状态清理用户 roomId={}, userId={}, micChanged={}, reason={}",
        roomId, userId, micChanged, reason);
    return micChanged;
  }

  public void cleanupRoom(Long roomId, String reason) {
    if (Objects.isNull(roomId)) {
      return;
    }
    liveMicCacheService.goDownAll(roomId);
    liveMicUserCacheService.remove(roomId);
    liveMusicHeartbeatService.removeMickUser(roomId);
    notifyMicChanged(roomId, reason);
    log.warn("声网状态清理房间 roomId={}, reason={}", roomId, reason);
  }

  private void notifyMicChanged(Long roomId, String reason) {
    try {
      liveMicrophoneGateway.micUserChangeNotice(roomId);
    } catch (Exception e) {
      log.error("声网状态清理后推送麦位变更失败 roomId={}, reason={}", roomId, reason, e);
    }
  }
}
