import { ref } from 'vue'
import type { RTCConnectionState } from '@/types'

// RTC 连接参数
interface RTCConnectParams {
  appId: string
  roomId: string
  userId: string
  token: string
  sessionId?: string  // 面试会话 ID，用于传递给工作流
}

/**
 * 火山引擎 RTC Hook
 * 封装 RTC 连接、断开、静音、TTS 发送等操作
 */
export function useRTC() {
  const connectionState = ref<RTCConnectionState>('disconnected')
  const isMuted = ref(false)
  const isReceiveOnly = ref(false)  // 仅接收模式
  const isTTSSending = ref(false)   // TTS 正在发送

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  let engine: any = null
  let audioContext: AudioContext | null = null
  let ttsDestination: MediaStreamAudioDestinationNode | null = null

  /**
   * 初始化 TTS 音频上下文
   * 创建一个虚拟音频目标，用于捕获 TTS 输出
   */
  function initTTSAudio() {
    if (!audioContext) {
      audioContext = new AudioContext()
      ttsDestination = audioContext.createMediaStreamDestination()
      console.log('TTS audio context initialized')
    }
  }

  /**
   * 连接 RTC 房间（TTS 模式：使用 TTS 模拟语音输入）
   * 
   * 工作原理：
   * 1. 创建虚拟音频设备（MediaStreamAudioDestinationNode）
   * 2. TTS 输出连接到虚拟设备
   * 3. RTC 从虚拟设备采集音频发送
   */
  async function connectTTSMode(params: RTCConnectParams) {
    try {
      connectionState.value = 'connecting'
      isReceiveOnly.value = false  // TTS 模式可以发送

      // 初始化 TTS 音频
      initTTSAudio()

      // 动态导入 RTC SDK
      console.log('Loading RTC SDK (TTS mode)...')
      const VERTC = await import('@volcengine/rtc')

      // 创建引擎
      console.log('Creating RTC engine with appId:', params.appId)
      engine = VERTC.default.createEngine(params.appId)

      // 监听事件
      engine.on('onUserJoined', (event: { userId: string }) => {
        console.log('User joined:', event.userId)
      })

      engine.on('onUserLeave', (event: { userId: string }) => {
        console.log('User left:', event.userId)
      })

      engine.on('onError', (error: Error) => {
        console.error('RTC error:', error)
        connectionState.value = 'failed'
      })

      engine.on('onRoomStateChanged', (event: { state: number; errorCode: number }) => {
        console.log('Room state changed:', event)
      })

      // 监听远端音频（AI 的回复）
      engine.on('onRemoteAudioPropertiesReport', (event: any) => {
        if (event && event.length > 0) {
          console.log('AI is speaking:', event)
        }
      })

      // 加入房间
      console.log('Joining room (TTS mode):', params.roomId)
      await engine.joinRoom(
        params.token,
        params.roomId,
        {
          userId: params.userId,
        },
        {
          isAutoPublish: true,   // 自动发布（TTS 音频）
          isAutoSubscribeAudio: true,  // 接收 AI 语音
          isAutoSubscribeVideo: false,
        }
      )

      // 设置自定义音频轨道
      if (ttsDestination) {
        const stream = ttsDestination.stream
        const audioTrack = stream.getAudioTracks()[0]
        
        if (audioTrack) {
          console.log('Setting custom audio track for TTS...')
          // 使用 setAudioTrack 或 replaceTrack API
          try {
            // 方法1: 尝试使用 setCustomizeAudioTrack
            if (engine.setCustomizeAudioTrack) {
              await engine.setCustomizeAudioTrack(audioTrack)
              console.log('Custom audio track set via setCustomizeAudioTrack')
            }
            // 方法2: 尝试使用外部音频采集
            else if (engine.setExternalAudioSource) {
              await engine.setExternalAudioSource(true, 48000, 1)
              console.log('External audio source enabled')
            }
            // 方法3: 开始采集但不使用默认设备
            else {
              console.log('Using default audio capture (TTS may not work)')
            }
          } catch (e) {
            console.warn('Failed to set custom audio track:', e)
          }
        }
      }

      // 开始音频采集（使用静音或自定义源）
      try {
        await engine.startAudioCapture()
        console.log('Audio capture started')
      } catch (e) {
        console.warn('Audio capture failed (expected in TTS mode):', e)
      }

      connectionState.value = 'connected'
      console.log('RTC connected successfully (TTS mode)')
    } catch (error: any) {
      console.error('RTC connect error:', error)
      connectionState.value = 'failed'
      throw error
    }
  }

  /**
   * 使用 TTS 发送文字到 RTC 房间
   * 将文字转换为语音并通过 RTC 发送
   */
  async function sendTTSMessage(text: string): Promise<void> {
    if (!audioContext || !ttsDestination) {
      console.error('TTS audio not initialized')
      return
    }

    isTTSSending.value = true

    return new Promise((resolve, reject) => {
      if (!window.speechSynthesis) {
        isTTSSending.value = false
        reject(new Error('浏览器不支持语音合成'))
        return
      }

      const utterance = new SpeechSynthesisUtterance(text)
      utterance.lang = 'zh-CN'
      utterance.rate = 1.0
      utterance.pitch = 1.0
      utterance.volume = 1.0

      // 选择中文语音
      const voices = window.speechSynthesis.getVoices()
      const chineseVoice = voices.find(v => v.lang.includes('zh'))
      if (chineseVoice) {
        utterance.voice = chineseVoice
      }

      utterance.onend = () => {
        console.log('TTS finished:', text)
        isTTSSending.value = false
        resolve()
      }

      utterance.onerror = (event) => {
        console.error('TTS error:', event)
        isTTSSending.value = false
        reject(new Error('语音合成失败'))
      }

      console.log('TTS speaking:', text)
      window.speechSynthesis.speak(utterance)
    })
  }

  /**
   * 连接 RTC 房间（正常麦克风模式）
   */
  async function connect(params: RTCConnectParams) {
    try {
      connectionState.value = 'connecting'
      isReceiveOnly.value = false

      // 1. 先请求麦克风权限
      console.log('Requesting microphone permission...')
      await requestMicrophonePermission()

      // 2. 动态导入 RTC SDK
      console.log('Loading RTC SDK...')
      const VERTC = await import('@volcengine/rtc')

      // 3. 创建引擎
      console.log('Creating RTC engine with appId:', params.appId)
      engine = VERTC.default.createEngine(params.appId)

      // 4. 监听事件
      engine.on('onUserJoined', (event: { userId: string }) => {
        console.log('User joined:', event.userId)
      })

      engine.on('onUserLeave', (event: { userId: string }) => {
        console.log('User left:', event.userId)
      })

      engine.on('onError', (error: Error) => {
        console.error('RTC error:', error)
        connectionState.value = 'failed'
      })

      engine.on('onRoomStateChanged', (event: { state: number; errorCode: number }) => {
        console.log('Room state changed:', event)
      })

      // 5. 加入房间
      console.log('Joining room:', params.roomId)
      await engine.joinRoom(
        params.token,
        params.roomId,
        {
          userId: params.userId,
        },
        {
          isAutoPublish: true,
          isAutoSubscribeAudio: true,
          isAutoSubscribeVideo: false,
        }
      )

      // 6. 开始音频采集
      console.log('Starting audio capture...')
      await engine.startAudioCapture()

      // 7. 发送 session.update 事件，传递 session_id 给工作流
      if (params.sessionId) {
        console.log('Sending session.update event with session_id:', params.sessionId)
        await sendSessionUpdate(engine, params.sessionId)
      }

      connectionState.value = 'connected'
      console.log('RTC connected successfully')
    } catch (error: any) {
      console.error('RTC connect error:', error)
      connectionState.value = 'failed'
      throw error
    }
  }

  /**
   * 断开 RTC 连接
   */
  async function disconnect() {
    try {
      if (engine) {
        try {
          await engine.stopAudioCapture()
        } catch (e) {
          console.warn('Stop audio capture failed:', e)
        }
        await engine.leaveRoom()
        engine.destroy()
        engine = null
      }
      
      // 清理 TTS 音频上下文
      if (audioContext) {
        await audioContext.close()
        audioContext = null
        ttsDestination = null
      }
      
      connectionState.value = 'disconnected'
      isReceiveOnly.value = false
      isTTSSending.value = false
      console.log('RTC disconnected')
    } catch (error) {
      console.error('RTC disconnect error:', error)
    }
  }

  /**
   * 切换静音状态
   */
  function toggleMute(mute: boolean) {
    if (engine) {
      if (mute) {
        engine.muteLocalAudio()
      } else {
        engine.unmuteLocalAudio()
      }
      isMuted.value = mute
    }
  }

  return {
    connectionState,
    isMuted,
    isReceiveOnly,
    isTTSSending,
    connect,
    connectTTSMode,
    disconnect,
    toggleMute,
    sendTTSMessage,
  }
}

