/**
 * 语音流式对话 WebSocket 管理模块
 */

class VoiceStreamWebSocket {
  constructor(url) {
    this.url = url
    this.ws = null
    this.isConnected = false
    this.reconnectAttempts = 0
    this.maxReconnectAttempts = 5
    this.reconnectDelay = 2000
    this.manualClose = false  // 标记是否为主动关闭
    
    // 事件监听器
    this.listeners = {
      onConnected: null,
      onDisconnected: null,
      onSttResult: null,
      onLlmToken: null,
      onSentence: null,
      onAudioChunk: null,
      onComplete: null,
      onError: null
    }
  }

  /**
   * 建立连接
   * @param {String} sessionId - 聊天会话ID（用于历史记录查询和保存，与文字对话的sessionId保持一致）
   * @param {Number} templateId - 模板ID
   * @param {String} token - 认证令牌（可选）
   * @param {String} userId - 用户ID（可选）
   */
  connect(sessionId = null, templateId = null, token = null, userId = null) {
    return new Promise((resolve, reject) => {
      try {
        // 重置主动关闭标志
        this.manualClose = false

        // 构建连接URL
        let wsUrl = this.url
        const params = []
        if (sessionId) params.push(`sessionId=${sessionId}`)
        if (templateId) params.push(`templateId=${templateId}`)
        if (token) params.push(`token=${token}`)
        if (userId) params.push(`userId=${userId}`)
        if (params.length > 0) {
          wsUrl += '?' + params.join('&')
        }

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

        // 创建WebSocket连接
        this.ws = uni.connectSocket({
          url: wsUrl,
          success: () => {
            console.log('[VoiceStreamWS] WebSocket创建成功')
          },
          fail: (err) => {
            console.error('[VoiceStreamWS] WebSocket创建失败:', err)
            reject(err)
          }
        })

        // 连接打开
        this.ws.onOpen(() => {
          console.log('[VoiceStreamWS] 连接已建立')
          this.isConnected = true
          this.reconnectAttempts = 0
          if (this.listeners.onConnected) {
            this.listeners.onConnected()
          }
          resolve()
        })

        // 接收消息
        this.ws.onMessage((res) => {
          this.handleMessage(res)
        })

        // 连接错误
        this.ws.onError((err) => {
          console.error('[VoiceStreamWS] 连接错误:', err)
          this.isConnected = false
          if (this.listeners.onError) {
            this.listeners.onError('WebSocket连接错误')
          }
        })

        // 连接关闭
        this.ws.onClose(() => {
          console.log('[VoiceStreamWS] 连接已关闭')
          this.isConnected = false
          if (this.listeners.onDisconnected) {
            this.listeners.onDisconnected()
          }
          
          // 只有非主动关闭才尝试重连
          if (!this.manualClose) {
            console.log('[VoiceStreamWS] 检测到异常断开，将尝试自动重连')
            this.tryReconnect()
          } else {
            console.log('[VoiceStreamWS] 主动关闭连接，不进行重连')
          }
        })

      } catch (err) {
        console.error('[VoiceStreamWS] 连接异常:', err)
        reject(err)
      }
    })
  }

