"use strict";
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);
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const TUIRoomEngine = require("@tencentcloud/tuiroom-engine-js");
const types = require("../types.js");
const environment = require("../../utils/environment.js");
const message = require("../../constants/message.js");
const index = require("../../utils/common/logger/index.js");
class MediaManager {
  constructor(service) {
    __publicField(this, "service");
    __publicField(this, "intersectionObserver", null);
    __publicField(this, "observerDataMap", /* @__PURE__ */ new Map());
    __publicField(this, "observerRoot", null);
    __publicField(this, "onUserVideoStateChanged", (eventInfo) => {
      const { userId, streamType, hasVideo, reason } = eventInfo;
      if (userId === this.service.basicStore.userId && !hasVideo && reason === TUIRoomEngine.TUIChangeReason.kChangedByAdmin) {
        if (streamType === TUIRoomEngine.TUIVideoStreamType.kCameraStream) {
          this.service.emit(types.EventType.ROOM_NOTICE_MESSAGE, {
            type: "warning",
            message: this.service.t("Your camera has been turned off"),
            duration: message.MESSAGE_DURATION.NORMAL
          });
          this.service.roomStore.setCanControlSelfVideo(
            !this.service.roomStore.isCameraDisableForAllUser
          );
        }
        if (streamType === TUIRoomEngine.TUIVideoStreamType.kScreenStream) {
          this.service.emit(types.EventType.ROOM_NOTICE_MESSAGE_BOX, {
            title: this.service.t("Your screen sharing has been stopped"),
            message: this.service.t(
              "Your screen sharing has been stopped, Now only the host/admin can share the screen"
            ),
            confirmButtonText: this.service.t("I got it")
          });
        }
      }
    });
    this.service = service;
    this.bindRoomEngineEvents();
  }
  getRecordStreamType(streamType) {
    if (streamType === TUIRoomEngine.TUIVideoStreamType.kCameraStreamLow) {
      return TUIRoomEngine.TUIVideoStreamType.kCameraStream;
    }
    return streamType;
  }
  intersectionObserverCallback(entries) {
    entries.forEach((entry) => {
      var _a;
      const { isIntersecting, target } = entry;
      const observerData = this.observerDataMap.get(target);
      if (!observerData) {
        return;
      }
      const { userId, streamType } = observerData;
      const streamInfo = this.service.roomStore.getStreamInfo(
        userId,
        streamType
      );
      if (!streamInfo) {
        return;
      }
      const { playDomList } = streamInfo;
      if (isIntersecting && (playDomList == null ? void 0 : playDomList.length)) {
        observerData.isIntersection = true;
        this.doStartPlayVideo({ userId, streamType, view: playDomList });
      } else {
        observerData.isIntersection = false;
        const isContinuePlay = (_a = streamInfo == null ? void 0 : streamInfo.playDomList) == null ? void 0 : _a.find(
          (item) => {
            var _a2;
            return (_a2 = this.observerDataMap.get(item)) == null ? void 0 : _a2.isIntersection;
          }
        );
        if (!isContinuePlay) {
          this.doStopPlayVideo({ userId, streamType });
        }
      }
    });
  }
  initIntersectionObserver() {
    if (!this.intersectionObserver || document.getElementById("roomContainer") !== this.observerRoot) {
      const observerRoot = document.getElementById("roomContainer");
      this.intersectionObserver = new IntersectionObserver(
        this.intersectionObserverCallback.bind(this),
        {
          root: observerRoot,
          rootMargin: "0px"
        }
      );
      this.observerDataMap = /* @__PURE__ */ new Map();
      this.observerRoot = observerRoot;
    }
  }
  async startPlayVideo(options) {
    var _a, _b, _c, _d;
    const { userId, streamType, view, observerViewInVisible } = options;
    index.default.info(
      "MediaManager.startPlayVideo",
      userId,
      streamType,
      view,
      observerViewInVisible
    );
    const streamInfo = this.service.roomStore.getStreamInfo(userId, streamType);
    if (!streamInfo) {
      return;
    }
    let newPlayDomList = ((_a = streamInfo.playDomList) == null ? void 0 : _a.slice(0)) || [];
    newPlayDomList.push(view);
    newPlayDomList = [...new Set(newPlayDomList)];
    if (!observerViewInVisible) {
      this.service.roomStore.updateStreamInfo({
        userId,
        streamType,
        playDomList: newPlayDomList
      });
      await this.doStartPlayVideo({ userId, streamType, view: newPlayDomList });
      return;
    }
    this.initIntersectionObserver();
    (_b = streamInfo == null ? void 0 : streamInfo.playDomList) == null ? void 0 : _b.forEach((playDom) => {
      var _a2, _b2, _c2;
      if (!newPlayDomList.includes(playDom)) {
        if (((_a2 = this.observerDataMap.get(playDom)) == null ? void 0 : _a2.userId) === userId && this.getRecordStreamType(
          (_b2 = this.observerDataMap.get(playDom)) == null ? void 0 : _b2.streamType
        ) === this.getRecordStreamType(streamType)) {
          this.observerDataMap.delete(playDom);
          (_c2 = this.intersectionObserver) == null ? void 0 : _c2.unobserve(playDom);
        }
      }
    });
    this.service.roomStore.updateStreamInfo({
      userId,
      streamType,
      playDomList: newPlayDomList
    });
    this.observerDataMap.set(
      view,
      Object.assign(this.observerDataMap.get(view) || {}, {
        userId,
        streamType
      })
    );
    (_c = this.intersectionObserver) == null ? void 0 : _c.observe(view);
    if ((_d = this.observerDataMap.get(view)) == null ? void 0 : _d.isIntersection) {
      await this.doStartPlayVideo({ userId, streamType, view: newPlayDomList });
    }
  }
  async doStartPlayVideo(options) {
    var _a, _b, _c;
    const { userId, streamType, view } = options;
    const viewIdList = view.map((item) => {
      if (item instanceof HTMLElement) {
        return item == null ? void 0 : item.id;
      }
      return item;
    });
    this.service.roomStore.updateStreamInfo({
      userId,
      streamType,
      isLoading: true
    });
    if (userId === this.service.basicStore.userId && streamType === TUIRoomEngine.TUIVideoStreamType.kCameraStream) {
      (_a = this.service.roomEngine.instance) == null ? void 0 : _a.setLocalVideoView({ view: viewIdList });
    } else {
      (_b = this.service.roomEngine.instance) == null ? void 0 : _b.setRemoteVideoView({
        userId,
        streamType,
        view: viewIdList
      });
      await this.setVideoRenderParams({ userId, streamType });
      await ((_c = this.service.roomEngine.instance) == null ? void 0 : _c.startPlayRemoteVideo({
        userId,
        streamType
      }));
    }
    this.service.roomStore.updateStreamInfo({
      userId,
      streamType,
      isLoading: false
    });
  }
  async setVideoRenderParams(options) {
    var _a;
    const { userId, streamType } = options;
    if (userId !== this.service.basicStore.userId) {
      const trtcCloud = (_a = this.service.roomEngine.instance) == null ? void 0 : _a.getTRTCCloud();
      const trtcStreamType = streamType === TUIRoomEngine.TUIVideoStreamType.kScreenStream ? TUIRoomEngine.TRTCVideoStreamType.TRTCVideoStreamTypeSub : TUIRoomEngine.TRTCVideoStreamType.TRTCVideoStreamTypeBig;
      let trtcFillMode = TUIRoomEngine.TRTCVideoFillMode.TRTCVideoFillMode_Fit;
      if (environment.isMobile && streamType !== TUIRoomEngine.TUIVideoStreamType.kScreenStream) {
        trtcFillMode = TUIRoomEngine.TRTCVideoFillMode.TRTCVideoFillMode_Fill;
      }
      await (trtcCloud == null ? void 0 : trtcCloud.setRemoteRenderParams(userId, trtcStreamType, {
        mirrorType: TUIRoomEngine.TRTCVideoMirrorType.TRTCVideoMirrorType_Disable,
        rotation: TUIRoomEngine.TRTCVideoRotation.TRTCVideoRotation0,
        fillMode: trtcFillMode
      }));
    }
  }
  // If only one view wants to stop playing, update the viewList, but don't stop the stream.
  // If no view is passed in, the stream is stopped.
  async stopPlayVideo(options) {
    var _a;
    const { userId, streamType, view } = options;
    index.default.info("MediaManager.stopPlayVideo", userId, streamType, view);
    const streamInfo = this.service.roomStore.getStreamInfo(userId, streamType);
    if (!(streamInfo == null ? void 0 : streamInfo.playDomList) || (streamInfo == null ? void 0 : streamInfo.playDomList.length) === 0) {
      return;
    }
    if (this.observerDataMap.get(view)) {
      this.observerDataMap.delete(view);
      (_a = this.intersectionObserver) == null ? void 0 : _a.unobserve(view);
    }
    const newPlayDomList = streamInfo == null ? void 0 : streamInfo.playDomList.slice(0).filter((item) => item !== view);
    if (newPlayDomList.length > 0) {
      this.service.roomStore.updateStreamInfo({
        userId,
        streamType,
        playDomList: newPlayDomList
      });
      await this.doStartPlayVideo({
        userId,
        streamType,
        view: newPlayDomList
      });
    } else {
      this.service.roomStore.updateStreamInfo({
        userId,
        streamType,
        playDomList: []
      });
      await this.doStopPlayVideo(options);
    }
  }
  async doStopPlayVideo(options) {
    var _a, _b;
    const { userId, streamType } = options;
    this.service.roomStore.updateStreamInfo({
      userId,
      streamType,
      isLoading: false
    });
    if (userId === this.service.basicStore.userId && streamType === TUIRoomEngine.TUIVideoStreamType.kCameraStream) {
      (_a = this.service.roomEngine.instance) == null ? void 0 : _a.setLocalVideoView({ view: null });
    } else {
      await ((_b = this.service.roomEngine.instance) == null ? void 0 : _b.stopPlayRemoteVideo({
        userId,
        streamType
      }));
    }
  }
  onUserAudioStateChanged(eventInfo) {
    const { userId, hasAudio, reason } = eventInfo;
    if (userId === this.service.basicStore.userId && !hasAudio && reason === TUIRoomEngine.TUIChangeReason.kChangedByAdmin) {
      this.service.emit(types.EventType.ROOM_NOTICE_MESSAGE, {
        type: "warning",
        message: this.service.t("Your microphone has been turned off"),
        duration: message.MESSAGE_DURATION.NORMAL
      });
      this.service.roomStore.setCanControlSelfAudio(
        !this.service.roomStore.isMicrophoneDisableForAllUser
      );
    }
  }
  dispose() {
    this.intersectionObserver = null;
    this.observerDataMap = /* @__PURE__ */ new Map();
  }
  bindRoomEngineEvents() {
    TUIRoomEngine.once("ready", () => {
      var _a, _b;
      (_a = this.service.roomEngine.instance) == null ? void 0 : _a.on(
        TUIRoomEngine.TUIRoomEvents.onUserVideoStateChanged,
        this.onUserVideoStateChanged.bind(this)
      );
      (_b = this.service.roomEngine.instance) == null ? void 0 : _b.on(
        TUIRoomEngine.TUIRoomEvents.onUserAudioStateChanged,
        this.onUserAudioStateChanged.bind(this)
      );
    });
  }
  unbindRoomEngineEvents() {
    var _a, _b;
    (_a = this.service.roomEngine.instance) == null ? void 0 : _a.off(
      TUIRoomEngine.TUIRoomEvents.onUserVideoStateChanged,
      this.onUserVideoStateChanged
    );
    (_b = this.service.roomEngine.instance) == null ? void 0 : _b.off(
      TUIRoomEngine.TUIRoomEvents.onUserAudioStateChanged,
      this.onUserAudioStateChanged
    );
  }
}
exports.MediaManager = MediaManager;
