import { defineStore } from "pinia";
import { TUIVideoQuality, TUISeatMode, TUIVideoStreamType, TUIRole, TUIMediaDeviceType, TUIInvitationStatus } from "@tencentcloud/tuiroom-engine-js";
import { useBasicStore } from "./basic.mjs";
import { set, del } from "../utils/vue.mjs";
import { isMobile } from "../utils/environment.mjs";
function getNewStreamInfo(userId, streamType) {
  const newStreamInfo = {
    userId,
    hasAudioStream: false,
    hasVideoStream: false,
    streamType: streamType || TUIVideoStreamType.kCameraStream,
    isLoading: false,
    playDomList: []
  };
  return newStreamInfo;
}
function getNewUserInfo(userId) {
  const newUserInfo = {
    userId,
    userName: "",
    avatarUrl: "",
    nameCard: "",
    hasAudioStream: false,
    hasVideoStream: false,
    hasScreenStream: false,
    isMessageDisabled: false,
    userRole: TUIRole.kGeneralUser,
    onSeat: false,
    isUserApplyingToAnchor: false,
    isInvitingUserToAnchor: false,
    isInRoom: false,
    status: TUIInvitationStatus.kNone
  };
  return newUserInfo;
}
function getRecordStreamType(streamType) {
  if (streamType === TUIVideoStreamType.kCameraStreamLow) {
    return TUIVideoStreamType.kCameraStream;
  }
  return streamType;
}
function sortStreamList(streamList) {
  const basicStore = useBasicStore();
  return streamList.sort((item1, item2) => {
    if (item1.userId === basicStore.userId) {
      return -1;
    }
    if (item2.userId === basicStore.userId) {
      return 1;
    }
    if (item1.streamType === TUIVideoStreamType.kScreenStream) {
      return -1;
    }
    if (item2.streamType === TUIVideoStreamType.kScreenStream) {
      return 1;
    }
    return 0;
  });
}
const useRoomStore = defineStore("room", {
  state: () => ({
    userInfoObj: {},
    streamInfoObj: {},
    userVolumeObj: {},
    canControlSelfAudio: true,
    canControlSelfVideo: true,
    localVideoQuality: isMobile ? TUIVideoQuality.kVideoQuality_360p : TUIVideoQuality.kVideoQuality_720p,
    currentCameraId: "",
    currentMicrophoneId: "",
    currentSpeakerId: "",
    cameraList: [],
    microphoneList: [],
    speakerList: [],
    masterUserId: "",
    isMicrophoneDisableForAllUser: false,
    isCameraDisableForAllUser: false,
    isScreenShareDisableForAllUser: false,
    isSeatEnabled: void 0,
    seatMode: TUISeatMode.kFreeToTake,
    maxMembersCount: 5,
    // Includes local streams and screen shares, above which subsequent streams are played
    maxSeatCount: 20,
    password: "",
    roomName: "",
    // Visual area user flow list
    hasOtherScreenShare: false,
    isOnStateTabActive: true,
    isLocalUserSharing: false,
    isWhiteboardVisiable: false,
    isSharingScreen: false,
    isAnnotationVisiable: false
  }),
  getters: {
    localUser(state) {
      const basicStore = useBasicStore();
      return state.userInfoObj[basicStore.userId] || getNewUserInfo(basicStore.userId);
    },
    localStream(state) {
      const basicStore = useBasicStore();
      return state.streamInfoObj[`${basicStore.userId}_${TUIVideoStreamType.kCameraStream}`] || getNewStreamInfo(basicStore.userId, TUIVideoStreamType.kCameraStream);
    },
    localScreenStream(state) {
      const basicStore = useBasicStore();
      return state.streamInfoObj[`${basicStore.userId}_${TUIVideoStreamType.kScreenStream}`];
    },
    isMaster(state) {
      return this.localUser.userId === state.masterUserId;
    },
    isAdmin() {
      return this.localUser.userRole === TUIRole.kAdministrator;
    },
    isGeneralUser() {
      return this.localUser.userRole === TUIRole.kGeneralUser;
    },
    isFreeSpeakMode() {
      return this.isSeatEnabled === false;
    },
    isSpeakAfterTakingSeatMode() {
      return Boolean(this.isSeatEnabled) && this.seatMode === TUISeatMode.kApplyToTake;
    },
    // Whether the current user is on the stage
    isAnchor() {
      if (this.isFreeSpeakMode) {
        return true;
      }
      if (this.isSpeakAfterTakingSeatMode) {
        return this.localUser.onSeat;
      }
    },
    // Whether the current user is under the stage
    isAudience() {
      if (this.isFreeSpeakMode) {
        return false;
      }
      if (this.isSpeakAfterTakingSeatMode) {
        return !this.localUser.onSeat;
      }
    },
    isLocalAudioIconDisable() {
      const micForbidden = this.isGeneralUser && !this.canControlSelfAudio;
      return micForbidden || this.isAudience;
    },
    isLocalVideoIconDisable() {
      const cameraForbidden = this.isGeneralUser && !this.canControlSelfVideo;
      return cameraForbidden || this.isAudience;
    },
    streamList() {
      let streamList = [];
      if (this.isFreeSpeakMode) {
        streamList = Object.values(this.streamInfoObj);
      } else {
        streamList = Object.values(this.streamInfoObj).filter((item) => {
          return this.userInfoObj[item.userId].onSeat;
        });
      }
      return sortStreamList(streamList);
    },
    remoteStreamList() {
      const basicStore = useBasicStore();
      return this.streamList.filter((item) => item.userId !== basicStore.userId);
    },
    cameraStreamList() {
      return this.streamList.filter(
        (stream) => stream.streamType === TUIVideoStreamType.kCameraStream
      );
    },
    streamNumber() {
      return this.streamList.length;
    },
    userList() {
      const basicStore = useBasicStore();
      return [...Object.values(this.userInfoObj)].sort((item1, item2) => {
        if (item1.userId === basicStore.userId) {
          return -1;
        }
        if (item2.userId === basicStore.userId) {
          return 1;
        }
        if (item1.userRole === TUIRole.kRoomOwner) {
          return -1;
        }
        if (item2.userRole === TUIRole.kRoomOwner) {
          return 1;
        }
        if (item1.userRole === TUIRole.kAdministrator) {
          return -1;
        }
        if (item2.userRole === TUIRole.kAdministrator) {
          return 1;
        }
        return 0;
      });
    },
    userNumber() {
      return this.userList.filter((item) => item.isInRoom).length;
    },
    remoteUserList() {
      const basicStore = useBasicStore();
      return [...Object.values(this.userInfoObj)].filter(
        (item) => item.userId !== basicStore.userId
      );
    },
    remoteEnteredUserList() {
      return this.remoteUserList.filter((item) => item.isInRoom);
    },
    remoteNotEnteredUserList() {
      return this.userList.filter((item) => !item.isInRoom);
    },
    remoteAnchorList() {
      return this.remoteUserList.filter((item) => item.onSeat);
    },
    generalUserScreenStreamList() {
      return this.remoteUserList.filter(
        (item) => item.hasScreenStream && item.userRole === TUIRole.kGeneralUser
      );
    },
    anchorUserList() {
      return this.userList.filter((item) => item.onSeat);
    },
    applyToAnchorList() {
      return this.remoteUserList.filter((item) => item.isUserApplyingToAnchor).sort(
        (item1, item2) => ((item1 == null ? void 0 : item1.applyToAnchorTimestamp) || 0) - ((item2 == null ? void 0 : item2.applyToAnchorTimestamp) || 0)
      ) || [];
    },
    defaultStreamType() {
      return Object.values(this.streamInfoObj).filter(
        (stream) => stream.hasVideoStream
      ).length > this.maxMembersCount ? TUIVideoStreamType.kCameraStreamLow : TUIVideoStreamType.kCameraStream;
    },
    getDisplayName() {
      return (userId) => {
        const userInfo = this.userInfoObj[userId];
        if (userInfo) {
          const { nameCard, userName, userId: userId2 } = userInfo;
          return nameCard || userName || userId2;
        }
        return userId;
      };
    }
  },
  actions: {
    getUserName(userId) {
      var _a, _b;
      return ((_a = this.userInfoObj[userId]) == null ? void 0 : _a.nameCard) || ((_b = this.userInfoObj[userId]) == null ? void 0 : _b.userName) || userId;
    },
    getUserRole(userId) {
      var _a;
      return (_a = this.userInfoObj[userId]) == null ? void 0 : _a.userRole;
    },
    addUserInfo(userInfo) {
      const { userId } = userInfo;
      if (!userId) {
        return;
      }
      if (this.userInfoObj[userId]) {
        Object.assign(this.userInfoObj[userId], userInfo);
      } else {
        const newUserInfo = Object.assign(getNewUserInfo(userId), userInfo);
        set(this.userInfoObj, userId, newUserInfo);
      }
    },
    // todo: can use addUserInfo instead
    addRemoteUser(userInfo) {
      const { userId } = userInfo;
      const basicStore = useBasicStore();
      if (!userId || userId === basicStore.userId) {
        return;
      }
      if (this.userInfoObj[userId]) {
        Object.assign(this.userInfoObj[userId], userInfo, { isInRoom: true });
      } else {
        const newUserInfo = Object.assign(getNewUserInfo(userId), userInfo, {
          isInRoom: true
        });
        set(this.userInfoObj, userId, newUserInfo);
      }
    },
    updateUserInfo(userInfo) {
      if (!userInfo.userId) {
        return;
      }
      Object.assign(this.userInfoObj[userInfo.userId], userInfo);
    },
    removeUserInfo(userId) {
      const basicStore = useBasicStore();
      if (!userId || userId === basicStore.userId) {
        return;
      }
      if (this.userInfoObj[userId]) {
        del(this.userInfoObj, userId);
      }
    },
    addStreamInfo(userId, streamType) {
      const recordStreamType = getRecordStreamType(streamType);
      if (this.streamInfoObj[`${userId}_${recordStreamType}`]) {
        return;
      }
      const newStreamInfo = getNewStreamInfo(userId, recordStreamType);
      set(this.streamInfoObj, `${userId}_${recordStreamType}`, newStreamInfo);
    },
    updateStreamInfo(streamInfo) {
      const { userId, streamType } = streamInfo;
      const recordStreamType = getRecordStreamType(streamType);
      if (!this.streamInfoObj[`${userId}_${recordStreamType}`]) {
        return;
      }
      if (streamType !== recordStreamType) {
        Object.assign(streamInfo, { streamType: recordStreamType });
      }
      set(
        this.streamInfoObj,
        `${userId}_${recordStreamType}`,
        Object.assign(
          this.streamInfoObj[`${userId}_${recordStreamType}`],
          streamInfo
        )
      );
    },
    removeStreamInfo(userId, streamType) {
      const recordStreamType = getRecordStreamType(streamType);
      if (this.streamInfoObj[`${userId}_${recordStreamType}`]) {
        del(this.streamInfoObj, `${userId}_${recordStreamType}`);
      }
    },
    getStreamInfo(userId, streamType) {
      const recordStreamType = getRecordStreamType(streamType);
      if (this.streamInfoObj[`${userId}_${recordStreamType}`]) {
        return this.streamInfoObj[`${userId}_${recordStreamType}`];
      }
    },
    setAudioVolume(audioVolumeArray) {
      const basicStore = useBasicStore();
      audioVolumeArray.forEach((audioVolumeItem) => {
        let { userId } = audioVolumeItem;
        const { volume } = audioVolumeItem;
        if (userId === "") {
          userId = basicStore.userId;
        }
        set(this.userVolumeObj, userId, volume);
      });
    },
    setCurrentDeviceId(type, deviceId) {
      switch (type) {
        case TUIMediaDeviceType.kMediaDeviceTypeVideoCamera:
          this.setCurrentCameraId(deviceId);
          break;
        case TUIMediaDeviceType.kMediaDeviceTypeAudioInput:
          this.setCurrentMicrophoneId(deviceId);
          break;
        case TUIMediaDeviceType.kMediaDeviceTypeAudioOutput:
          this.setCurrentSpeakerId(deviceId);
          break;
      }
    },
    setCurrentCameraId(deviceId) {
      this.currentCameraId = deviceId;
    },
    setCurrentMicrophoneId(deviceId) {
      this.currentMicrophoneId = deviceId;
    },
    setCurrentSpeakerId(deviceId) {
      this.currentSpeakerId = deviceId;
    },
    setRoomInfo(roomInfo) {
      if (!roomInfo) return;
      const {
        roomOwner = this.masterUserId,
        isMicrophoneDisableForAllUser = this.isMicrophoneDisableForAllUser,
        isCameraDisableForAllUser = this.isCameraDisableForAllUser,
        isScreenShareDisableForAllUser = this.isScreenShareDisableForAllUser,
        isSeatEnabled = this.isSeatEnabled,
        seatMode = this.seatMode,
        maxSeatCount = this.maxSeatCount,
        password = this.password,
        roomName = this.roomName
      } = roomInfo;
      if (this.localUser.userId === roomOwner) {
        this.localUser.userRole = TUIRole.kRoomOwner;
      }
      this.masterUserId = roomOwner;
      this.isMicrophoneDisableForAllUser = isMicrophoneDisableForAllUser;
      this.isCameraDisableForAllUser = isCameraDisableForAllUser;
      this.isScreenShareDisableForAllUser = isScreenShareDisableForAllUser;
      this.isSeatEnabled = isSeatEnabled;
      this.seatMode = seatMode;
      this.maxSeatCount = maxSeatCount;
      this.password = password;
      this.roomName = roomName;
      this.canControlSelfAudio = !this.isMicrophoneDisableForAllUser;
      this.canControlSelfVideo = !this.isCameraDisableForAllUser;
    },
    setDisableMicrophoneForAllUserByAdmin(isDisable) {
      this.isMicrophoneDisableForAllUser = isDisable;
    },
    setDisableCameraForAllUserByAdmin(isDisable) {
      this.isCameraDisableForAllUser = isDisable;
    },
    setDisableScreenShareForAllUserByAdmin(isDisable) {
      this.isScreenShareDisableForAllUser = isDisable;
    },
    setMasterUserId(userId) {
      this.masterUserId = userId;
    },
    setCanControlSelfAudio(capability) {
      this.canControlSelfAudio = capability;
    },
    setCanControlSelfVideo(capability) {
      this.canControlSelfVideo = capability;
    },
    updateVideoQuality(quality) {
      this.localVideoQuality = quality;
    },
    setDeviceList(type, deviceList) {
      switch (type) {
        case TUIMediaDeviceType.kMediaDeviceTypeVideoCamera:
          this.setCameraList(deviceList);
          break;
        case TUIMediaDeviceType.kMediaDeviceTypeAudioInput:
          this.setMicrophoneList(deviceList);
          break;
        case TUIMediaDeviceType.kMediaDeviceTypeAudioOutput:
          this.setSpeakerList(deviceList);
          break;
      }
    },
    setCameraList(deviceList) {
      this.cameraList = deviceList;
      if (!this.currentCameraId && deviceList.length > 0) {
        this.setCurrentCameraId(deviceList[0].deviceId);
      }
    },
    setMicrophoneList(deviceList) {
      this.microphoneList = deviceList;
      if (!this.currentMicrophoneId && deviceList.length > 0) {
        this.setCurrentMicrophoneId(deviceList[0].deviceId);
      }
    },
    setSpeakerList(deviceList) {
      this.speakerList = deviceList;
      if (!this.currentSpeakerId && deviceList.length > 0) {
        this.setCurrentSpeakerId(deviceList[0].deviceId);
      }
    },
    // Moderator individually modifies the mute status of a user's outgoing text messages
    setMuteUserChat(userId, muted) {
      const remoteUserInfo = this.userInfoObj[userId];
      if (remoteUserInfo) {
        remoteUserInfo.isMessageDisabled = muted;
      }
    },
    setRemoteUserRole(userId, role) {
      const remoteUserInfo = this.userInfoObj[userId];
      if (remoteUserInfo) {
        remoteUserInfo.userRole = role;
      }
    },
    setRequestUserOpenMic(options) {
      const { userId, isRequesting, requestId } = options;
      const remoteUserInfo = this.userInfoObj[userId];
      if (remoteUserInfo) {
        remoteUserInfo.isRequestingUserOpenMic = isRequesting;
        remoteUserInfo.requestUserOpenMicRequestId = isRequesting ? requestId : "";
      }
    },
    setRequestUserOpenCamera(options) {
      const { userId, isRequesting, requestId } = options;
      const remoteUserInfo = this.userInfoObj[userId];
      if (remoteUserInfo) {
        remoteUserInfo.isRequestingUserOpenCamera = isRequesting;
        remoteUserInfo.requestUserOpenCameraRequestId = isRequesting ? requestId : "";
      }
    },
    addApplyToAnchorUser(options) {
      const { userId, requestId, timestamp } = options;
      const remoteUserInfo = this.userInfoObj[userId];
      if (remoteUserInfo) {
        remoteUserInfo.isUserApplyingToAnchor = true;
        remoteUserInfo.applyToAnchorRequestId = requestId;
        remoteUserInfo.applyToAnchorTimestamp = timestamp;
      }
    },
    removeApplyToAnchorUser(requestId) {
      const applyToAnchorItem = Object.values(this.userInfoObj).find(
        (item) => item.isUserApplyingToAnchor && item.applyToAnchorRequestId === requestId
      );
      if (applyToAnchorItem) {
        applyToAnchorItem.isUserApplyingToAnchor = false;
        applyToAnchorItem.applyToAnchorRequestId = "";
        applyToAnchorItem.applyToAnchorTimestamp = 0;
      }
    },
    addInviteToAnchorUser(options) {
      const { userId, requestId } = options;
      const remoteUserInfo = this.userInfoObj[userId];
      if (remoteUserInfo) {
        remoteUserInfo.isInvitingUserToAnchor = true;
        remoteUserInfo.inviteToAnchorRequestId = requestId;
      }
    },
    removeInviteToAnchorUser(userId) {
      const remoteUserInfo = this.userInfoObj[userId];
      if (remoteUserInfo) {
        remoteUserInfo.isInvitingUserToAnchor = false;
        remoteUserInfo.inviteToAnchorRequestId = "";
      }
    },
    setHasOtherScreenShare(hasScreenShare) {
      this.hasOtherScreenShare = hasScreenShare;
    },
    setOnStageTabStatus(isOnStateTabActive) {
      this.isOnStateTabActive = isOnStateTabActive;
    },
    updateInviteeList(userList) {
      userList.forEach((user) => {
        if (this.userInfoObj[user.userId]) {
          Object.assign(this.userInfoObj[user.userId], user);
        } else {
          const newUserInfo = Object.assign(getNewUserInfo(user.userId), user);
          set(this.userInfoObj, user.userId, newUserInfo);
        }
      });
    },
    reset() {
      const basicStore = useBasicStore();
      basicStore.setIsOpenMic(false);
      this.streamInfoObj = {};
      this.userInfoObj = {};
      this.userVolumeObj = {};
      this.canControlSelfAudio = true;
      this.canControlSelfVideo = true;
      this.localVideoQuality = TUIVideoQuality.kVideoQuality_720p;
      this.currentCameraId = "";
      this.currentMicrophoneId = "";
      this.currentSpeakerId = "";
      this.cameraList = [];
      this.microphoneList = [];
      this.speakerList = [];
      this.masterUserId = "";
      this.isMicrophoneDisableForAllUser = false;
      this.isCameraDisableForAllUser = false;
      this.isScreenShareDisableForAllUser = false;
      this.isSeatEnabled = void 0;
      this.seatMode = TUISeatMode.kFreeToTake;
      this.hasOtherScreenShare = false;
      this.isOnStateTabActive = true;
      this.maxSeatCount = 20;
      this.password = "";
      this.roomName = "";
      this.isLocalUserSharing = false;
      this.isWhiteboardVisiable = false;
      this.isSharingScreen = false;
      this.isAnnotationVisiable = false;
    }
  }
});
export {
  useRoomStore
};
