/*
 * Copyright (c) 2020 WildFireChat. All rights reserved.
 */

import EventType from "../../client/wfcEvent";
import { BrowserWindow, ipcRenderer, isElectron, remote } from "../../../platform";
import ConversationType from "../../model/conversationType";
import MessageContentType from "../../messages/messageContentType";
import wfc from "../../client/wfc";
import MessageConfig from "../../client/messageConfig";
import DetectRTC from "detectrtc";
import Config from "../../../config";
import { longValue, numberValue } from "../../util/longUtil";
import Conversation from "../../../wfc/model/conversation";
import CallEndReason from "./callEndReason";
import CallByeMessageContent from "../messages/callByeMessageContent";

// main window renderer process -> voip window renderer process
// voip window renderer process -> main process -> main window renderer process
export class AvEngineKitProxy {
  wfc;
  queueEvents = [];
  callWin;
  type;

  conference = false;
  conversation;
  callId;
  inviteMessageUid;
  participants = [];
  isSupportVoip = false;
  hasMicrophone = false;
  hasSpeaker = false;
  hasWebcam = false;

  /**
   * 无法正常弹出音视频通话窗口是的回调
   * 回到参数说明：-1，有音视频通话正在进行中；-2，设备不支持音视频通话，可能原因是不支持webrtc，没有摄像头或麦克风等
   * @type {(Number) => {}}
   */
  onVoipCallErrorCallback;

  /**
   * 音视频通话通话状态回调
   */
  onVoipCallStatusCallback = (covnersation, ongonging) => {};

  /**
   * 应用初始化的时候调用
   * @param wfc
   */
  setup(wfc) {
    if (this.wfc === wfc) {
      console.log("re-setup, just ignore");
      return;
    }
    this.wfc = wfc;
    DetectRTC.load(() => {
      this.isSupportVoip = DetectRTC.isWebRTCSupported;
      this.hasMicrophone = DetectRTC.hasMicrophone;
      // Safari 14.0 版本，hasSpeakers一直为false，先全部置为true
      //this.hasSpeaker = DetectRTC.hasSpeakers;
      this.hasSpeaker = true;
      this.hasWebcam = DetectRTC.hasWebcam;
      console.log(
        `detectRTC, isWebRTCSupported: ${DetectRTC.isWebRTCSupported}, hasWebcam: ${DetectRTC.hasWebcam}, hasSpeakers: ${DetectRTC.hasSpeakers}, hasMicrophone: ${DetectRTC.hasMicrophone}`,
        this.isSupportVoip
      );
    });
    this.event = wfc.eventEmitter;
    this.event.on(EventType.ReceiveMessage, this.onReceiveMessage);
    this.event.on(EventType.ConferenceEvent, this.onReceiveConferenceEvent);
    this.event.on(EventType.ConnectionStatusChanged, this.onConnectionStatusChange);
    if (!isElectron()) {
      const EventEmitter = require("events").EventEmitter;
      this.events = new EventEmitter();
      this.events.on("voip-message", this.sendVoipListener);
      this.events.on("conference-request", this.sendConferenceRequestListener);
      this.events.on("update-call-start-message", this.updateCallStartMessageContentListener);
    }
  }

  updateCallStartMessageContentListener = (event, message) => {
    let messageUid = message.messageUid;
    let content = message.content;

    let msg = wfc.getMessageByUid(messageUid);
    let orgContent = msg.messageContent;
    orgContent.connectTime = content.connectTime ? content.connectTime : orgContent.connectTime;
    orgContent.endTime = content.endTime ? content.endTime : orgContent.endTime;
    orgContent.status = content.status;
    orgContent.audioOnly = content.audioOnly;
    wfc.updateMessageContent(msg.messageId, orgContent);
  };