/**
 * 发送 session.update 事件，将 session_id 传递给 Coze 工作流
 * 
 * 在 Coze RTC 语音模式下，需要通过此事件传递自定义参数
 * 工作流可以通过入参获取 session_id
 * 
 * 根据 Coze 文档，事件需要通过信令通道发送
 */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async function sendSessionUpdate(engine: any, sessionId: string): Promise<void> {
  try {
    // 构造 session.update 事件（Coze 标准格式）
    const eventData = {
      id: `event_${Date.now()}`,
      event_type: 'session.update',
      data: {
        chat_config: {
          parameters: {
            session_id: sessionId,
          },
        },
      },
    }

    const eventJson = JSON.stringify(eventData)
    console.log('Sending session.update event:', eventData)

    // 尝试多种方式发送事件到 Coze

    // 方法1: sendStreamSyncInfo (火山引擎 RTC 流同步信息)
    if (engine.sendStreamSyncInfo) {
      try {
        const encoder = new TextEncoder()
        const data = encoder.encode(eventJson)
        await engine.sendStreamSyncInfo(data, { repeatCount: 3 })
        console.log('session.update sent via sendStreamSyncInfo')
        return
      } catch (e) {
        console.warn('sendStreamSyncInfo failed:', e)
      }
    }

    // 方法2: sendSEIMessage (Supplemental Enhancement Information)
    if (engine.sendSEIMessage) {
      try {
        const encoder = new TextEncoder()
        const data = encoder.encode(eventJson)
        // streamIndex: 0 表示主流，1 表示屏幕流
        await engine.sendSEIMessage(0, data, { repeatCount: 3 })
        console.log('session.update sent via sendSEIMessage')
        return
      } catch (e) {
        console.warn('sendSEIMessage failed:', e)
      }
    }

    // 方法3: sendPublicStreamSEIMessage
    if (engine.sendPublicStreamSEIMessage) {
      try {
        const encoder = new TextEncoder()
        const data = encoder.encode(eventJson)
        await engine.sendPublicStreamSEIMessage(data)
        console.log('session.update sent via sendPublicStreamSEIMessage')
        return
      } catch (e) {
        console.warn('sendPublicStreamSEIMessage failed:', e)
      }
    }

    // 方法4: sendRoomMessage (房间消息)
    if (engine.sendRoomMessage) {
      try {
        await engine.sendRoomMessage(eventJson)
        console.log('session.update sent via sendRoomMessage')
        return
      } catch (e) {
        console.warn('sendRoomMessage failed:', e)
      }
    }

    // 方法5: sendUserMessage (用户消息)
    if (engine.sendUserMessage) {
      try {
        // 发送给 AI Bot（Coze Bot 在房间中的用户 ID 通常以 bot_ 或 uid_ 开头）
        await engine.sendUserMessage('', eventJson)  // 空字符串表示广播
        console.log('session.update sent via sendUserMessage')
        return
      } catch (e) {
        console.warn('sendUserMessage failed:', e)
      }
    }

    // 方法6: 尝试直接调用 engine 上的其他方法
    console.log('Available engine methods:', Object.keys(engine).filter(k => typeof engine[k] === 'function'))
    
    console.warn('No suitable method found to send session.update event. Coze may not receive the parameters.')
  } catch (error) {
    console.error('Failed to send session.update:', error)
  }
}

/**
 * 请求麦克风权限
 */
async function requestMicrophonePermission(): Promise<boolean> {
  try {
    if (navigator.permissions) {
      const result = await navigator.permissions.query({ name: 'microphone' as PermissionName })
      console.log('Microphone permission status:', result.state)
      
      if (result.state === 'denied') {
        throw new Error('麦克风权限被拒绝，请在浏览器设置中允许访问麦克风')
      }
    }

    const stream = await navigator.mediaDevices.getUserMedia({ 
      audio: {
        echoCancellation: true,
        noiseSuppression: true,
        autoGainControl: true,
      }
    })
    
    stream.getTracks().forEach(track => track.stop())
    
    console.log('Microphone permission granted')
    return true
  } catch (error: any) {
    console.error('Microphone permission error:', error)
    
    if (error.name === 'NotAllowedError') {
      throw new Error('请允许使用麦克风以进行语音面试。如果您已拒绝，请在浏览器地址栏左侧的锁图标中重新授权。')
    } else if (error.name === 'NotFoundError') {
      throw new Error('未检测到麦克风设备，请确保您的设备已连接麦克风。')
    } else {
      throw new Error(`麦克风权限获取失败: ${error.message}`)
    }
  }
}
