/**
 * WebSocket 消息服务
 * 用于实时接收消息通知
 */
import { getToken } from '@/utils/auth'
import { ElNotification } from 'element-plus'

class WebSocketService {
  constructor() {
    this.ws = null
    this.reconnectAttempts = 0
    this.maxReconnectAttempts = 5
    this.reconnectDelay = 3000
    this.heartbeatInterval = null
    this.listeners = new Map()
    this.isConnected = false
  }

  /**
   * 建立 WebSocket 连接
   */
  connect() {
    const token = getToken()
    if (!token) {
      console.warn('[WebSocket] 未登录，无法建立连接')
      return
    }

    // 判断协议
    const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
    const host = window.location.host
    // 开发环境使用后端端口
    const wsHost = import.meta.env.DEV ? 'localhost:8080' : host
    const wsUrl = `${protocol}//${wsHost}/ws/message?token=${token}`

    console.log('[WebSocket] 正在连接:', wsUrl)

    try {
      this.ws = new WebSocket(wsUrl)

      this.ws.onopen = () => {
        console.log('[WebSocket] 连接成功')
        this.isConnected = true
        this.reconnectAttempts = 0
        this.startHeartbeat()
        this.emit('connected')
      }

      this.ws.onmessage = (event) => {
        this.handleMessage(event.data)
      }

      this.ws.onclose = (event) => {
        console.log('[WebSocket] 连接关闭:', event.code, event.reason)
        this.isConnected = false
        this.stopHeartbeat()
        this.emit('disconnected')
        
        // 尝试重连
        if (this.reconnectAttempts < this.maxReconnectAttempts) {
          this.reconnectAttempts++
          console.log(`[WebSocket] ${this.reconnectDelay / 1000}秒后尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})`)
          setTimeout(() => this.connect(), this.reconnectDelay)
        }
      }

      this.ws.onerror = (error) => {
        console.error('[WebSocket] 连接错误:', error)
        this.emit('error', error)
      }
    } catch (error) {
      console.error('[WebSocket] 创建连接失败:', error)
    }
  }

  /**
   * 处理收到的消息
   */
  handleMessage(data) {
    try {
      // 心跳响应
      if (data === 'pong') {
        console.log('[WebSocket] 收到心跳响应')
        return
      }

      console.log('[WebSocket] 收到原始数据:', data)
      const message = JSON.parse(data)
      console.log('[WebSocket] 解析后消息:', message.type, message)

      switch (message.type) {
        case 'connection_ack':
          console.log('[WebSocket] 连接已确认')
          break

        case 'unread_snapshot':
          // 未读消息数快照
          this.emit('unread_count', message.payload?.unreadCount || 0)
          break

        case 'new_message':
          // 新消息通知
          this.handleNewMessage(message.payload)
          break

        case 'new_notification':
        case 'system_notification':
          // 新系统通知
          this.handleNewNotification(message.payload)
          break

        default:
          this.emit(message.type, message.payload)
      }
    } catch (error) {
      console.error('[WebSocket] 解析消息失败:', error, data)
    }
  }

  /**
   * 处理新消息
   */
  handleNewMessage(payload) {
    // 弹窗通知
    ElNotification({
      title: payload.senderName || '新消息',
      message: payload.content?.substring(0, 50) || '您收到一条新消息',
      type: 'info',
      duration: 5000,
      position: 'top-right',
      onClick: () => {
        // 点击跳转到消息中心
        window.location.href = '/#/message'
      }
    })

    // 触发事件供其他组件使用
    this.emit('new_message', payload)
  }

  /**
   * 处理新通知
   */
  handleNewNotification(payload) {
    // 弹窗通知
    ElNotification({
      title: payload.title || '系统通知',
      message: payload.content?.substring(0, 100) || '您收到一条系统通知',
      type: payload.priority === '2' ? 'warning' : 'info',
      duration: payload.priority === '2' ? 0 : 5000, // 紧急通知不自动关闭
      position: 'top-right',
      onClick: () => {
        window.location.href = '/#/message'
      }
    })

    // 触发事件
    this.emit('new_notification', payload)
  }

  /**
   * 启动心跳
   */
  startHeartbeat() {
    this.stopHeartbeat()
    this.heartbeatInterval = setInterval(() => {
      if (this.ws && this.ws.readyState === WebSocket.OPEN) {
        this.ws.send('ping')
      }
    }, 30000) // 30秒一次心跳
  }

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

  /**
   * 发送消息
   */
  send(data) {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(typeof data === 'string' ? data : JSON.stringify(data))
    } else {
      console.warn('[WebSocket] 连接未就绪，无法发送消息')
    }
  }

  /**
   * 发送已读确认
   */
  sendReadAck(messageIds) {
    this.send({
      type: 'read_ack',
      payload: { messageIds }
    })
  }

  /**
   * 断开连接
   */
  disconnect() {
    this.stopHeartbeat()
    if (this.ws) {
      this.ws.close()
      this.ws = null
    }
    this.isConnected = false
    this.listeners.clear()
  }

  /**
   * 注册事件监听
   */
  on(event, callback) {
    if (!this.listeners.has(event)) {
      this.listeners.set(event, new Set())
    }
    this.listeners.get(event).add(callback)
    
    // 返回取消监听的函数
    return () => this.off(event, callback)
  }

  /**
   * 取消事件监听
   */
  off(event, callback) {
    if (this.listeners.has(event)) {
      this.listeners.get(event).delete(callback)
    }
  }

  /**
   * 触发事件
   */
  emit(event, data) {
    if (this.listeners.has(event)) {
      this.listeners.get(event).forEach(callback => {
        try {
          callback(data)
        } catch (error) {
          console.error(`[WebSocket] 事件处理错误 (${event}):`, error)
        }
      })
    }
  }
}

// 导出单例
export const wsService = new WebSocketService()

export default wsService