  sendConferenceRequestListener = (event, request) => {
    console.log("to send conference request", request);
    wfc.sendConferenceRequestEx(
      request.sessionId ? request.sessionId : 0,
      request.roomId ? request.roomId : "",
      request.request,
      request.data,
      request.advance,
      (errorCode, res) => {
        this.emitToVoip("sendConferenceRequestResult", {
          error: errorCode,
          sendConferenceRequestId: request.sendConferenceRequestId,
          response: res,
        });
      }
    );
  };

  // 发送消息时，返回的timestamp，已经过修正，后面使用时,不用考虑和服务器的时间差
  sendVoipListener = (event, msg) => {
    let contentClazz = MessageConfig.getMessageContentClazz(msg.content.type);

    let content = new contentClazz();
    content.decode(msg.content);
    console.log("to send voip message", content.type, content.callId, content);
    let delta = wfc.getServerDeltaTime();
    if (content.type === MessageContentType.VOIP_CONTENT_TYPE_ADD_PARTICIPANT) {
      this.participants.push(content.participants);
    } else if (content.type === MessageContentType.VOIP_CONTENT_TYPE_END) {
      console.log("to send end message", content.reason, content);
      this.conversation = null;
      this.queueEvents = [];
      this.callId = null;
      this.inviteMessageUid = null;
      this.participants = [];
      // 仅仅为了通知proxy，其他端已经接听电话了，关闭窗口时，不应当发送挂断信令
      if (!content.callId) {
        return;
      }
    }
    let conversation = new Conversation(msg.conversation.type, msg.conversation.target, msg.conversation.line);
    wfc.sendConversationMessage(
      conversation,
      content,
      msg.toUsers,
      (messageId, timestamp) => {
        // do nothing
      },
      (uploaded, total) => {
        // do nothing
      },
      (messageUid, timestamp) => {
        this.emitToVoip("sendMessageResult", {
          error: 0,
          sendMessageId: msg.sendMessageId,
          messageUid: messageUid,
          timestamp: longValue(numberValue(timestamp) - delta),
        });
        if (content.type === MessageContentType.VOIP_CONTENT_TYPE_START) {
          this.inviteMessageUid = messageUid;
        }
      },
      (errorCode) => {
        this.emitToVoip("sendMessageResult", { error: errorCode, sendMessageId: msg.sendMessageId });
      }
    );
  };

  onReceiveConferenceEvent = (event) => {
    this.emitToVoip("conferenceEvent", event);
  };

