import { getToken } from '@/utils/token-util';

class WebSocketService {
  constructor() {
    this.ws = null; // 连接实例
    this.isConnected = false; // 连接状态
    this.isConnecting = false; // 添加此状态
    this.reconnectTimer = null; // 重连计时器
    this.heartbeatTimer = null; // 心跳计时器
    this.heartbeatInterval = 30000; // 心跳间隔（30秒）
    this.maxReconnectCount = 100; // 最大重连次数
    this.reconnectCount = 0; // 当前重连次数
  }

  // 初始化连接（核心方法）
  init() {
    // 更严格的连接状态检查
    if (
      this.isConnecting ||
      (this.ws && this.ws.readyState === WebSocket.CONNECTING)
    ) {
      console.log('连接已在进行中，跳过重复连接请求');
      return false;
    }
    // 检查是否已经建立连接
    if (this.isConnected && this.ws && this.ws.readyState === WebSocket.OPEN) {
      console.log('WebSocket 已连接，无需重复连接');
      return false;
    }
    // 1. 获取 Token 和用户 ID（优先 Vuex，其次 localStorage）
    let token = getToken();

    // 2. 无 Token 则阻断连接，等待登录
    if (!token) {
      console.log('无有效 Token，等待登录后连接');
      return false;
    }
    this.isConnecting = true;
    // 3. 已存在连接则关闭旧连接
    if (this.ws) this.close();

    // 4. 建立 WebSocket 连接（携带授权信息）
    const wsUrl = `${process.env.VUE_APP_WS_URL}?token=${token}&platform=${process.env.VUE_APP_WS_PLATFORM}`;
    this.ws = new WebSocket(wsUrl);

    // 5. 连接成功回调
    this.ws.onopen = () => {
      console.log('WebSocket 连接成功');
      this.isConnected = true;
      this.reconnectCount = 0; // 重置重连次数
      this.startHeartbeat(); // 启动心跳
      window.EventBus.$emit('ws:connected', true); // 触发连接成功事件
    };

    // 6. 接收消息回调
    this.ws.onmessage = (event) => {
      try {
        const message = JSON.parse(event.data);
        // console.log('WebSocket 收到消息：', message);
        // 处理 Token 失效（服务端约定 code: 401）
        if (message.code === 401) {
          this.handleTokenInvalid();
          return;
        }
        // 正常消息分发
        window.EventBus.$emit('ws:message', message);
      } catch (error) {
        console.error('消息解析失败：', error);
      }
    };

    // 7. 连接关闭回调
    this.ws.onclose = (event) => {
      console.log(`WebSocket 关闭（code: ${event.code}）`);
      // 确保重置连接状态
      this.isConnected = false;
      this.isConnecting = false; // 必须重置连接中状态
      this.stopHeartbeat();
      window.EventBus.$emit('ws:connected', false);

      // 异常关闭则重连
      if (event.code !== 1000 && this.reconnectCount < this.maxReconnectCount) {
        this.reconnect();
      }
    };

    // 8. 连接错误回调
    this.ws.onerror = (error) => {
      console.error('WebSocket 错误：', error);
      window.EventBus.$emit('ws:error', error);
    };
  }

  // 发送消息
  send(data) {
    if (this.isConnected && this.ws) {
      this.ws.send(JSON.stringify(data));
    } else {
      console.error('WebSocket 未连接，无法发送消息');
    }
  }

  // 主动关闭连接
  close() {
    this.isConnecting = false; // 重置连接中状态
    if (this.ws) {
      this.ws.close(1000, '手动关闭'); // 1000 表示正常关闭
      this.ws = null;
      this.isConnected = false;
      this.stopHeartbeat();
      this.clearReconnectTimer();
    }
  }

  // 心跳检测（维持连接）
  startHeartbeat() {
    this.heartbeatTimer = setInterval(() => {
      if (this.isConnected) {
        this.send({ type: 'heartbeat', content: 'ping' });
      }
    }, this.heartbeatInterval);
  }

  // 停止心跳
  stopHeartbeat() {
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer);
      this.heartbeatTimer = null;
    }
  }

  // 重连机制
  reconnect() {
    this.clearReconnectTimer();
    this.isConnecting = false; // 重置连接状态

    this.reconnectCount++;
    console.log(`第 ${this.reconnectCount} 次重连...`);
    this.reconnectTimer = setTimeout(() => {
      // 重连前确保连接已完全关闭
      if (this.ws) {
        this.ws.onopen = null;
        this.ws.onclose = null;
        this.ws.onerror = null;
        this.ws.onmessage = null;
        this.ws = null;
      }
      this.init();
    }, 3000 * this.reconnectCount); // 指数退避重连（3s, 6s, 9s...）
  }

  // 清除重连计时器
  clearReconnectTimer() {
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer);
      this.reconnectTimer = null;
    }
  }

  // 处理 Token 失效
  handleTokenInvalid() {
    this.close(); // 关闭连接
    // store.dispatch('user/logout'); // 清除 Token
    // router.push('/login?redirect=' + router.currentRoute.path); // 跳转登录页（带回调地址）
    // window.EventBus.$emit('ws:error', 'Token 已过期，请重新登录');
  }
}

// 单例导出
export default new WebSocketService();
