/**
 * WebSocket 工具类
 * 提供通用的 WebSocket 连接管理功能
 */
export class WebSocketManager {
  constructor (options = {}) {
    this.options = {
      autoReconnect: true,
      reconnectInterval: 3000,
      maxReconnectAttempts: 5,
      ...options
    }

    this.websocket = null
    this.reconnectAttempts = 0
    this.isConnected = false
    this.reconnectTimer = null
    this.listeners = new Map()
    // 标记是否为手动断开，手动断开时不触发自动重连
    this.manualClose = false
  }

  /**
   * 连接 WebSocket
   * @param {string} url WebSocket 连接地址
   * @param {Object} options 连接选项
   */
  connect (url, options = {}) {
    const connectOptions = { ...this.options, ...options }

    try {
      // 重置手动断开标记
      this.manualClose = false
      this.websocket = new WebSocket(url)

      this.websocket.onopen = (event) => this.handleOpen(event, connectOptions)
      this.websocket.onmessage = (event) => this.handleMessage(event, connectOptions)
      this.websocket.onclose = (event) => this.handleClose(event, connectOptions)
      this.websocket.onerror = (event) => this.handleError(event, connectOptions)

      this.emit('connecting', { url })
    } catch (error) {
      console.error('>>>> WebSocket连接失败:', error, url)
      this.emit('error', { error })
      if (connectOptions.autoReconnect) {
        this.handleReconnect(url, connectOptions)
      }
    }
  }

  /**
   * 处理连接成功
   */
  handleOpen (event, options) {
    this.isConnected = true
    this.reconnectAttempts = 0
    this.emit('connected', { event })
  }

  /**
   * 处理消息接收
   */
  handleMessage (event, options) {
    try {
      const data = JSON.parse(event.data)
      this.emit('message', { data, event })
    } catch (error) {
      // 如果不是JSON格式，直接处理原始数据
      this.emit('message', { data: { message: event.data }, event })
    }
  }

  /**
   * 处理连接关闭
   */
  handleClose (event, options) {
    this.isConnected = false
    this.emit('closed', { event })

    // 手动断开时不进行重连
    if (!this.manualClose && options.autoReconnect && this.reconnectAttempts < options.maxReconnectAttempts) {
      this.handleReconnect(options.url, options)
    }
  }

  /**
   * 处理连接错误
   */
  handleError (event, options) {
    console.error('WebSocket连接错误:', event)
    this.isConnected = false
    this.emit('error', { event })
  }

  /**
   * 处理重连
   */
  handleReconnect (url, options) {
    if (this.reconnectAttempts >= options.maxReconnectAttempts) {
      console.log('达到最大重连次数，停止重连')
      this.emit('reconnect-failed', { attempts: this.reconnectAttempts })
      return
    }

    this.reconnectAttempts++

    this.reconnectTimer = setTimeout(() => {
      console.log(`尝试重连 WebSocket (${this.reconnectAttempts}/${options.maxReconnectAttempts})`)
      this.connect(url, options)
    }, options.reconnectInterval)

    this.emit('reconnecting', { attempts: this.reconnectAttempts })
  }

  /**
   * 断开连接
   */
  disconnect () {
    // 设置手动关闭标记，阻止自动重连
    this.manualClose = true
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer)
      this.reconnectTimer = null
    }

    if (this.websocket) {
      this.websocket.close()
      this.websocket = null
    }

    this.isConnected = false
    this.emit('disconnected')
  }

  /**
   * 发送消息
   * @param {string|Object} message 要发送的消息
   */
  send (message) {
    if (this.websocket && this.isConnected) {
      const data = typeof message === 'string' ? message : JSON.stringify(message)
      this.websocket.send(data)
      return true
    }
    return false
  }

  /**
   * 手动重连
   */
  reconnect (url, options = {}) {
    this.disconnect()
    this.reconnectAttempts = 0
    this.connect(url, options)
  }

  /**
   * 添加事件监听器
   * @param {string} event 事件名称
   * @param {Function} callback 回调函数
   */
  on (event, callback) {
    if (!this.listeners.has(event)) {
      this.listeners.set(event, [])
    }
    this.listeners.get(event).push(callback)
  }

  /**
   * 移除事件监听器
   * @param {string} event 事件名称
   * @param {Function} callback 回调函数
   */
  off (event, callback) {
    if (this.listeners.has(event)) {
      const callbacks = this.listeners.get(event)
      const index = callbacks.indexOf(callback)
      if (index > -1) {
        callbacks.splice(index, 1)
      }
    }
  }

  /**
   * 触发事件
   * @param {string} event 事件名称
   * @param {Object} data 事件数据
   */
  emit (event, data) {
    if (this.listeners.has(event)) {
      this.listeners.get(event).forEach(callback => {
        try {
          callback(data)
        } catch (error) {
          console.error(`WebSocket事件监听器错误 (${event}):`, error)
        }
      })
    }
  }

  /**
   * 获取连接状态
   */
  getConnectionState () {
    return {
      isConnected: this.isConnected,
      reconnectAttempts: this.reconnectAttempts,
      readyState: this.websocket ? this.websocket.readyState : WebSocket.CLOSED
    }
  }
}

/**
 * Vue 2 组合式 API 风格的 WebSocket Hook
 * @param {Object} options 配置选项
 */
export function useWebSocket (options = {}) {
  const wsManager = new WebSocketManager(options)

  return {
    // 连接方法
    connect: (url, connectOptions) => wsManager.connect(url, connectOptions),
    disconnect: () => wsManager.disconnect(),
    reconnect: (url, connectOptions) => wsManager.reconnect(url, connectOptions),

    // 消息方法
    send: (message) => wsManager.send(message),

    // 事件监听
    on: (event, callback) => wsManager.on(event, callback),
    off: (event, callback) => wsManager.off(event, callback),

    // 状态
    getConnectionState: () => wsManager.getConnectionState(),

    // 原始管理器实例（用于高级用法）
    manager: wsManager
  }
}

export default WebSocketManager