  onConnectionStatusChange = (status) => {
    this.emitToVoip("connectionStatus", status);
  };
  // 收到消息时，timestamp已经过修正，后面使用时，不用考虑和服务器的时间差
  onReceiveMessage = (msg) => {
    if (!Config.ENABLE_MULTI_VOIP_CALL && msg.conversation.type === ConversationType.Group) {
      console.log("not enable multi call ");
      return;
    }
    if (!Config.ENABLE_SINGLE_VOIP_CALL && msg.conversation.type === ConversationType.Single) {
      console.log("not enable multi call ");
      return;
    }
    let now = new Date().valueOf();
    let delta = wfc.getServerDeltaTime();
    if (now - (numberValue(msg.timestamp) - delta) >= 90 * 1000) {
      // 消息已失效，不做处理
      return;
    }
    let content = msg.messageContent;
    if (this.callWin && this.conference && content.type !== MessageContentType.CONFERENCE_CONTENT_TYPE_COMMAND) {
      console.log("in conference, ignore all other msg");
      return;
    }
    if (
      msg.direction === 1 &&
      (content.type === MessageContentType.VOIP_CONTENT_TYPE_START ||
        content.type === MessageContentType.VOIP_CONTENT_TYPE_ADD_PARTICIPANT)
    ) {
      if (this.callWin) {
        if (
          content.type === MessageContentType.VOIP_CONTENT_TYPE_START ||
          (content.type === MessageContentType.VOIP_CONTENT_TYPE_ADD_PARTICIPANT &&
            content.participants.indexOf(wfc.getUserId()) >= 0)
        ) {
          // 已在音视频通话中，其他的音视频通话，又邀请自己，这儿是只是让主界面提示一下，拒绝逻辑在 engine 里面
          this.onVoipCallErrorCallback && this.onVoipCallErrorCallback(-1);
        }
      }
      if (!this.isSupportVoip || !this.hasMicrophone || !this.hasSpeaker) {
        this.onVoipCallErrorCallback && this.onVoipCallErrorCallback(-2);
        return;
      }
    }

    if (
      msg.conversation.type === ConversationType.Single ||
      msg.conversation.type === ConversationType.Group ||
      (this.conference && msg.conversation.type === ConversationType.ChatRoom)
    ) {
      if (
        content.type === MessageContentType.VOIP_CONTENT_TYPE_START ||
        content.type === MessageContentType.VOIP_CONTENT_TYPE_END ||
        content.type === MessageContentType.VOIP_CONTENT_TYPE_ACCEPT ||
        content.type === MessageContentType.VOIP_CONTENT_TYPE_SIGNAL ||
        content.type === MessageContentType.VOIP_CONTENT_TYPE_MODIFY ||
        content.type === MessageContentType.VOIP_CONTENT_TYPE_ACCEPT_T ||
        content.type === MessageContentType.VOIP_CONTENT_TYPE_ADD_PARTICIPANT ||
        content.type === MessageContentType.VOIP_CONTENT_TYPE_MUTE_VIDEO ||
        content.type === MessageContentType.VOIP_Join_Call_Request ||
        content.type === MessageContentType.CONFERENCE_CONTENT_TYPE_KICKOFF_MEMBER ||
        content.type === MessageContentType.CONFERENCE_CONTENT_TYPE_CHANGE_MODE ||
        content.type === MessageContentType.CONFERENCE_CONTENT_TYPE_COMMAND
      ) {
        console.log("receive voip message", msg.messageContent.type, msg.messageContent.callId, msg.messageUid.toString(), msg);
        if (
          msg.direction === 0 &&
          content.type !== MessageContentType.VOIP_CONTENT_TYPE_END &&
          content.type !== MessageContentType.VOIP_CONTENT_TYPE_ACCEPT &&
          content.type !== MessageContentType.VOIP_CONTENT_TYPE_ACCEPT
        ) {
          return;
        }

        let participantUserInfos = [];
        let selfUserInfo = wfc.getUserInfo(wfc.getUserId());
        if (content.type === MessageContentType.VOIP_CONTENT_TYPE_START) {
          this.conversation = msg.conversation;
          this.callId = content.callId;
          this.inviteMessageUid = msg.messageUid;
          this.participants.push(...content.targetIds);
          this.participants.push(msg.from);
          // 参与者不包含自己
          this.participants = this.participants.filter((uid) => uid !== selfUserInfo.uid);

          if (msg.conversation.type === ConversationType.Single) {
            participantUserInfos = [wfc.getUserInfo(msg.from)];
          } else {
            let targetIds = content.targetIds.filter((id) => id !== selfUserInfo.uid);
            targetIds.push(msg.from);
            participantUserInfos = wfc.getUserInfos(targetIds, msg.conversation.target);
          }
          if (!this.callWin) {
            setTimeout(() => {
              if (this.conversation) {
                this.showCallUI(msg.conversation, false, {
                  event: "message",
                  args: msg,
                });
              } else {
                console.log("call ended");
              }
            }, 200);
          }
        } else if (content.type === MessageContentType.VOIP_CONTENT_TYPE_ADD_PARTICIPANT) {
          let participantIds = [...content.participants];
          if (content.existParticipants) {
            content.existParticipants.forEach((p) => {
              participantIds.push(p.userId);
            });
          }

          this.conversation = msg.conversation;
          this.callId = content.callId;
          this.inviteMessageUid = msg.messageUid;
          this.participants.push(...participantIds);

          participantIds = participantIds.filter((u) => u.uid !== selfUserInfo.uid);
          participantUserInfos = wfc.getUserInfos(participantIds, msg.conversation.target);

          if (!this.callWin && content.participants.indexOf(selfUserInfo.uid) > -1) {
            setTimeout(() => {
              if (this.conversation) {
                this.showCallUI(msg.conversation, false, {
                  event: "message",
                  args: msg,
                });
              } else {
                console.log("call ended");
              }
            }, 200);
          }
        } else if (content.type === MessageContentType.VOIP_CONTENT_TYPE_END) {
          if (content.callId !== this.callId) {
            return;
          }
        }

        if (
          msg.conversation.type === ConversationType.Group &&
          (content.type === MessageContentType.VOIP_CONTENT_TYPE_START ||
            content.type === MessageContentType.VOIP_CONTENT_TYPE_ADD_PARTICIPANT)
        ) {
          let memberIds = wfc.getGroupMemberIds(msg.conversation.target);
          msg.groupMemberUserInfos = wfc.getUserInfos(memberIds, msg.conversation.target);
        }

        msg.participantUserInfos = participantUserInfos;
        msg.selfUserInfo = selfUserInfo;
        msg.timestamp = longValue(numberValue(msg.timestamp) - delta);
        if (this.callWin) {
          this.emitToVoip("message", msg);
        }
      }
    }
  };

