import { computed, onBeforeUnmount, watch } from "vue";
import TUIRoomEngine__default, { TUIRoomEvents, TUIRequestAction, TUIErrorCode, TUIRequestCallbackType } from "@tencentcloud/tuiroom-engine-js";
import useGetRoomEngine from "./useRoomEngine.mjs";
import renderMsg from "../components/common/base/Message/Message.mjs";
import { MESSAGE_DURATION } from "../constants/message.mjs";
import { useRoomStore } from "../stores/room.mjs";
import { storeToRefs } from "pinia";
import { useI18n } from "../locales/index.mjs";
import logger from "../utils/common/logger/index.mjs";
import { useBasicStore } from "../stores/basic.mjs";
import Notification from "../components/common/base/Notification/index.mjs";
import { isMobile } from "../utils/environment.mjs";
const roomEngine = useGetRoomEngine();
function useMasterApplyControl() {
  const roomStore = useRoomStore();
  const basicStore = useBasicStore();
  const { applyToAnchorList } = storeToRefs(roomStore);
  const { showApplyUserList } = storeToRefs(basicStore);
  const { t } = useI18n();
  let notification;
  const applyToAnchorUserIdList = computed(
    () => applyToAnchorList.value.map((item) => item.userId)
  );
  const applyToAnchorUserCount = computed(() => applyToAnchorList.value.length);
  function onRequestReceived(eventInfo) {
    const { requestAction, requestId, userId, timestamp } = eventInfo.request;
    if (requestAction === TUIRequestAction.kRequestToTakeSeat) {
      userId && roomStore.addApplyToAnchorUser({ userId, requestId, timestamp });
    }
  }
  function onRequestCancelled(eventInfo) {
    const { requestId } = eventInfo;
    roomStore.removeApplyToAnchorUser(requestId);
  }
  function onRequestProcessed(eventInfo) {
    const { requestId } = eventInfo;
    roomStore.removeApplyToAnchorUser(requestId);
  }
  async function handleUserApply(applyUserId, agree) {
    var _a;
    try {
      const userInfo = roomStore.userInfoObj[applyUserId];
      const requestId = userInfo.applyToAnchorRequestId;
      if (requestId) {
        await ((_a = roomEngine.instance) == null ? void 0 : _a.responseRemoteRequest({
          requestId,
          agree
        }));
        roomStore.removeApplyToAnchorUser(requestId);
      } else {
        logger.warn(
          "Failed to process the stage application. The data is abnormal. Please try again！",
          userInfo
        );
      }
    } catch (error) {
      if (error.code === TUIErrorCode.ERR_ALL_SEAT_OCCUPIED) {
        renderMsg({ type: "warning", message: t("The stage is full") });
      } else {
        logger.error("Failure to process a user request", error);
      }
    }
  }
  async function agreeUserOnStage(userInfo) {
    var _a;
    try {
      const requestId = userInfo.applyToAnchorRequestId;
      if (requestId) {
        await ((_a = roomEngine.instance) == null ? void 0 : _a.responseRemoteRequest({
          requestId,
          agree: true
        }));
        roomStore.removeApplyToAnchorUser(requestId);
      } else {
        logger.warn(
          "Failed to process the stage application. The data is abnormal. Please try again！",
          userInfo
        );
      }
    } catch (error) {
      if (error.code === TUIErrorCode.ERR_ALL_SEAT_OCCUPIED) {
        renderMsg({ type: "warning", message: t("The stage is full") });
      } else {
        logger.error("Failed application for consent to go on stage", error);
      }
    }
  }
  async function denyUserOnStage(userInfo) {
    var _a;
    const requestId = userInfo.applyToAnchorRequestId;
    if (requestId) {
      await ((_a = roomEngine.instance) == null ? void 0 : _a.responseRemoteRequest({
        requestId,
        agree: false
      }));
      roomStore.removeApplyToAnchorUser(requestId);
    } else {
      logger.warn(
        "Failed to process the stage application. The data is abnormal. Please try again！",
        userInfo
      );
    }
  }
  async function handleAllUserApply(isAgreeOrRejectAllUserApply) {
    var _a;
    let hasErrorOccurred = false;
    const applyUserList = applyToAnchorList.value.map((item) => ({
      userId: item.userId,
      userName: item.nameCard || item.userName,
      applyToAnchorRequestId: item.applyToAnchorRequestId
    }));
    for (const { applyToAnchorRequestId } of applyUserList) {
      const action = isAgreeOrRejectAllUserApply ? "Agree" : "Reject";
      const actionFailedMessage = `${action} sb on stage failed, please retry`;
      try {
        if (applyToAnchorRequestId) {
          await ((_a = roomEngine.instance) == null ? void 0 : _a.responseRemoteRequest({
            requestId: applyToAnchorRequestId,
            agree: isAgreeOrRejectAllUserApply
          }));
          roomStore.removeApplyToAnchorUser(applyToAnchorRequestId);
        }
      } catch (error) {
        if (!hasErrorOccurred) {
          logger.error(actionFailedMessage);
          renderMsg({
            type: "warning",
            message: t("The stage is full"),
            duration: MESSAGE_DURATION.NORMAL
          });
          hasErrorOccurred = true;
        }
      }
    }
  }
  TUIRoomEngine__default.once("ready", () => {
    var _a, _b, _c;
    (_a = roomEngine.instance) == null ? void 0 : _a.on(TUIRoomEvents.onRequestReceived, onRequestReceived);
    (_b = roomEngine.instance) == null ? void 0 : _b.on(
      TUIRoomEvents.onRequestCancelled,
      onRequestCancelled
    );
    (_c = roomEngine.instance) == null ? void 0 : _c.on(
      TUIRoomEvents.onRequestProcessed,
      onRequestProcessed
    );
  });
  onBeforeUnmount(() => {
    var _a, _b, _c;
    (_a = roomEngine.instance) == null ? void 0 : _a.off(
      TUIRoomEvents.onRequestReceived,
      onRequestReceived
    );
    (_b = roomEngine.instance) == null ? void 0 : _b.off(
      TUIRoomEvents.onRequestCancelled,
      onRequestCancelled
    );
    (_c = roomEngine.instance) == null ? void 0 : _c.off(
      TUIRoomEvents.onRequestProcessed,
      onRequestProcessed
    );
  });
  async function inviteUserOnStage(userInfo) {
    var _a;
    const { userId } = userInfo;
    const request = await ((_a = roomEngine.instance) == null ? void 0 : _a.takeUserOnSeatByAdmin({
      seatIndex: -1,
      userId,
      timeout: 60,
      requestCallback: (callbackInfo) => {
        const { requestCallbackType, userId: userId2, code } = callbackInfo;
        const userName = roomStore.getUserName(userId2);
        roomStore.removeInviteToAnchorUser(userId2);
        switch (requestCallbackType) {
          case TUIRequestCallbackType.kRequestAccepted:
            renderMsg({
              type: "success",
              message: `${userName || userId2} ${t("accepted the invitation to the stage")}`,
              duration: MESSAGE_DURATION.NORMAL
            });
            break;
          case TUIRequestCallbackType.kRequestRejected:
            renderMsg({
              type: "warning",
              message: `${userName || userId2} ${t("declined the invitation to the stage")}`,
              duration: MESSAGE_DURATION.NORMAL
            });
            break;
          case TUIRequestCallbackType.kRequestTimeout:
            renderMsg({
              type: "warning",
              message: t("The invitation to sb to go on stage has timed out", {
                name: userName || userId2
              }),
              duration: MESSAGE_DURATION.NORMAL
            });
            break;
          case TUIRequestCallbackType.kRequestError:
            if (code === TUIErrorCode.ERR_REQUEST_ID_REPEAT) {
              renderMsg({
                type: "warning",
                message: t(
                  "This member has already received the same request, please try again later"
                ),
                duration: MESSAGE_DURATION.NORMAL
              });
            }
            break;
        }
      }
    }));
    if (request && request.requestId) {
      roomStore.addInviteToAnchorUser({ userId, requestId: request.requestId });
    }
  }
  function cancelInviteUserOnStage(userInfo) {
    var _a;
    const { userId, inviteToAnchorRequestId } = userInfo;
    roomStore.removeInviteToAnchorUser(userId);
    if (inviteToAnchorRequestId) {
      (_a = roomEngine.instance) == null ? void 0 : _a.cancelRequest({
        requestId: inviteToAnchorRequestId
      });
    }
  }
  function kickUserOffStage(userInfo) {
    var _a;
    (_a = roomEngine.instance) == null ? void 0 : _a.kickUserOffSeatByAdmin({
      seatIndex: -1,
      userId: userInfo.userId
    });
  }
  const handleConfirm = async (onlyOneUserTakeStage, userId) => {
    if (isMobile) {
      basicStore.setSidebarOpenStatus(true);
      basicStore.setSidebarName("apply");
    } else {
      if (onlyOneUserTakeStage) {
        handleUserApply(userId, true);
      } else {
        basicStore.setShowApplyUserList(true);
      }
    }
  };
  const handleCancel = async (onlyOneUserTakeStage, userId) => {
    if (!isMobile && onlyOneUserTakeStage) {
      handleUserApply(userId, false);
    }
  };
  function hideApplyList() {
    basicStore.setShowApplyUserList(false);
  }
  function handleShowNotification() {
    watch(applyToAnchorUserIdList, (newVal, oldVal) => {
      var _a, _b, _c;
      if (newVal.length === oldVal.length && newVal === oldVal) {
        return;
      }
      if (newVal.length === 0) {
        notification && notification.close();
        notification = null;
        return;
      }
      const onlyOneUserTakeStage = newVal.length === 1;
      const firstUser = applyToAnchorList.value[0];
      const lastIndex = applyToAnchorList.value.length - 1;
      const userName = ((_a = applyToAnchorList.value[lastIndex]) == null ? void 0 : _a.nameCard) || ((_b = applyToAnchorList.value[lastIndex]) == null ? void 0 : _b.userName) || ((_c = applyToAnchorList.value[lastIndex]) == null ? void 0 : _c.userId);
      const message = onlyOneUserTakeStage ? `${userName} ${t("Applying for the stage")}` : `${userName} ${t("and so on number people applying to stage", { number: applyToAnchorList.value.length })}`;
      const confirmButtonText = isMobile ? t("Check") : onlyOneUserTakeStage ? t("Agree to the stage") : t("Check");
      const cancelButtonText = isMobile ? void 0 : onlyOneUserTakeStage ? t("Reject") : t("Neglect");
      const confirm = () => handleConfirm(onlyOneUserTakeStage, firstUser == null ? void 0 : firstUser.userId);
      const cancel = () => handleCancel(onlyOneUserTakeStage, firstUser == null ? void 0 : firstUser.userId);
      notification = Notification({
        message,
        confirmButtonText,
        cancelButtonText,
        confirm,
        cancel
      });
    });
  }
  return {
    t,
    roomStore,
    showApplyUserList,
    hideApplyList,
    applyToAnchorUserCount,
    applyToAnchorList,
    // Process the user's application for accessing the stage (agree/reject)
    handleUserApply,
    // Allow ordinary users to take the stage
    agreeUserOnStage,
    // Reject ordinary users to take the stage
    denyUserOnStage,
    // Invite users to the stage
    inviteUserOnStage,
    // Cancel invite users to the stage
    cancelInviteUserOnStage,
    // Kick the user off the stage
    kickUserOffStage,
    // Handle all user requests
    handleAllUserApply,
    handleShowNotification
  };
}
export {
  useMasterApplyControl as default
};
