/**
 * Coze语音客户端（基于@coze/api官方SDK）
 * 
 * 完全参考：coze-chat-frontend/src/stores/TrainingStore.ts
 * 保持最简洁的实现，避免过度配置
 */

import {
  WsChatClient,
  WsChatEventNames,
  WsToolsUtils,
  ClientEventType,
  type WsChatEventData
} from '@coze/api/ws-tools'

import {
  WebsocketsEventType,
  type ConversationAudioTranscriptCompletedEvent
} from '@coze/api'

export interface CozeVoiceConfig {
  token: string  // PAT Token
  botId: string
  userId: string
  scenePrompt?: string  // 首次连接时的场景提示词
  conversationId?: string  // 暂不支持，需要研究如何传递
}

export type VoiceEventType =
  | 'connected'
  | 'disconnected'
  | 'user_transcript'
  | 'ai_message_delta'
  | 'ai_speaking'
  | 'ai_speech_end'
  | 'error'

export type EventCallback = (data: any) => void

/**
 * Coze语音WebSocket客户端
 * 使用@coze/api官方SDK
 */
export class CozeVoiceClient {
  private client: WsChatClient | null = null
  private eventHandlers: Map<VoiceEventType, EventCallback[]> = new Map()
  private tempContent: string = ''
  private isFirstDelta: boolean = true
  
  /**
   * 初始化并连接（完全参考TrainingStore.ts）
   */
  async connect(config: CozeVoiceConfig): Promise<void> {
    try {
      // 1. 检查麦克风权限
      const permission = await WsToolsUtils.checkDevicePermission()
      if (!permission.audio) {
        throw new Error('需要麦克风权限才能使用语音陪练')
      }
      
      console.log('[CozeVoice] ✅ 麦克风权限检查通过')
      
      // 2. 创建WebSocket客户端（完全参考TrainingStore第94-100行）
      this.client = new WsChatClient({
        token: config.token,  
        baseWsURL: 'wss://ws.coze.cn',  
        allowPersonalAccessTokenInBrowser: true,  
        botId: config.botId,
        audioMutedDefault: false,  // 不静音
        // ⚠️ 不设置enableLocalLoopback，让SDK自动判断（桌面浏览器默认false）
        // enableLocalLoopback: true会导致用户听到自己的声音
        playbackVolumeDefault: 1.0,  // 默认音量
        debug: true
      })
      
      console.log('[CozeVoice] ✅ WebSocket客户端已创建')
      
      // 3. 注册事件监听器
      this.setupEventListeners()
      
      // 4. 连接WebSocket（参考TrainingStore第220行）
      await this.client.connect()
      
      console.log('[CozeVoice] ✅ WebSocket连接成功')
      
      // 5. 设置播放音量（参考TrainingStore第225-227行）
      if (this.client && typeof (this.client as any).setPlaybackVolume === 'function') {
        (this.client as any).setPlaybackVolume(1)
        console.log('[CozeVoice] ✅ 已设置播放音量=1')
      }
      
      // ⚠️ 重要：不要在连接后发送场景提示词！
      // SDK连接时默认设置 need_play_prologue: true，Bot会自动播放开场白
      // 如果手动发送sendTextMessage会干扰开场白播放流程
      // 场景信息应该在Bot的系统提示词中预设
      if (config.scenePrompt) {
        console.log('[CozeVoice] ⚠️ 场景提示词将通过Bot开场白播放，不手动发送')
        console.log('[CozeVoice] 📝 场景提示词:', config.scenePrompt.substring(0, 100) + '...')
      }
      
      console.log('[CozeVoice] 🎉 初始化完成，等待Bot开场白和用户对话...')
      
    } catch (error) {
      console.error('[CozeVoice] ❌ 连接失败:', error)
      throw error
    }
  }
  
  /**
   * 设置事件监听器（参考TrainingStore第108-136行）
   */
  private setupEventListeners(): void {
    if (!this.client) return
    
    // 连接成功
    this.client.on(WsChatEventNames.CONNECTED, () => {
      console.log('[CozeVoice] [事件] WebSocket连接已建立')
      this.emit('connected', {})
    })
    
    // 断开连接
    this.client.on(WsChatEventNames.DISCONNECTED, () => {
      console.log('[CozeVoice] [事件] WebSocket已断开')
      this.emit('disconnected', {})
    })
    
    // 服务器错误
    this.client.on(WsChatEventNames.SERVER_ERROR, (_: string, event: unknown) => {
      console.error('[CozeVoice] [事件] 服务器错误:', event)
      this.emit('error', { error: '服务器错误' })
    })
    
    // 所有消息事件（参考TrainingStore第135行）
    this.client.on(WsChatEventNames.ALL, (eventName: string, event: WsChatEventData) => {
      this.handleMessageEvent(eventName, event)
    })
  }
  