  emitToVoip(event, args) {
    console.log("emitToVoip", event, args);
    if (isElectron()) {
      // renderer/main to renderer
      if (this.callWin) {
        // fix object of long.js can be send inter-process
        args = JSON.stringify(args);
        this.callWin.webContents.send(event, args);
      } else if (this.queueEvents) {
        this.queueEvents.push({ event, args });
      }
    } else {
      if (this.events) {
        this.events.emit(event, event, args);
      } else if (this.queueEvents) {
        this.queueEvents.push({ event, args });
      }
    }
  }

  emitToMain(event, args) {
    console.log("emit to main", event, args);
    if (isElectron()) {
      // renderer to main
      ipcRenderer.send(event, args);
    } else {
      this.events.emit(event, event, args);
    }
  }

  listenVoipEvent = (event, listener) => {
    console.log("listenVoipEvent ", event, listener);
    if (isElectron()) {
      // listen for event from renderer
      ipcRenderer.on(event, listener);
    } else {
      this.events.on(event, listener);
    }
  };

  /**
   * 发起音视频通话
   * @param {Conversation} conversation 会话
   * @param {Boolean} audioOnly 是否是音频通话
   * @param {[String]} participants 参与者用户id列表
   * @param {string} callExtra 通话附加信息，会议版有效
   */
  startCall(conversation, audioOnly, participants, callExtra = "") {
    if (this.callWin) {
      console.log("voip call is ongoing");
      this.onVoipCallErrorCallback && this.onVoipCallErrorCallback(-1);
      return;
    }
    console.log(
      `startCall speaker、microphone、webcam检测结果分别为：${this.hasSpeaker} , ${this.hasMicrophone}, ${this.hasWebcam}，如果不全为true，请检查硬件设备是否正常，否则通话可能存在异常`
    );
    if (!this.isSupportVoip || !this.hasSpeaker || !this.hasMicrophone) {
      console.log("not support voip", this.isSupportVoip, this.hasSpeaker, this.hasMicrophone, this.hasWebcam);
      this.onVoipCallErrorCallback && this.onVoipCallErrorCallback(-2);
      return;
    }

    let selfUserInfo = wfc.getUserInfo(wfc.getUserId());
    participants = participants.filter((uid) => uid !== selfUserInfo.uid);
    let callId = conversation.target + Math.floor(Math.random() * 10000);
    this.conversation = conversation;
    this.participants.push(...participants);
    this.callId = callId;

    let participantUserInfos = wfc.getUserInfos(participants);
    let groupMemberUserInfos;
    if (conversation.type === ConversationType.Group) {
      let memberIds = wfc.getGroupMemberIds(conversation.target);
      groupMemberUserInfos = wfc.getUserInfos(memberIds, conversation.target);
    }
    delete conversation._target;
    this.showCallUI(conversation, false, {
      event: "startCall",
      args: {
        conversation: conversation,
        audioOnly: audioOnly,
        callId: callId,
        selfUserInfo: selfUserInfo,
        groupMemberUserInfos: groupMemberUserInfos,
        participantUserInfos: participantUserInfos,
        callExtra: callExtra,
      },
    });
  }

