import store from "@/store";
import { Message } from "iview";
import { VUE_APP_WK_SERVER_SOCKET_FOR_AUDIO } from "@/constants/constants";
import { createLog } from "@/utils/logger";

let ws;
let shouldReconnect = true;
let heartbeatIds = [];
const RECONNECT_INTERVAL = 6 * 1000;
const HEARTBEAT_INTERVAL = 50 * 1000;
let reconnectNumber = 0;

export function openWS({ examRecordDataId }) {
  window._hmt.push(["_trackEvent", "websocket", "准备连接"]);
  console.log("in openWS", examRecordDataId);
  createLog({ type: "websocket", action: "准备连接", examRecordDataId });
  ws = new WebSocket(
    VUE_APP_WK_SERVER_SOCKET_FOR_AUDIO +
      `?key=${store.state.user.key}&token=${store.state.user.token}`
  );

  ws.onopen = event => {
    console.log("open ws", event);
    reconnectNumber = 0;

    ws.onmessage = processWSMessage;

    ws.onclose = () => {
      console.log("ws close by server");
      createLog({ type: "websocket", action: "ws close by server" });
      for (const heartbeatId of heartbeatIds) {
        clearInterval(heartbeatId);
      }
      heartbeatIds = [];
      if (shouldReconnect) {
        console.log("close -> reconnect");
        setTimeout(() => {
          // tryWSReconnect();
          reconnectNumber++;
          if (reconnectNumber >= 5) {
            reconnectNumber = 0;
            // 仅在正在考试界面报错
            if (location.href.includes("/order/")) {
              Message.error({
                content: "Websocket重连失败",
                duration: 5,
                closable: true,
              });
            } else {
              shouldReconnect = false;
            }
          }
          window._hmt.push([
            "_trackEvent",
            "websocket",
            "连接被关闭后-准备连接",
          ]);
          createLog({
            type: "websocket",
            action: "连接被关闭后-准备连接",
            detail: "onclose",
          });
          openWS({ examRecordDataId });
        }, RECONNECT_INTERVAL);
      } else {
        shouldReconnect = true; // reset shouldReconnect
      }
    };

    heartbeat();
  };

  ws.onerror = () => {
    setTimeout(() => {
      reconnectNumber++;
      if (reconnectNumber >= 5) {
        reconnectNumber = 0;
        // 仅在正在考试界面报错
        if (location.href.includes("/order/")) {
          Message.error({
            content: "Websocket重连失败",
            duration: 5,
            closable: true,
          });
        } else {
          shouldReconnect = false;
        }
      }
      if (location.href.includes("/order/")) {
        window._hmt.push(["_trackEvent", "websocket", "连接错误后-重新连接"]);
        createLog({
          type: "websocket",
          action: "连接被关闭后-准备连接",
          detail: "onerror",
        });
        openWS({ examRecordDataId });
      } else {
        window._hmt.push([
          "_trackEvent",
          "websocket",
          "连接错误后-不在正在考试页面-重新连接",
        ]);
      }
    }, RECONNECT_INTERVAL);
  };
}

function heartbeat() {
  const heartbeatId = setInterval(() => {
    ws.send(
      JSON.stringify({
        eventType: "HEARTBEAT",
      })
    );
  }, HEARTBEAT_INTERVAL);

  heartbeatIds.push(heartbeatId);
}

export function closeWsWithoutReconnect() {
  createLog({ type: "websocket", action: "客户端准备关闭ws。" });
  shouldReconnect = false;
  try {
    if (ws && ws.readyState === 1) ws.close();
  } catch (e) {
    console.log("关闭ws异常。");
    createLog({ type: "websocket", action: "关闭ws异常。", detail: e });
  }
}

// export function getQRCode(order, transferFileType, testEnv) {
//   if (ws.readyState === ws.OPEN) {
//     ws.send(
//       JSON.stringify({
//         eventType: "GET_QR_CODE",
//         order,
//         transferFileType: transferFileType,
//         ...testEnv,
//       })
//     );
//     return true;
//   } else {
//     return false;
//   }
// }

function processWSMessage(event) {
  // console.log("get ws msg: ", event);
  let res;
  try {
    res = JSON.parse(event.data).content;
  } catch (error) {
    window._hmt.push(["_trackEvent", "websocket", "JSON.parse出错" + error]);
    return;
  }
  if (!res) {
    console.log("ws message format error", event);
    return;
  }
  if (res.eventType && res.eventType !== "HEARTBEAT" && !res.isSuccess) {
    Message.error({
      content: res.errorMessage,
      duration: 10,
      closable: true,
    });
    return;
  }
  switch (res.eventType) {
    case "HEARTBEAT":
      // console.log("ws heartbeat response from server");
      break;
    // case "GET_QR_CODE":
    //   console.log("get qrcode", res);
    //   window._hmt.push(["_trackEvent", "websocket", "获得二维码"]);
    //   store.commit("examingHomeModule/setQuestionQrCode", {
    //     qrCode: res.data.qrCode,
    //     order: res.data.order,
    //   });
    //   break;
    case "SCAN_QR_CODE":
      console.log("wx scanned qrcode", res);
      window._hmt.push(["_trackEvent", "websocket", "二维码被扫描"]);
      store.commit("examingHomeModule/setQuestionQrCodeScanned", {
        order: res.data.order,
      });
      break;
    case "GET_FILE_ANSWER":
      console.log("get file url", res);
      window._hmt.push(["_trackEvent", "websocket", "获得音频地址"]);

      store.commit("examingHomeModule/setQuestionFileAnswerUrl", {
        order: res.data.order,
        fileUrl: res.data.fileUrl,
        transferFileType: res.data.transferFileType,
      });
      break;
    case "SYSTEM_ERROR":
      console.log("ws get error", res);
      break;
  }
}