  /**
   * 处理消息事件（参考TrainingStore第139-203行）
   */
  private handleMessageEvent(eventName: string, event: WsChatEventData): void {
    // 忽略CONNECTED事件（参考TrainingStore第140-143行）
    if (eventName === WsChatEventNames.CONNECTED) {
      return
    }
    
    if (!event) return
    
    // 🔍 调试：打印所有收到的事件（详细日志）
    console.log('[CozeVoice] 📨 收到事件:', eventName, '-> event_type:', event.event_type)
    console.log('[CozeVoice] 📨 事件数据:', JSON.stringify(event.data || {}).substring(0, 200))
    
    switch (event.event_type) {
      // 用户开始说话 - 关闭扬声器本地回放（避免用户听到自己的声音）
      case 'input_audio_buffer.speech_started': {
        console.log('[CozeVoice] 🎤 用户开始说话')
        // 关闭本地回放（避免扬声器播放用户自己的声音）
        const wavStreamPlayer = (this.client as any)?.wavStreamPlayer
        if (wavStreamPlayer && typeof wavStreamPlayer.setLocalLoopbackEnable === 'function') {
          wavStreamPlayer.setLocalLoopbackEnable(false)
          console.log('[CozeVoice] 🔇 已关闭扬声器本地回放')
        }
        break
      }
      
      // 用户停止说话
      case 'input_audio_buffer.speech_stopped': {
        console.log('[CozeVoice] 🎤 用户停止说话，等待识别...')
        break
      }
      
      // 用户语音转文字完成（参考TrainingStore第148-158行）
      case WebsocketsEventType.CONVERSATION_AUDIO_TRANSCRIPT_COMPLETED: {
        const { content } = (event as ConversationAudioTranscriptCompletedEvent).data
        console.log('[CozeVoice] 🎤 用户说:', content)
        this.emit('user_transcript', { content })
        break
      }
      
      // AI开始语音回复 - 确保扬声器打开
      case 'conversation.audio.sentence_start': {
        // 恢复扬声器（播放AI声音）
        const wavStreamPlayer = (this.client as any)?.wavStreamPlayer
        if (wavStreamPlayer && typeof wavStreamPlayer.setLocalLoopbackEnable === 'function') {
          wavStreamPlayer.setLocalLoopbackEnable(false)  // 保持false，只播放AI不播放用户
          console.log('[CozeVoice] 🔊 AI开始说话')
        }
        break
      }
      
      // AI文字回复增量（参考TrainingStore第160-180行）
      case WebsocketsEventType.CONVERSATION_MESSAGE_DELTA: {
        if (event.data.content) {
          const content = this.tempContent + event.data.content
          this.tempContent = content
          
          this.emit('ai_message_delta', {
            content: event.data.content,
            fullContent: content,
            isFirst: this.isFirstDelta
          })
          
          if (this.isFirstDelta) {
            this.isFirstDelta = false
          }
        }
        break
      }
      
      // AI消息完成（参考TrainingStore第181-187行）
      case WebsocketsEventType.CONVERSATION_MESSAGE_COMPLETED: {
        this.isFirstDelta = true
        this.tempContent = ''
        break
      }
      
      // AI语音增量（参考TrainingStore第189-193行）
      case WebsocketsEventType.CONVERSATION_AUDIO_DELTA: {
        this.emit('ai_speaking', {})
        break
      }
      
      // 音频播放结束（参考TrainingStore第195-199行）
      case ClientEventType.AUDIO_SENTENCE_PLAYBACK_ENDED: {
        this.emit('ai_speech_end', {})
        break
      }
      
      // 🔍 调试：捕获服务器错误事件
      case 'error': {
        console.error('[CozeVoice] ❌ 服务器返回错误:', event)
        this.emit('error', { error: event.data?.error || '未知错误' })
        break
      }
      
      // 对话创建事件
      case WebsocketsEventType.CONVERSATION_CHAT_CREATED: {
        console.log('[CozeVoice] ✅ 对话创建成功')
        break
      }
      
      // 对话进行中
      case 'conversation.chat.in_progress': {
        console.log('[CozeVoice] 🔄 AI正在思考...')
        break
      }
      
      // 对话失败事件
      case 'conversation.chat.failed': {
        console.error('[CozeVoice] ❌ 对话失败:', event)
        this.emit('error', { error: event.data?.last_error?.msg || '对话失败' })
        break
      }
      
      // 对话完成事件
      case 'conversation.chat.completed': {
        console.log('[CozeVoice] ✅ 对话完成')
        break
      }
      
      // 默认处理：记录未知事件
      default: {
        console.log('[CozeVoice] ⚠️ 未处理的事件类型:', event.event_type)
      }
    }
  }
  
  /**
   * 注册事件监听器
   */
  on(eventType: VoiceEventType, callback: EventCallback): void {
    if (!this.eventHandlers.has(eventType)) {
      this.eventHandlers.set(eventType, [])
    }
    this.eventHandlers.get(eventType)!.push(callback)
  }
  
  /**
   * 移除事件监听器
   */
  off(eventType: VoiceEventType, callback: EventCallback): void {
    const handlers = this.eventHandlers.get(eventType)
    if (handlers) {
      const index = handlers.indexOf(callback)
      if (index > -1) {
        handlers.splice(index, 1)
      }
    }
  }
  
  /**
   * 触发事件
   */
  private emit(eventType: VoiceEventType, data: any): void {
    const handlers = this.eventHandlers.get(eventType)
    if (handlers) {
      handlers.forEach(callback => callback(data))
    }
  }
  
  /**
   * 打断AI回复（参考TrainingStore第206-212行）
   */
  interrupt(): void {
    if (this.client) {
      this.client.interrupt()
      console.log('[CozeVoice] ⏸️ 已打断AI回复')
    }
  }
  
  /**
   * 断开连接（参考TrainingStore第235-244行）
   */
  async disconnect(): Promise<void> {
    if (this.client) {
      await this.client.disconnect()
      this.client = null
      console.log('[CozeVoice] ✅ 已断开连接')
    }
    
    // 清空事件处理器
    this.eventHandlers.clear()
    this.tempContent = ''
    this.isFirstDelta = true
  }
  
  /**
   * 获取连接状态
   */
  isConnected(): boolean {
    return this.client !== null
  }
}

/**
 * 检查麦克风权限（使用@coze/api工具）
 */
export async function checkMicrophonePermission(): Promise<boolean> {
  try {
    const permission = await WsToolsUtils.checkDevicePermission()
    return permission.audio === true
  } catch (error) {
    console.error('麦克风权限检查失败:', error)
    return false
  }
}