  /**
   * 开始会议
   * @param {string} callId 会议id
   * @param {boolean} audioOnly 是否仅仅开启音频; true，音频会议；false，视频会议
   * @param {string} pin 入会pin码
   * @param {string} host 主持人用户id
   * @param {string} title 会议标题
   * @param {string} desc 会议描述
   * @param {boolean} audience 其他人加入会议时，是否默认为观众；true，默认为观众；false，默认为互动者
   * @param {boolean} advance 是否为高级会议，当预计参与人员很多的时候，开需要开启超级会议
   * @param {boolean} record 是否开启服务端录制
   * @param {Object} extra 一些额外信息，主要用于将信息传到音视频通话窗口，会议的其他参与者，无法看到该附加信息
   * @param {Object} callExtra  通话附件信息，会议的所有参与者都能看到该附加信息
   * @param {boolean} muteAudio 是否是静音加入会议
   * @param {boolean} muteVideo 是否是关闭摄像头加入会议
   */
  startConference(
    callId,
    audioOnly,
    pin,
    host,
    title,
    desc,
    audience,
    advance,
    record = false,
    extra,
    callExtra,
    muteAudio = false,
    muteVideo = false
  ) {
    if (this.callWin) {
      console.log("voip call is ongoing");
      this.onVoipCallErrorCallback && this.onVoipCallErrorCallback(-1);
      return;
    }
    if (!this.isSupportVoip || !this.hasSpeaker || !this.hasMicrophone) {
      console.log("not support voip", this.isSupportVoip, this.hasSpeaker);
      this.onVoipCallErrorCallback && this.onVoipCallErrorCallback(-2);
      return;
    }

    callId = callId ? callId : wfc.getUserId() + Math.floor(Math.random() * 10000);
    this.callId = callId; // !!！显示弹框
    this.conversation = null;
    this.conference = true;

    wfc.joinChatroom(
      callId,
      () => {
        console.log("join conference chatRoom success", callId);
      },
      (err) => {
        console.error("join conference chatRoom fail", callId, err);
      }
    );

    let selfUserInfo = wfc.getUserInfo(wfc.getUserId());
    this.showCallUI(null, true, {
      event: "startConference",
      args: {
        audioOnly: audioOnly,
        callId: callId,
        pin: pin ? pin : Math.ceil(Math.random() * 1000000) + "",
        host: host,
        title: title,
        desc: desc,
        audience: audience,
        advance: advance,
        record: record,
        selfUserInfo: selfUserInfo,
        extra: extra,
        callExtra: callExtra,
        muteAudio: muteAudio,
        muteVideo: muteVideo,
      },
    });
  }

