package com.red.circle.live.app.command.mic;

import com.red.circle.external.inner.endpoint.message.TrtcClient;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.live.app.convertor.LiveMicAppConvertor;
import com.red.circle.live.app.dto.clientobject.LiveMicrophoneCO;
import com.red.circle.live.app.dto.cmd.MicUpDownCmd;
import com.red.circle.live.domain.gateway.LiveMicrophoneGateway;
import com.red.circle.live.domain.live.dto.LiveMicrophoneNoticeDTO;
import com.red.circle.live.infra.database.cache.service.UserAgoraTokenCacheService;
import com.red.circle.live.infra.database.mongo.service.LiveMicSettingService;
import com.red.circle.live.inner.error.LiveMicErrorCode;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 上麦克风.
 *
 * @author pengliang on 2023/12/8
 */
@Component
@RequiredArgsConstructor
public class LiveMicGoUpCmdExe {

  private static final Logger log = LoggerFactory.getLogger(LiveMicGoUpCmdExe.class);
  private final LiveMicAppConvertor liveMicAppConvertor;
  private final LiveMicSettingService liveMicSettingService;
  private final LiveMicrophoneGateway liveMicrophoneGateway;
  private final TrtcClient trtcClient;
  private final UserAgoraTokenCacheService userAgoraTokenCacheService;


  public LiveMicrophoneCO execute(MicUpDownCmd cmd) {
    checkPermissions(cmd);
    LiveMicrophoneNoticeDTO noticeDTO = liveMicrophoneGateway.goUp(
        cmd.getRoomId(),
        cmd.getMickIndex(),
        cmd.requiredReqUserId()
    );
    LiveMicrophoneCO notice = returnMicrophoneCO(cmd, noticeDTO);
    String roomToken = userAgoraTokenCacheService.getUserAgoraToken(cmd.getReqUserId(), cmd.getRoomId());
    if (Objects.isNull(roomToken)) {
      notice.setRoomToken(trtcClient.createAgoraTokenGoUp(cmd.getReqUserId(), cmd.getRoomId().toString()).getBody());
      //notice.setRoomToken(trtcClient.createAgoraTokenGoUp(cmd.getReqUserId(),cmd.getRoomId().toString()).getBody());
      userAgoraTokenCacheService.save(notice.getRoomToken(), cmd.getReqUserId(), cmd.getRoomId());
    } else {
      notice.setRoomToken(roomToken);
    }
    //notice.setRoomToken(createAgoraTokenGoUp(cmd));
    return notice;
  }

  private LiveMicrophoneCO returnMicrophoneCO(MicUpDownCmd cmd, LiveMicrophoneNoticeDTO notice) {
    return liveMicAppConvertor.toLiveMicrophoneCO(notice.filterMicIndex(cmd.getMickIndex()));
  }

  private void checkPermissions(MicUpDownCmd cmd) {
    if (!cmd.eventTypeEqInvite()) {
      // 麦克风是否上锁
      ResponseAssert.isFalse(LiveMicErrorCode.MIC_LOCKED,
          liveMicSettingService.checkLock(cmd.getRoomId(), cmd.getMickIndex()));
    }
  }

  /**
   * 异步拿声网token，5分钟拿不到就返回默认一串字符串
   * @param cmd
   * @return
   */
  private String createAgoraTokenGoUp(MicUpDownCmd cmd) {
    ExecutorService executor = Executors.newSingleThreadExecutor();
    AtomicReference<String> agoraToken = new AtomicReference<>("BaHrIypJdFWqwWtoZLToRucRyoGrVgYCONBFvGynmlJsevFYsWBfEIcaWUUGijQBjycTtmSvkmBINoSltJMmgiPeBnkaWErixaxg");
    Future<?> future = executor.submit(() -> {
      agoraToken.set(trtcClient.createAgoraTokenGoUp(cmd.getReqUserId(), cmd.getRoomId().toString()).getBody());
    });

    try {
      future.get(3, TimeUnit.SECONDS); // 等待最多3秒
    } catch (TimeoutException e) {
      // 处理超时
      log.warn("上麦获取声网token超时: {}", e.getMessage());
    } catch (InterruptedException | ExecutionException e) {
      // 处理其他异常
      log.warn("上麦获取声网token其他异常: {}", e.getMessage());
    }

    executor.shutdown();
    return agoraToken.get();
  }

  public static void main(String[] args) {
    System.out.println("开始等待...");
    ExecutorService executor = Executors.newSingleThreadExecutor();
    AtomicReference<String> agoraToken = new AtomicReference<>("");
    Future<?> future = executor.submit(() -> {
        // 等待6秒
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        agoraToken.set("拿到值啦！！！！！");
    });

    try {
      future.get(5, TimeUnit.SECONDS); // 等待最多3秒
    } catch (TimeoutException e) {
      // 处理超时
      log.warn("上麦获取声网token超时: {}", e);
    } catch (InterruptedException | ExecutionException e) {
      // 处理其他异常
      log.warn("上麦获取声网token其他异常: {}", e);
    }

    executor.shutdown();
    System.out.println(agoraToken.get());
    System.out.println("结束...");
  }


}
