import { MESSAGETYPES, getMessageTypeName } from "@/constants";
let socket = null;
let heartbeatInterval = null;
let reconnectTimer = null;

/**
 * 建立 WebSocket 连接
 */
function createWebSocket(token, onMessage) {
  let url = "wss://api.shelingxingqiu.com/socket";
  try {
    const accountInfo = uni.getAccountInfoSync();
    const envVersion = accountInfo.miniProgram.envVersion;

    switch (envVersion) {
      case "develop": // 开发版
        // url = "ws://192.168.1.242:8000/socket";
        url = "wss://apitest.shelingxingqiu.com/socket";
        break;
      case "trial": // 体验版
        url = "wss://apitest.shelingxingqiu.com/socket";
        break;
      case "release": // 正式版
        url = "wss://api.shelingxingqiu.com/socket";
        break;
      default:
        // 保持默认值
        break;
    }
  } catch (e) {
    console.error("获取环境信息失败，使用默认正式环境", e);
  }
  url += `?authorization=${token}`;
  socket = uni.connectSocket({
    url,
    success: () => {
      console.log("websocket 连接成功");
      // 启动心跳
      startHeartbeat(onMessage);
    },
    fail: () => {
      reconnect(onMessage);
    },
  });

  // 接收消息
  uni.onSocketMessage((res) => {
    const data = JSON.parse(res.data);
    if (data.event === "pong" || !data.data.updates) return;
    if (onMessage) onMessage(data.data.updates);
    const msg = data.data.updates[0];
    if (!msg) return;
    console.log("收到消息：", getMessageTypeName(msg.constructor), msg);
    if (msg.constructor === MESSAGETYPES.BackToGame) {
      const pages = getCurrentPages();
      const currentPage = pages[pages.length - 1];
      if (
        currentPage.route === "pages/battle-room" ||
        currentPage.route === "pages/team-battle" ||
        currentPage.route === "pages/melee-match"
      ) {
        return;
      }
      const { battleInfo } = msg;
      uni.setStorageSync("current-battle", battleInfo);
      // console.log("----battleInfo", battleInfo);
      if (battleInfo.config.mode === 1) {
        uni.navigateTo({
          url: `/pages/team-battle?battleId=${battleInfo.id}&gameMode=${battleInfo.config.battleMode}`,
        });
      } else if (battleInfo.config.mode === 2) {
        uni.navigateTo({
          url: `/pages/melee-match?battleId=${battleInfo.id}&gameMode=${battleInfo.config.battleMode}`,
        });
      }
    } else if (msg.constructor === MESSAGETYPES.MatchOver) {
      uni.$emit("game-over");
    } else if (msg.constructor === MESSAGETYPES.RankUpdate) {
      uni.setStorageSync("latestRank", msg.lvl);
    } else if (msg.constructor === MESSAGETYPES.LvlUpdate) {
      uni.setStorageSync("latestLvl", msg.lvl);
    }
  });

  // 错误处理
  uni.onSocketError((err) => {
    console.error("WebSocket 错误", err);
    reconnect(onMessage);
  });

  uni.onSocketClose((result) => {
    console.log("WebSocket 已关闭", result);
    stopHeartbeat();
    reconnect(onMessage);
  });
}

/**
 * 重连机制
 */
function reconnect(onMessage) {
  reconnectTimer && clearTimeout(reconnectTimer);
  closeWebSocket(); // 确保关闭旧连接

  const token = uni.getStorageSync(
    `${uni.getAccountInfoSync().miniProgram.envVersion}_token`
  );
  if (!token) return;

  reconnectTimer = setTimeout(() => {
    console.log("reconnecting...");
    createWebSocket(token, onMessage);
  }, 1000);
}

function closeWebSocket() {
  if (socket) {
    reconnectTimer && clearTimeout(reconnectTimer);
    stopHeartbeat();

    try {
      socket.close();
    } catch (err) {
      console.error("关闭WebSocket连接失败", err);
    }

    socket = null; // 清除socket引用
  }
}

function sendHeartbeat(onMessage) {
  uni.sendSocketMessage({
    data: JSON.stringify({ event: "ping", data: {} }),
    success: () => {
      // console.log("发送心跳成功");
    },
    fail: (err) => {
      console.error("发送心跳失败", err);
      stopHeartbeat();
      closeWebSocket(); // 关闭失效的连接
      reconnect(onMessage); // 触发重连
    },
  });
}

/**
 * 启动心跳
 */
function startHeartbeat(onMessage) {
  stopHeartbeat(); // 防止重复启动

  heartbeatInterval = setInterval(() => {
    if (socket && socket.readyState === 1) {
      // 检查连接状态
      sendHeartbeat(onMessage);
    }
  }, 10000);
}

/**
 * 停止心跳
 */
function stopHeartbeat() {
  if (heartbeatInterval) {
    clearInterval(heartbeatInterval);
    heartbeatInterval = null;
  }
}

export default {
  createWebSocket,
  closeWebSocket,
};