  /**
   * 加入会议
   * @param {string} callId 会议id
   * @param {string} audioOnly 是否只开启音频
   * @param {string} pin 会议pin码
   * @param {string} host 会议主持人
   * @param {string} title 会议标题
   * @param {string} desc 会议描述
   * @param {boolean} audience 是否是以观众角色入会
   * @param {string} advance 是否是高级会议
   * @param {boolean} muteAudio 是否是静音加入会议
   * @param {boolean} muteVideo 是否是关闭摄像头加入会议
   * @param {Object} extra 一些额外信息，主要用于将信息传到音视频通话窗口
   * @param {Object} callExtra 通话附加信息，会议的所有参与者都能看到该附加信息
   */
  joinConference(
    callId,
    audioOnly,
    pin,
    host,
    title,
    desc,
    audience,
    advance,
    muteAudio,
    muteVideo,
    extra = null,
    callExtra = null
  ) {
    if (this.callWin) {
      console.log("voip call is ongoing");
      this.onVoipCallErrorCallback && this.onVoipCallErrorCallback(-1);
      return;
    }
    if (!this.isSupportVoip || !this.hasSpeaker || !this.hasMicrophone) {
      console.log("not support voip", this.isSupportVoip, this.hasSpeaker, this.hasMicrophone);
      this.onVoipCallErrorCallback && this.onVoipCallErrorCallback(-2);
      return;
    }

    this.conversation = null;
    this.conference = true;
    this.callId = callId;

    wfc.joinChatroom(
      callId,
      () => {
        console.log("join conference chatRoom success", callId);
      },
      (err) => {
        console.error("join conference chatRoom fail", callId, err);
      }
    );
    let selfUserInfo = wfc.getUserInfo(wfc.getUserId());
    this.showCallUI(null, true, {
      event: "joinConference",
      args: {
        audioOnly: audioOnly,
        callId: callId,
        pin: pin,
        host: host,
        title: title,
        desc: desc,
        audience: audience,
        advance: advance,
        muteAudio: muteAudio,
        muteVideo: muteVideo,
        selfUserInfo: selfUserInfo,
        extra: extra,
        callExtra: callExtra,
      },
    });
  }

  showCallUI(conversation, isConference, options) {
    let type = isConference ? "conference" : conversation.type === ConversationType.Single ? "single" : "multi";
    this.type = type;

    let width = 360;
    let height = 640;
    let minWidth = 360;
    let minHeight = 640;
    switch (type) {
      case "single":
        width = 360;
        height = 640;
        break;
      case "multi":
      case "conference":
        width = 960;
        height = 600;
        minWidth = 800;
        minHeight = 480;
        break;
      default:
        break;
    }
    if (isElectron()) {
      let win = new BrowserWindow({
        width: width,
        height: height,
        minWidth: minWidth,
        minHeight: minHeight,
        resizable: true,
        maximizable: true,
        transparent: !!isConference,
        frame: !isConference,
        webPreferences: {
          scrollBounce: false,
          nativeWindowOpen: true,
          nodeIntegration: true,
          contextIsolation: false,
        },
      });
      // const remoteMain = require("@electron/remote").require("@electron/remote/main");
      const remoteMain = remote.require("@electron/remote/main");
      remoteMain.enable(win.webContents);

      win.webContents.on("did-finish-load", () => {
        this.onVoipWindowReady(win);
      });

      if (localStorage.getItem("enable_voip_debug")) {
        win.webContents.openDevTools();
      }
      win.on("close", () => {
        this.onVoipWindowClose();
      });

      // win.loadURL(path.join('file://', AppPath, 'src/index.html?' + type));
      let hash = window.location.hash;
      let url = window.location.origin;
      if (hash) {
        url = window.location.href.replace(hash, "#/voip");
      } else {
        url += "/voip";
      }
      url += "/" + type + "?t=" + new Date().getTime();
      win.loadURL(url);
      console.log("voip windows url", url);
      win.show();
      win.removeMenu();

      this.emitToVoip(options.event, options.args);
    } else {
      this.callWin = window;
      console.log("windowEmitter subscribe events");
      this.events.once("close-voip-div", () => {
        this.onVoipCallStatusCallback && this.conversation && this.onVoipCallStatusCallback(this.conversation, false);
        this.callWin = null;
        this.conference = null;
        this.callId = null; // !!!关闭弹框
        this.conversation = null;
      });
      // 等 voip view mounted
      setTimeout(() => {
        this.emitToVoip(options.event, options.args);
      }, 200);
      this.onVoipCallStatusCallback && this.conversation && this.onVoipCallStatusCallback(this.conversation, true);
    }
  }

