// src/utils/websocket.ts
let wsObj: WebSocket | null = null;
let wsUrl: string = '';
let lockReconnect = false;
let wsCreateHandler: ReturnType<typeof setTimeout> | null = null;
let messageCallback: ((msg: string) => void) | null = null;
let errorCallback: ((err: Event) => void) | null = null;
let sendDatas: Record<string, any> = {};

// WebSocket连接初始化
export const connectWebsocket = (
  url: string,
  agentData: Record<string, any>,
  successCallback: (msg: string) => void,
  errCallback: (err: Event) => void
) => {
  wsUrl = url;
  messageCallback = successCallback;
  errorCallback = errCallback;
  sendDatas = agentData;
  createWebSocket();
};

// 手动关闭WebSocket
export const closeWebsocket = () => {
  if (wsObj) {
    log('手动关闭WebSocket连接');
    wsObj.close();
    lockReconnect = true;
    wsCreateHandler && clearTimeout(wsCreateHandler);
    heartCheck.stop();
  }
};

// 发送消息
export const sendMsg = (value: any) => {
  if (wsObj && wsObj.readyState === WebSocket.OPEN) {
    wsObj.send(JSON.stringify(value));
  } else {
    log('WebSocket 未连接，消息发送失败');
  }
};

// 创建 WebSocket 实例
const createWebSocket = () => {
  if (typeof WebSocket === 'undefined') {
    log('当前浏览器不支持 WebSocket');
    return;
  }

  try {
    wsObj = new WebSocket(wsUrl);
    initWsEvents();
  } catch (e) {
    log('WebSocket 创建异常，尝试重连');
    reconnect();
  }
};

// 绑定事件
const initWsEvents = () => {
  if (!wsObj) return;

  wsObj.onopen = (event) => {
    log('WebSocket连接成功');
    if (wsObj?.readyState === WebSocket.OPEN) {
      wsObj.send(JSON.stringify(sendDatas));
    }
    heartCheck.start();
  };

  wsObj.onmessage = (event) => {
    heartCheck.reset();
    log('接收到服务器消息：', event.data);
    messageCallback?.(event.data);
  };

  wsObj.onclose = (event) => {
    log('WebSocket连接关闭:', event);
    if (event.code !== 1000) {
      errorCallback?.(event);
      reconnect();
    }
  };

  wsObj.onerror = (event) => {
    log('WebSocket连接错误:', event);
    errorCallback?.(event);
    reconnect();
  };
};

// 封装 console.log
const log = (...args: any[]) => {
  console.log('[WebSocket]', ...args);
};

// 心跳机制
const heartCheck = {
  timeout: 60 * 1000,
  timeoutObj: null as ReturnType<typeof setTimeout> | null,
  serverTimeoutObj: null as ReturnType<typeof setTimeout> | null,

  reset() {
    this.timeoutObj && clearTimeout(this.timeoutObj);
    this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
    this.start();
  },

  stop() {
    this.timeoutObj && clearTimeout(this.timeoutObj);
    this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
  },

  start() {
    this.timeoutObj = setTimeout(() => {
      try {
        log('发送心跳包');
        const ping = { content: '心跳检测' };
        wsObj?.send(JSON.stringify(ping));
      } catch (err) {
        log('发送心跳失败，尝试重连');
        reconnect();
      }

      this.serverTimeoutObj = setTimeout(() => {
        log('心跳无响应，尝试重连');
        reconnect();
      }, this.timeout);
    }, this.timeout);
  },
};

// 重连逻辑
const reconnect = () => {
  if (lockReconnect) return;
  lockReconnect = true;

  wsCreateHandler && clearTimeout(wsCreateHandler);
  wsCreateHandler = setTimeout(() => {
    log('执行重连...');
    createWebSocket();
    lockReconnect = false;
  }, 60000); // 1分钟重连
};
