/**
 * WebSocket通信管理类
 * 支持自动重连、消息订阅机制
 */
import { message } from '@/layouts/messageStore';
import { getEnvConfig } from './envConfig';

// 环境配置获取
const getWebSocketUrl = () => {
  const env = process.env.NODE_ENV;
  if (env === 'development' || env === 'test') {
    return 'ws://171.217.92.33:21601/city-operation/movement-sensor-event/websocket';
  }
  return 'wss://cdcgzgf.cn:13200/city-operation/movement-sensor-event/websocket';
};

// 消息类型定义
type MessageType = 'total' | 'other'; // 可扩展其他消息类型
export interface WSMessage {
  code: number;
  data: any;
  msg: string;
  success: boolean;
  type: MessageType;
}

// 消息处理函数
type MessageHandler = (data: any) => void;

class WebSocketService {
  private ws: WebSocket | null = null;
  private url: string;
  private reconnectAttempts = 0;
  private maxReconnectAttempts = 5;
  private reconnectInterval = 3000; // 重连间隔3秒
  private reconnectTimeoutId: number | null = null;
  private messageSubscribers: Map<MessageType, Set<MessageHandler>> = new Map();
  private isConnecting = false;
  private isManualClosed = false;

  constructor(url?: string) {
    this.url = url || getWebSocketUrl();
  }

  // 连接WebSocket
  connect(): Promise<boolean> {
    if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING)) {
      return Promise.resolve(true);
    }

    if (this.isConnecting) {
      return new Promise((resolve) => {
        // 等待连接完成
        const checkInterval = setInterval(() => {
          if (this.ws && this.ws.readyState === WebSocket.OPEN) {
            clearInterval(checkInterval);
            resolve(true);
          }
        }, 100);
      });
    }

    this.isConnecting = true;
    this.isManualClosed = false;

    return new Promise((resolve) => {
      try {
        this.ws = new WebSocket(this.url);

        this.ws.onopen = () => {
          console.log('WebSocket connected');
          this.reconnectAttempts = 0;
          this.isConnecting = false;
          resolve(true);
        };

        this.ws.onmessage = (event) => {
          try {
            const data: WSMessage = JSON.parse(event.data);
            this.handleMessage(data);
          } catch (err) {
            console.error('Failed to parse WebSocket message', err);
          }
        };

        this.ws.onclose = (event) => {
          this.isConnecting = false;
          console.log('WebSocket disconnected', event.code, event.reason);
          
          if (!this.isManualClosed) {
            this.attemptReconnect();
          }
          
          if (this.ws) {
            this.ws = null;
          }
        };

        this.ws.onerror = (error) => {
          this.isConnecting = false;
          console.error('WebSocket error:', error);
          resolve(false);
        };
      } catch (error) {
        this.isConnecting = false;
        console.error('Failed to create WebSocket instance', error);
        resolve(false);
        this.attemptReconnect();
      }
    });
  }

  // 关闭WebSocket连接
  disconnect() {
    this.isManualClosed = true;
    
    if (this.reconnectTimeoutId) {
      window.clearTimeout(this.reconnectTimeoutId);
      this.reconnectTimeoutId = null;
    }

    if (this.ws) {
      this.ws.close();
      this.ws = null;
    }
    
    // 清空所有订阅
    this.messageSubscribers.clear();
  }

  // 尝试重新连接
  private attemptReconnect() {
    if (this.reconnectAttempts >= this.maxReconnectAttempts || this.isManualClosed) {
      console.log('Max reconnect attempts reached or manually closed. Giving up.');
      return;
    }

    this.reconnectAttempts++;
    console.log(`Attempting to reconnect (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`);

    this.reconnectTimeoutId = window.setTimeout(() => {
      this.connect().catch(console.error);
    }, this.reconnectInterval);
  }

  // 处理接收到的消息
  private handleMessage(message: WSMessage) {
    if (!message || !message.type) return;

    // 获取该类型的所有订阅者
    const subscribers = this.messageSubscribers.get(message.type);
    if (subscribers) {
      subscribers.forEach(handler => {
        try {
          handler(message.data);
        } catch (err) {
          console.error('Error in message handler', err);
        }
      });
    }
  }

  // 订阅消息
  subscribe(type: MessageType, handler: MessageHandler): () => void {
    if (!this.messageSubscribers.has(type)) {
      this.messageSubscribers.set(type, new Set());
    }

    const subscribers = this.messageSubscribers.get(type)!;
    subscribers.add(handler);

    // 如果WebSocket未连接，尝试连接
    if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
      this.connect().catch(console.error);
    }

    // 返回取消订阅的函数
    return () => {
      const subscribers = this.messageSubscribers.get(type);
      if (subscribers) {
        subscribers.delete(handler);
        
        // 如果该类型没有订阅者了，删除该类型
        if (subscribers.size === 0) {
          this.messageSubscribers.delete(type);
        }
      }
      
      // 如果没有任何订阅了，断开连接
      if (this.messageSubscribers.size === 0) {
        this.disconnect();
      }
    };
  }

  // 发送消息
  sendMessage(data: any) {
    if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
      console.error('WebSocket is not connected');
      return false;
    }

    try {
      this.ws.send(JSON.stringify(data));
      return true;
    } catch (err) {
      console.error('Failed to send message', err);
      return false;
    }
  }

  // 检查是否已连接
  isConnected(): boolean {
    return !!this.ws && this.ws.readyState === WebSocket.OPEN;
  }
}

// 创建单例
const webSocketService = new WebSocketService();

export default webSocketService; 