  onVoipWindowClose = (event) => {
    if (event && event.srcElement && event.srcElement.URL === "about:blank") {
      // fix safari bug: safari 浏览器，页面刚打开的时候，也会走到这个地方
      return;
    }
    // 让voip内部先处理关闭事件，内部处理时，可能还需要发消息
    console.log("onVoipWindowClose");
    if (!this.callWin) {
      return;
    }
    if (!isElectron()) {
      this.callWin.removeEventListener("beforeunload", this.onVoipWindowClose);
      this.callWin.removeEventListener("unload", this.onVoipWindowClose);
    }
    setTimeout(() => {
      this.onVoipCallStatusCallback && this.onVoipCallStatusCallback(this.conversation, false);
      this.conversation = null;
      this.queueEvents = [];
      if (this.conference) {
        wfc.quitChatroom(this.callId);
        this.conference = false;
      }
      this.callId = null;
      this.participants = [];
      this.queueEvents = [];
      this.callWin = null;
      this.voipEventRemoveAllListeners("voip-message", "conference-request", "update-call-start-message", "start-screen-share");
    }, 2000);
  };

  onVoipWindowReady(win) {
    if (!this.callId) {
      return;
    }
    this.callWin = win;
    console.log("onVoipWindowReady", this.onVoipCallStatusCallback);
    this.onVoipCallStatusCallback && this.onVoipCallStatusCallback(this.conversation, true);
    if (!isElectron()) {
      // 启动页面的时候就监听，不然太慢了，会丢事件
    } else {
      console.log("ipcRenderer subscribe events");
      ipcRenderer.on("voip-message", this.sendVoipListener);
      ipcRenderer.on("conference-request", this.sendConferenceRequestListener);
      ipcRenderer.on("update-call-start-message", this.updateCallStartMessageContentListener);
      ipcRenderer.on(/*IPCEventType.START_SCREEN_SHARE*/ "start-screen-share", (event, args) => {
        if (this.callWin) {
          let screenWidth = args.width;
          this.callWin.resizable = true;
          this.callWin.closable = true;
          this.callWin.maximizable = false;
          this.callWin.transparent = true;
          this.callWin.setMinimumSize(800, 800);
          this.callWin.setSize(800, 800);
          // console.log('screen width', screen, screen.width);
          this.callWin.setPosition((screenWidth - 800) / 2, 0, true);
        }
      });
      ipcRenderer.on(/*IPCEventType.STOP_SCREEN_SHARE*/ "stop-screen-share", (event, args) => {
        if (this.callWin) {
          let type = args.type;
          let width = 360;
          let height = 640;
          switch (type) {
            case "single":
              width = 360;
              height = 640;
              break;
            case "multi":
            case "conference":
              width = 1024;
              height = 800;
              break;
            default:
              break;
          }
          this.callWin.resizable = true;
          this.callWin.closable = true;
          this.callWin.maximizable = true;
          this.callWin.setMinimumSize(width, height);
          this.callWin.setSize(width, height);
          this.callWin.center();
        }
      });
    }
    if (this.queueEvents.length > 0) {
      this.queueEvents.forEach((eventArgs) => {
        console.log("process queued event", eventArgs);
        this.emitToVoip(eventArgs.event, eventArgs.args);
      });
    }
  }

  voipEventRemoveAllListeners(...events) {
    if (isElectron()) {
      // renderer
      events.forEach((e) => ipcRenderer.removeAllListeners(e));
    }
  }

  forceCloseVoipWindow() {
    if (isElectron() && this.callWin) {
      this.callWin.close();
    }
    this.callId = null;
    this.callWin = null;
  }

  // 仅 web 端，单人、多人通话有效
  forceCloseVoipWindowAndHangup() {
    if (this.callWin && !this.conference) {
      let byeMessage = new CallByeMessageContent();
      // 处理用户没有主动挂断，而是直接返回页面时，补偿一个挂断消息
      // 现在还无法处理会议的情况，会议只能等待超时
      byeMessage.callId = this.callId;
      byeMessage.inviteMsgUid = this.inviteMessageUid;
      byeMessage.reason = CallEndReason.REASON_Hangup;
      wfc.sendConversationMessage(this.conversation, byeMessage);

      this.onVoipWindowClose();
    }
  }
}

const self = new AvEngineKitProxy();
export default self;
