var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
import { TRTCVideoEncParam, TRTCVideoResolution, TUIRoomType, TUISeatMode, TUIMediaDeviceType, TUIVideoStreamType } from "@tencentcloud/tuiroom-engine-js";
import { EventType } from "../types.mjs";
import { isWeChat, isMobile } from "../../utils/environment.mjs";
import logger from "../../utils/common/logger/index.mjs";
const logPrefix = "[RoomService:roomActionManager]";
const smallParam = new TRTCVideoEncParam();
smallParam.videoResolution = TRTCVideoResolution.TRTCVideoResolution_640_360;
smallParam.videoFps = 10;
smallParam.videoBitrate = 550;
class RoomActionManager {
  constructor(service) {
    __publicField(this, "service");
    this.service = service;
  }
  async start(roomId, params = {}) {
    const {
      roomName,
      isSeatEnabled = false,
      isOpenCamera = false,
      isOpenMicrophone = false,
      defaultCameraId,
      defaultMicrophoneId,
      defaultSpeakerId
    } = params;
    const roomMode = isSeatEnabled ? "SpeakAfterTakingSeat" : "FreeToSpeak";
    await this.createRoom({
      roomId,
      roomName,
      roomMode,
      roomParam: {
        isOpenCamera,
        isOpenMicrophone,
        defaultCameraId,
        defaultMicrophoneId,
        defaultSpeakerId
      }
    });
    await this.enterRoom({
      roomId,
      roomParam: {
        isOpenCamera,
        isOpenMicrophone,
        defaultCameraId,
        defaultMicrophoneId,
        defaultSpeakerId
      }
    });
    this.service.emit(EventType.ROOM_START);
  }
  async join(roomId, params = {}) {
    const {
      isOpenCamera = false,
      isOpenMicrophone = false,
      defaultCameraId,
      defaultMicrophoneId,
      defaultSpeakerId,
      password
    } = params;
    await this.enterRoom({
      roomId,
      roomParam: {
        isOpenCamera,
        isOpenMicrophone,
        defaultCameraId,
        defaultMicrophoneId,
        defaultSpeakerId,
        password
      }
    });
    this.service.emit(EventType.ROOM_JOIN);
  }
  async leaveRoom() {
    var _a;
    try {
      this.closeMediaBeforeLeave();
      const response = await ((_a = this.service.roomEngine.instance) == null ? void 0 : _a.exitRoom());
      this.service.resetStore();
      logger.log(`${logPrefix}leaveRoom:`, response);
      this.service.emit(EventType.ROOM_LEAVE, response);
    } catch (error) {
      logger.error(`${logPrefix}leaveRoom error:`, error);
    }
  }
  async dismissRoom() {
    var _a;
    try {
      logger.log(`${logPrefix}dismissRoom: enter`);
      this.closeMediaBeforeLeave();
      await ((_a = this.service.roomEngine.instance) == null ? void 0 : _a.destroyRoom());
      this.service.resetStore();
      this.service.emit(EventType.ROOM_DISMISS, {});
    } catch (error) {
      logger.error(`${logPrefix}dismissRoom error:`, error);
    }
  }
  async createRoom(options) {
    try {
      const { roomId, roomName, roomMode } = options;
      const roomParams = {
        roomId,
        roomName,
        roomType: TUIRoomType.kConference,
        isSeatEnabled: roomMode !== "FreeToSpeak",
        seatMode: roomMode === "SpeakAfterTakingSeat" ? TUISeatMode.kApplyToTake : void 0
      };
      await this.handleRoomCreation(roomParams, options);
    } catch (error) {
      logger.error(`${logPrefix}createRoom error:`, error);
      this.service.errorHandler.handleError(error, "createRoom");
      throw error;
    }
  }
  async handleRoomCreation(roomParams, options) {
    var _a;
    const { roomEngine } = this.service;
    if (!roomEngine.instance) {
      return;
    }
    this.service.basicStore.setRoomId(roomParams.roomId);
    logger.debug(`${logPrefix}createRoom:`, roomParams, options);
    await ((_a = roomEngine.instance) == null ? void 0 : _a.createRoom(roomParams));
  }
  async enterRoom(options) {
    var _a;
    try {
      const { roomId, roomParam } = options;
      const roomInfo = await this.doEnterRoom({
        roomId,
        roomType: TUIRoomType.kConference,
        password: (roomParam == null ? void 0 : roomParam.password) || ""
      });
      this.service.roomStore.setRoomInfo(roomInfo);
      await this.getUserList();
      await this.syncUserInfo(this.service.basicStore.userId);
      await this.fetchAttendeeList(roomId);
      await this.getInvitationList(roomId);
      if (roomInfo.isSeatEnabled) {
        await this.getSeatList();
        this.service.roomStore.isMaster && await ((_a = this.service.roomEngine.instance) == null ? void 0 : _a.takeSeat({
          seatIndex: -1,
          timeout: 0
        }));
      }
      this.setRoomParams(roomParam);
    } catch (error) {
      logger.error(`${logPrefix}enterRoom error:`, error);
      this.service.errorHandler.handleError(error, "enterRoom");
      throw error;
    }
  }
  async setRoomParams(roomParam) {
    var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
    if (!roomParam) {
      return;
    }
    const {
      isOpenCamera,
      isOpenMicrophone,
      defaultCameraId,
      defaultMicrophoneId,
      defaultSpeakerId
    } = roomParam;
    if (defaultCameraId) {
      this.service.roomStore.setCurrentCameraId(defaultCameraId);
      (_a = this.service.roomEngine.instance) == null ? void 0 : _a.setCurrentCameraDevice({
        deviceId: defaultCameraId
      });
    }
    if (defaultMicrophoneId) {
      this.service.roomStore.setCurrentMicrophoneId(defaultMicrophoneId);
      (_b = this.service.roomEngine.instance) == null ? void 0 : _b.setCurrentMicDevice({
        deviceId: defaultMicrophoneId
      });
    }
    if (defaultSpeakerId) {
      this.service.roomStore.setCurrentSpeakerId(defaultSpeakerId);
      (_c = this.service.roomEngine.instance) == null ? void 0 : _c.setCurrentSpeakerDevice({
        deviceId: defaultSpeakerId
      });
    }
    const {
      isMaster,
      isMicrophoneDisableForAllUser,
      isCameraDisableForAllUser,
      isFreeSpeakMode
    } = this.service.roomStore;
    const isCanOpenMicrophone = isMaster || !isMicrophoneDisableForAllUser && isFreeSpeakMode;
    if (isCanOpenMicrophone) {
      if (isOpenMicrophone) {
        await ((_d = this.service.roomEngine.instance) == null ? void 0 : _d.unmuteLocalAudio());
        if (!this.service.basicStore.isOpenMic) {
          (_e = this.service.roomEngine.instance) == null ? void 0 : _e.openLocalMicrophone();
          this.service.basicStore.setIsOpenMic(true);
        }
        if (!isWeChat && !isMobile) {
          const microphoneList = await ((_f = this.service.roomEngine.instance) == null ? void 0 : _f.getMicDevicesList());
          const speakerList = await ((_g = this.service.roomEngine.instance) == null ? void 0 : _g.getSpeakerDevicesList());
          if ((microphoneList == null ? void 0 : microphoneList.length) === 0 || (speakerList == null ? void 0 : speakerList.length) === 0) return;
          if (!this.service.roomStore.currentMicrophoneId && microphoneList.length > 0) {
            this.service.roomStore.setCurrentMicrophoneId(
              microphoneList[0].deviceId
            );
          }
          if (!this.service.roomStore.currentSpeakerId && speakerList.length > 0) {
            this.service.roomStore.setCurrentSpeakerId(speakerList[0].deviceId);
          }
          await ((_h = this.service.roomEngine.instance) == null ? void 0 : _h.setCurrentMicDevice({
            deviceId: this.service.roomStore.currentMicrophoneId
          }));
        }
      } else {
        await ((_i = this.service.roomEngine.instance) == null ? void 0 : _i.muteLocalAudio());
      }
    }
    const isCanOpenCamera = isMaster || !isCameraDisableForAllUser && isFreeSpeakMode;
    if (isCanOpenCamera && isOpenCamera) {
      if (isMobile) {
        await ((_j = this.service.roomEngine.instance) == null ? void 0 : _j.openLocalCamera({
          isFrontCamera: this.service.basicStore.isFrontCamera
        }));
        return;
      }
      const deviceManager = (_k = this.service.roomEngine.instance) == null ? void 0 : _k.getMediaDeviceManager();
      if (!this.service.roomStore.currentCameraId) {
        const cameraList = await deviceManager.getDevicesList({
          type: TUIMediaDeviceType.kMediaDeviceTypeVideoCamera
        });
        if (cameraList && cameraList.length > 0) {
          this.service.roomStore.setCurrentCameraId(cameraList[0].deviceId);
        }
      }
      await deviceManager.setCurrentDevice({
        type: TUIMediaDeviceType.kMediaDeviceTypeVideoCamera,
        deviceId: this.service.roomStore.currentCameraId
      });
      await ((_l = this.service.roomEngine.instance) == null ? void 0 : _l.openLocalCamera());
    }
  }
  async doEnterRoom(params) {
    var _a, _b, _c, _d;
    const { roomEngine } = this.service;
    const { roomId, roomType, password } = params;
    this.service.basicStore.setRoomId(roomId);
    const isH5 = isMobile && !isWeChat;
    const trtcCloud = (_a = roomEngine.instance) == null ? void 0 : _a.getTRTCCloud();
    trtcCloud == null ? void 0 : trtcCloud.setDefaultStreamRecvMode(true, false);
    const roomInfo = await ((_b = roomEngine.instance) == null ? void 0 : _b.enterRoom({
      roomId,
      roomType,
      options: {
        password
      }
    }));
    trtcCloud == null ? void 0 : trtcCloud.enableSmallVideoStream(!isH5, smallParam);
    (_c = roomEngine.instance) == null ? void 0 : _c.muteLocalAudio();
    if (!roomInfo.isSeatEnabled) {
      (_d = roomEngine.instance) == null ? void 0 : _d.openLocalMicrophone();
      this.service.basicStore.setIsOpenMic(true);
    }
    return roomInfo;
  }
  async getUserList() {
    var _a;
    const { roomEngine } = this.service;
    let nextSequence = 0;
    try {
      do {
        const result = await ((_a = roomEngine.instance) == null ? void 0 : _a.getUserList({
          nextSequence
        }));
        result.userInfoList.forEach((user) => {
          this.service.roomStore.addUserInfo(
            Object.assign(user, { isInRoom: true })
          );
          if (this.service.roomStore.isFreeSpeakMode) {
            this.service.roomStore.addStreamInfo(
              user.userId,
              TUIVideoStreamType.kCameraStream
            );
          }
        });
        nextSequence = result.nextSequence;
      } while (nextSequence !== 0);
    } catch (error) {
      logger.error("TUIRoomEngine.getUserList", error.code, error.message);
    }
  }
  async getInvitationList(roomId, cursor = "", result = []) {
    const res = await this.service.conferenceInvitationManager.getInvitationList({
      roomId,
      cursor,
      count: 20
    });
    if (!(res == null ? void 0 : res.invitationList)) return [];
    result.push(...res == null ? void 0 : res.invitationList);
    if (res.cursor !== "") {
      await this.getInvitationList(roomId, res.cursor, result);
    }
    const list = result.map(({ invitee, status }) => ({
      ...invitee,
      status
    }));
    this.service.roomStore.updateInviteeList(list);
  }
  async fetchAttendeeList(roomId, cursor = "", result = []) {
    const res = await this.service.scheduleConferenceManager.fetchAttendeeList({
      roomId,
      cursor,
      count: 20
    });
    if (!(res == null ? void 0 : res.attendeeList)) return [];
    result.push(...res == null ? void 0 : res.attendeeList);
    if (res.cursor !== "") {
      await this.fetchAttendeeList(roomId, res.cursor, result);
    }
    const inviteeList = result.filter((user) => {
      return !this.service.roomStore.userList.some(
        (item) => item.userId === user.userId
      );
    });
    this.service.roomStore.updateInviteeList(inviteeList);
  }
  async syncUserInfo(userId) {
    var _a;
    const { roomEngine } = this.service;
    const userInfo = await ((_a = roomEngine.instance) == null ? void 0 : _a.getUserInfo({
      userId
    }));
    const { isMessageDisabled } = userInfo;
    this.service.chatStore.setSendMessageDisableChanged(isMessageDisabled);
  }
  async getSeatList() {
    var _a;
    const { roomEngine } = this.service;
    try {
      const seatList = await ((_a = roomEngine.instance) == null ? void 0 : _a.getSeatList());
      seatList.forEach((seat) => {
        const { userId } = seat;
        if (!userId) {
          return;
        }
        const user = this.service.roomStore.userInfoObj[userId];
        if (user) {
          this.service.roomStore.updateUserInfo({ userId, onSeat: true });
        } else {
          this.service.roomStore.addUserInfo({
            userId,
            onSeat: true,
            isInRoom: true
          });
        }
        this.service.roomStore.addStreamInfo(
          userId,
          TUIVideoStreamType.kCameraStream
        );
      });
    } catch (error) {
      logger.error("TUIRoomEngine.getSeatList", error.code, error.message);
    }
  }
  closeMediaBeforeLeave() {
    var _a, _b;
    const { roomEngine } = this.service;
    if (this.service.roomStore.localUser.hasAudioStream) {
      (_a = roomEngine.instance) == null ? void 0 : _a.closeLocalMicrophone();
    }
    if (this.service.roomStore.localUser.hasVideoStream) {
      (_b = roomEngine.instance) == null ? void 0 : _b.closeLocalCamera();
    }
  }
  async fetchRoomInfo(options) {
    var _a;
    return await ((_a = this.service.roomEngine.instance) == null ? void 0 : _a.fetchRoomInfo(options));
  }
}
export {
  RoomActionManager
};