  /**
   * 处理接收到的消息
   */
  handleMessage(res) {
    try {
      // 二进制消息（音频数据）
      if (res.data instanceof ArrayBuffer) {
        console.log('[VoiceStreamWS] 收到音频数据:', res.data.byteLength, 'bytes')
        if (this.listeners.onAudioChunk) {
          this.listeners.onAudioChunk(res.data)
        }
        return
      }

      // 文本消息（JSON格式）
      const message = JSON.parse(res.data)
      console.log('[VoiceStreamWS] 收到消息:', message.type)

      switch (message.type) {
        case 'connected':
          console.log('[VoiceStreamWS] 服务器确认连接')
          break
          
        case 'stt_result':
          // STT识别结果
          if (this.listeners.onSttResult) {
            this.listeners.onSttResult(message.message)
          }
          break
          
        case 'llm_token':
          // LLM输出token
          if (this.listeners.onLlmToken) {
            this.listeners.onLlmToken(message.message)
          }
          break
          
        case 'sentence':
          // 完整句子
          if (this.listeners.onSentence) {
            this.listeners.onSentence(message.message)
          }
          break
          
        case 'complete':
          // 对话完成
          if (this.listeners.onComplete) {
            this.listeners.onComplete()
          }
          break
          
        case 'error':
          // 错误
          console.error('[VoiceStreamWS] 服务器错误:', message.message)
          if (this.listeners.onError) {
            this.listeners.onError(message.message)
          }
          break
          
        case 'pong':
          // 心跳响应
          console.log('[VoiceStreamWS] 心跳响应')
          break
          
        default:
          console.warn('[VoiceStreamWS] 未知消息类型:', message.type)
      }
    } catch (err) {
      console.error('[VoiceStreamWS] 处理消息失败:', err)
    }
  }

  /**
   * 发送音频数据
   */
  sendAudio(audioData) {
    if (!this.isConnected || !this.ws) {
      console.error('[VoiceStreamWS] 未连接，无法发送音频')
      return false
    }

    try {
      this.ws.send({
        data: audioData,
        success: () => {
          console.log('[VoiceStreamWS] 音频数据发送成功:', audioData.byteLength, 'bytes')
        },
        fail: (err) => {
          console.error('[VoiceStreamWS] 音频数据发送失败:', err)
          if (this.listeners.onError) {
            this.listeners.onError('发送音频失败')
          }
        }
      })
      return true
    } catch (err) {
      console.error('[VoiceStreamWS] 发送音频异常:', err)
      return false
    }
  }

  /**
   * 发送文本消息
   */
  sendMessage(type, data = null) {
    if (!this.isConnected || !this.ws) {
      console.error('[VoiceStreamWS] 未连接，无法发送消息')
      return false
    }

    try {
      const message = {
        type,
        timestamp: Date.now()
      }
      if (data) {
        message.data = data
      }

      this.ws.send({
        data: JSON.stringify(message),
        success: () => {
          console.log('[VoiceStreamWS] 消息发送成功:', type)
        },
        fail: (err) => {
          console.error('[VoiceStreamWS] 消息发送失败:', err)
        }
      })
      return true
    } catch (err) {
      console.error('[VoiceStreamWS] 发送消息异常:', err)
      return false
    }
  }

  /**
   * 取消当前对话（打断）
   */
  cancel() {
    return this.sendMessage('cancel')
  }

  /**
   * 发送心跳
   */
  ping() {
    return this.sendMessage('ping')
  }

  /**
   * 尝试重连
   */
  tryReconnect() {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.log('[VoiceStreamWS] 达到最大重连次数，停止重连')
      return
    }

    this.reconnectAttempts++
    console.log(`[VoiceStreamWS] 尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})`)

    setTimeout(() => {
      if (!this.isConnected) {
        this.connect().catch(err => {
          console.error('[VoiceStreamWS] 重连失败:', err)
        })
      }
    }, this.reconnectDelay)
  }

  /**
   * 关闭连接
   */
  close() {
    if (this.ws) {
      console.log('[VoiceStreamWS] 主动关闭连接')
      this.manualClose = true  // 标记为主动关闭
      this.isConnected = false
      this.reconnectAttempts = 0  // 重置重连计数
      this.ws.close()
      this.ws = null
    }
  }

  /**
   * 设置事件监听器
   */
  on(event, callback) {
    if (this.listeners.hasOwnProperty(`on${event.charAt(0).toUpperCase()}${event.slice(1)}`)) {
      this.listeners[`on${event.charAt(0).toUpperCase()}${event.slice(1)}`] = callback
    }
  }
}

export default VoiceStreamWebSocket

