<script setup lang="ts">
import { ref, onMounted, onUnmounted, computed, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { candidateApi } from '@/api'
import { useCozeRealtime } from '@/composables/useCozeRealtime'

// 聊天容器 ref
const chatContainer = ref<HTMLElement | null>(null)

const router = useRouter()

// 从 sessionStorage 获取模式和 session_id
const interviewMode = ref<'voice' | 'text'>('voice')
const sessionId = ref('')
const candidateName = ref('')

// 状态
const step = ref<'incoming' | 'incall'>('incoming')
const callDuration = ref(0)
const isMuted = ref(false)
const isAISpeaking = ref(false)
const isConnecting = ref(false)
let durationTimer: number | null = null

// 文字对话相关
const textInput = ref('')
const chatHistory = ref<Array<{ role: 'user' | 'ai'; content: string }>>([])
const isSending = ref(false)
const conversationId = ref('')

// 调试信息（默认隐藏，连按7次'd'键打开）
const showDebug = ref(false)
const debugInfo = ref<any>({})
const initDebugInfo = ref<any>(null)
let debugKeyPressCount = 0
let debugKeyPressTimer: number | null = null

// Coze Realtime Hook（语音模式使用）
// 该 Hook 封装了 RTC 连接和 session.update 事件发送
const {
  connectionState,
  connect,
  disconnect,
  toggleMute,
  interrupt,
  commitAudioInput,
  isSessionUpdateSent,
  debugSummary: cozeDebugSummary,
  timeline: cozeTimeline,  // 通讯时间线
  isSpeaking,              // 本地 VAD: 用户是否正在说话
  isAISpeaking: cozeIsAISpeaking,  // AI 是否正在说话
  currentVolume,           // 本地 VAD: 当前音量
} = useCozeRealtime()

// 初始化
onMounted(() => {
  // 读取 sessionStorage
  sessionId.value = sessionStorage.getItem('sessionId') || ''
  candidateName.value = sessionStorage.getItem('candidateName') || ''
  const mode = sessionStorage.getItem('interviewMode') as 'voice' | 'text'
  if (mode) {
    interviewMode.value = mode
  }
  
  // 读取初始化调试信息
  const initDebugStr = sessionStorage.getItem('initDebugInfo')
  if (initDebugStr) {
    try {
      initDebugInfo.value = JSON.parse(initDebugStr)
    } catch (e) {
      console.error('Failed to parse initDebugInfo:', e)
    }
  }
  
  // 更新调试信息
  debugInfo.value = {
    sessionId: sessionId.value,
    candidateName: candidateName.value,
    interviewMode: interviewMode.value,
    initDebugInfo: initDebugInfo.value,
    chatHistory: [],
    lastApiResponse: null,
  }

  // 验证必要参数
  if (!sessionId.value) {
    ElMessage.error('会话信息丢失，请重新开始')
    debugInfo.value.error = 'sessionId is empty!'
    router.push('/')
    return
  }

  console.log(`🎯 Interview mode: ${interviewMode.value}, sessionId: ${sessionId.value}`)
  
  // 添加调试快捷键监听（连按7次'd'键打开调试面板）
  window.addEventListener('keydown', handleDebugKeyPress)
})

// 处理调试快捷键
function handleDebugKeyPress(e: KeyboardEvent) {
  if (e.key.toLowerCase() === 'd') {
    debugKeyPressCount++
    
    // 清除之前的定时器
    if (debugKeyPressTimer) {
      clearTimeout(debugKeyPressTimer)
    }
    
    // 2秒内没有继续按则重置计数
    debugKeyPressTimer = window.setTimeout(() => {
      debugKeyPressCount = 0
    }, 2000)
    
    // 连按7次打开调试面板
    if (debugKeyPressCount >= 7) {
      showDebug.value = !showDebug.value
      debugKeyPressCount = 0
      console.log(`🔧 Debug panel ${showDebug.value ? 'opened' : 'closed'}`)
    }
  }
}

// 组件卸载时移除事件监听
onUnmounted(() => {
  window.removeEventListener('keydown', handleDebugKeyPress)
  if (debugKeyPressTimer) {
    clearTimeout(debugKeyPressTimer)
  }
})

// 格式化通话时长
const formattedDuration = computed(() => {
  const minutes = Math.floor(callDuration.value / 60)
  const seconds = callDuration.value % 60
  return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`
})

// 开始计时
function startTimer() {
  durationTimer = window.setInterval(() => {
    callDuration.value++
  }, 1000)
}

// 语音模式调试信息
const voiceDebugInfo = ref<any>(null)

// ==================== 语音模式 ====================
async function handleAnswerVoice() {
  if (isConnecting.value) return
  isConnecting.value = true

  try {
    // 1. 获取 Coze Realtime SDK 配置
    console.log('🔧 Step 1: Getting Coze config...')
    const configResponse = await candidateApi.getCozeConfig()
    const cozeConfig = configResponse.data
    
    console.log('✅ Coze config received:', {
      botId: cozeConfig.botId,
      voiceId: cozeConfig.voiceId,
      hasToken: !!cozeConfig.accessToken,
    })

    // 保存调试信息
    voiceDebugInfo.value = {
      botId: cozeConfig.botId,
      voiceId: cozeConfig.voiceId,
      sessionId: sessionId.value,
      method: 'Coze Realtime SDK',
    }
    debugInfo.value.cozeConfig = cozeConfig
    debugInfo.value.voiceDebugInfo = voiceDebugInfo.value

    // 2. 使用 Coze Realtime SDK 连接
    console.log('🎤 Step 2: Connecting with Coze Realtime SDK...')
    await connect({
      accessToken: cozeConfig.accessToken,
      botId: cozeConfig.botId,
      sessionId: sessionId.value,  // 关键：传递 session_id 给工作流
      voiceId: cozeConfig.voiceId,
    })

    step.value = 'incall'
    startTimer()

    // 模拟 AI 说话动画
    simulateAISpeaking()
  } catch (error: unknown) {
    const errorMessage = error instanceof Error ? error.message : String(error)
    console.error('Connect voice error:', error)
    debugInfo.value.voiceError = {
      message: errorMessage,
      timestamp: new Date().toISOString()
    }
    ElMessage.error(errorMessage || '连接失败，请检查麦克风权限')
  } finally {
    isConnecting.value = false
  }
}

// 模拟 AI 说话动画
let speakingTimer: number | null = null
function simulateAISpeaking() {
  speakingTimer = window.setInterval(() => {
    isAISpeaking.value = !isAISpeaking.value
  }, 3000)
}

// ==================== 文字模式 ====================
async function handleAnswerText() {
  if (isConnecting.value) return
  isConnecting.value = true

  try {
    step.value = 'incall'
    startTimer()

    // 发送开始面试消息
    chatHistory.value.push({
      role: 'ai',
      content: '📝 文字面试模式已开启\n\n您好！我是 AI 面试官。请输入"开始"来开始面试。'
    })
  } catch (error: any) {
    console.error('Start text interview error:', error)
    ElMessage.error(error.message || '启动失败')
  } finally {
    isConnecting.value = false
  }
}

// 发送文字消息
async function sendTextMessage() {
  if (!textInput.value.trim() || isSending.value) return

  const message = textInput.value.trim()
  textInput.value = ''
  isSending.value = true

  // 添加用户消息并滚动
  chatHistory.value.push({ role: 'user', content: message })
  scrollToBottom()
  
  // 更新调试信息
  debugInfo.value.lastRequest = {
    sessionId: sessionId.value,
    message: message,
    conversationId: conversationId.value,
    timestamp: new Date().toISOString()
  }

  try {
    // 调用 chat API，传入 sessionId
    const response = await candidateApi.chat({
      sessionId: sessionId.value,
      message: message,
      conversationId: conversationId.value || undefined,
    })
    
    // 更新调试信息
    debugInfo.value.lastApiResponse = response.data
    debugInfo.value.chatHistory = chatHistory.value.slice()

    // 保存 conversationId
    if (response.data.conversationId) {
      conversationId.value = response.data.conversationId
      debugInfo.value.conversationId = response.data.conversationId
    }

    // 添加 AI 回复并滚动
    chatHistory.value.push({ role: 'ai', content: response.data.reply })
    scrollToBottom()
  } catch (error: any) {
    console.error('Send message error:', error)
    debugInfo.value.lastError = {
      message: error.message,
      response: error.response?.data,
      status: error.response?.status,
      timestamp: new Date().toISOString()
    }
    ElMessage.error(error.message || '发送失败')
    chatHistory.value.pop()
  } finally {
    isSending.value = false
    scrollToBottom()
  }
}

function scrollToBottom() {
  nextTick(() => {
    if (chatContainer.value) {
      chatContainer.value.scrollTo({
        top: chatContainer.value.scrollHeight,
        behavior: 'smooth'
      })
    }
  })
}

// 复制调试信息
function copyDebugInfo() {
  const info = {
    sessionId: sessionId.value,
    conversationId: conversationId.value,
    interviewMode: interviewMode.value,
    candidateName: candidateName.value,
    chatHistoryCount: chatHistory.value.length,
    ...debugInfo.value,
    initDebugInfo: initDebugInfo.value,
  }
  navigator.clipboard.writeText(JSON.stringify(info, null, 2))
    .then(() => ElMessage.success('已复制调试信息'))
    .catch(() => ElMessage.error('复制失败'))
}

// ==================== 通用操作 ====================

// 接听（根据模式）
function handleAnswer() {
  if (interviewMode.value === 'voice') {
    handleAnswerVoice()
  } else {
    handleAnswerText()
  }
}

// 挂断
async function handleHangup() {
  if (durationTimer) clearInterval(durationTimer)
  if (speakingTimer) clearInterval(speakingTimer)

  try {
    // 语音模式断开 RTC
    if (interviewMode.value === 'voice') {
      await disconnect()
    }

    // 通知后端结束面试
    if (sessionId.value) {
      await candidateApi.endInterview(sessionId.value)
    }
  } catch (error) {
    console.error('Hangup error:', error)
  }

  // 清除 sessionStorage
  sessionStorage.removeItem('sessionId')
  sessionStorage.removeItem('candidateName')
  sessionStorage.removeItem('interviewMode')

  router.push('/complete')
}

// 拒接
function handleReject() {
  sessionStorage.removeItem('sessionId')
  sessionStorage.removeItem('candidateName')
  sessionStorage.removeItem('interviewMode')
  router.push('/')
}

// 切换麦克风静音（仅语音模式）
function handleToggleMute() {
  isMuted.value = !isMuted.value
  toggleMute(isMuted.value)
  console.log(`🎤 麦克风: ${isMuted.value ? '已关闭' : '已开启'}`)
}

// 说完了 - 手动触发 VAD 结束，告诉服务器用户已说完
async function handleFinishSpeaking() {
  if (isMuted.value) return
  
  console.log('✋ 用户点击"说完了"，发送 commit 信令...')
  
  // 方案 1: 发送 commit 信令
  const committed = commitAudioInput()
  
  // 方案 2: 如果 commit 不支持，同时短暂静音麦克风触发 VAD
  if (!committed) {
    console.log('📢 使用备用方案：短暂静音触发 VAD')
    await toggleMute(true)
    isMuted.value = true
    
    // 300ms 后自动恢复麦克风（比 VAD 静音阈值短）
    setTimeout(async () => {
      await toggleMute(false)
      isMuted.value = false
      console.log('🎤 麦克风已自动恢复')
    }, 300)
  }
}

// 打断 AI 说话
function handleInterrupt() {
  console.log('🛑 用户打断 AI')
  interrupt()
  isAISpeaking.value = false
}

// 清理
onUnmounted(() => {
  if (durationTimer) clearInterval(durationTimer)
  if (speakingTimer) clearInterval(speakingTimer)
  disconnect()
})
</script>

<template>
  <div class="call-page w-full max-w-lg h-full flex flex-col">
    <!-- 来电界面 -->
    <div v-if="step === 'incoming'" class="incoming-call text-center">
      <!-- 来电动画 -->
      <div class="relative mb-8">
        <div class="pulse-ring w-32 h-32 mx-auto rounded-full flex items-center justify-center"
          :class="interviewMode === 'voice' 
            ? 'bg-gradient-to-br from-green-400 to-green-600' 
            : 'bg-gradient-to-br from-blue-400 to-blue-600'"
        >
          <el-icon :size="56" class="text-white animate-ring">
            <Microphone v-if="interviewMode === 'voice'" />
            <ChatLineSquare v-else />
          </el-icon>
        </div>
      </div>

      <!-- 来电信息 -->
      <h2 class="text-2xl font-bold text-gray-800 mb-2">AI 面试官</h2>
      <p class="text-gray-500 mb-2">{{ candidateName || '候选人' }}</p>
      <el-tag :type="interviewMode === 'voice' ? 'success' : 'primary'" size="small" class="mb-8">
        {{ interviewMode === 'voice' ? '🎤 语音面试' : '📝 文字面试' }}
      </el-tag>

      <!-- 操作按钮 -->
      <div class="flex justify-center gap-8">
        <div class="text-center">
          <el-button
            class="w-16 h-16 rounded-full"
            type="danger"
            :disabled="isConnecting"
            @click="handleReject"
          >
            <el-icon :size="28"><Close /></el-icon>
          </el-button>
          <p class="text-sm text-gray-500 mt-2">取消</p>
        </div>

        <div class="text-center">
          <el-button
            class="w-16 h-16 rounded-full"
            type="success"
            :loading="isConnecting"
            @click="handleAnswer"
          >
            <el-icon v-if="!isConnecting" :size="28"><Phone /></el-icon>
          </el-button>
          <p class="text-sm text-gray-500 mt-2">{{ isConnecting ? '连接中' : '开始' }}</p>
        </div>
      </div>
    </div>

    <!-- 通话中界面 -->
    <div v-else class="in-call">
      <!-- 头部信息 -->
      <div class="text-center mb-4">
        <div class="w-16 h-16 mx-auto rounded-full flex items-center justify-center mb-2"
          :class="interviewMode === 'voice' 
            ? 'bg-gradient-to-br from-green-500 to-green-600' 
            : 'bg-gradient-to-br from-blue-500 to-indigo-600'"
        >
          <el-icon :size="28" class="text-white">
            <Microphone v-if="interviewMode === 'voice'" />
            <ChatLineSquare v-else />
          </el-icon>
        </div>
        <h2 class="text-xl font-bold text-gray-800">AI 面试官</h2>
        <p class="text-gray-500 text-sm">{{ formattedDuration }}</p>
        <el-tag :type="interviewMode === 'voice' ? 'success' : 'primary'" size="small" class="mt-1">
          {{ interviewMode === 'voice' ? '🎤 语音对话中' : '📝 文字对话中' }}
        </el-tag>
      </div>

      <!-- ==================== 文字模式 ==================== -->
      <div v-if="interviewMode === 'text'" class="text-mode">
        <!-- 聊天历史 -->
        <div ref="chatContainer" class="chat-history bg-gray-50 rounded-lg p-4 overflow-y-auto mb-4">
          <div
            v-for="(msg, index) in chatHistory"
            :key="index"
            class="mb-3"
            :class="msg.role === 'user' ? 'text-right' : 'text-left'"
          >
            <div
              class="inline-block max-w-[80%] px-4 py-2 rounded-2xl text-sm whitespace-pre-wrap"
              :class="msg.role === 'user'
                ? 'bg-blue-500 text-white rounded-br-md'
                : 'bg-white text-gray-800 rounded-bl-md shadow-sm'"
            >
              {{ msg.content }}
            </div>
          </div>
          <div v-if="isSending" class="text-left">
            <div class="inline-block bg-white text-gray-400 px-4 py-2 rounded-2xl rounded-bl-md shadow-sm text-sm">
              AI 正在思考...
            </div>
          </div>
        </div>

        <!-- 输入区域 -->
        <div class="flex gap-2 mb-4">
          <el-input
            v-model="textInput"
            placeholder="输入您的回答..."
            :disabled="isSending"
            @keyup.enter="sendTextMessage"
          />
          <el-button
            type="primary"
            :loading="isSending"
            @click="sendTextMessage"
          >
            发送
          </el-button>
        </div>
      </div>

      <!-- ==================== 语音模式 ==================== -->
      <div v-else class="voice-mode text-center">
        <!-- 连接状态 -->
        <div class="mb-4">
          <el-tag v-if="connectionState === 'connected'" type="success" size="small">✓ 已连接</el-tag>
          <el-tag v-else-if="connectionState === 'connecting'" type="warning" size="small">连接中...</el-tag>
          <el-tag v-else type="info" size="small">{{ connectionState }}</el-tag>
          <el-tag v-if="isSpeaking" type="warning" size="small" class="ml-2">🎤 说话中</el-tag>
          <el-tag v-else-if="cozeIsAISpeaking" type="info" size="small" class="ml-2">🔊 AI说话中</el-tag>
          <el-tag v-else-if="connectionState === 'connected'" type="success" size="small" class="ml-2">🎙️ 等待中</el-tag>
        </div>

        <!-- 音量指示器 -->
        <div class="volume-indicator mb-4">
          <div class="volume-bar-container">
            <div 
              class="volume-bar" 
              :style="{ width: `${Math.min(currentVolume * 500, 100)}%` }"
              :class="{ 'speaking': isSpeaking }"
            ></div>
            <!-- 阈值线 (15%) -->
            <div class="threshold-line" :style="{ left: `${0.15 * 500}%` }"></div>
          </div>
          <span class="text-xs ml-2 text-gray-400">{{ (currentVolume * 100).toFixed(0) }}%</span>
        </div>

        <!-- 语音波形 -->
        <div class="h-16 flex items-center justify-center mb-6">
          <div v-if="isAISpeaking" class="audio-wave">
            <span></span><span></span><span></span><span></span><span></span>
          </div>
          <div v-else-if="isSpeaking" class="user-speaking">
            <span>🎤</span>
            <span class="text-sm text-yellow-500 ml-2">正在录音...</span>
          </div>
          <p v-else class="text-gray-400">{{ connectionState === 'connected' ? '请开始说话...' : '等待连接...' }}</p>
        </div>

        <!-- 控制按钮区 -->
        <div class="flex justify-center gap-8 mb-6">
          <!-- 麦克风开关（控制我的麦克风） -->
          <div class="text-center">
            <el-button
              class="w-14 h-14 rounded-full"
              :type="isMuted ? 'danger' : 'success'"
              @click="handleToggleMute"
            >
              <el-icon :size="24">
                <Mute v-if="isMuted" />
                <Microphone v-else />
              </el-icon>
            </el-button>
            <p class="text-xs mt-2" :class="isMuted ? 'text-red-500' : 'text-green-500'">
              {{ isMuted ? '麦克风已关' : '麦克风开启' }}
            </p>
          </div>

          <!-- 说完了按钮（快速触发 VAD） -->
          <div class="text-center">
            <el-button
              class="w-14 h-14 rounded-full"
              type="primary"
              @click="handleFinishSpeaking"
              :disabled="isMuted"
            >
              <el-icon :size="24"><Check /></el-icon>
            </el-button>
            <p class="text-xs text-gray-500 mt-2">说完了</p>
          </div>

          <!-- 打断 AI（暂停 AI 说话） -->
          <div class="text-center">
            <el-button
              class="w-14 h-14 rounded-full"
              type="warning"
              @click="handleInterrupt"
              :disabled="!isAISpeaking"
            >
              <el-icon :size="24"><VideoPause /></el-icon>
            </el-button>
            <p class="text-xs text-gray-500 mt-2">打断 AI</p>
          </div>
        </div>
      </div>

      <!-- 结束按钮 -->
      <div class="text-center mt-4">
        <el-button
          class="w-14 h-14 rounded-full"
          type="danger"
          @click="handleHangup"
        >
          <el-icon :size="24"><Phone /></el-icon>
        </el-button>
        <p class="text-xs text-gray-500 mt-2">结束面试</p>
      </div>
    </div>

    <!-- ==================== 调试面板 ==================== -->
    <div v-if="showDebug" class="debug-panel">
      <div class="debug-header">
        <span>🔧 调试信息</span>
        <div class="flex items-center gap-2">
          <el-button size="small" @click="copyDebugInfo">复制</el-button>
          <el-switch v-model="showDebug" size="small" />
        </div>
      </div>
      <div class="debug-content">
        <div class="debug-section">
          <h4>会话信息</h4>
          <div class="debug-item">
            <span class="debug-label">sessionId:</span>
            <span class="debug-value" :class="{ 'text-red-400': !sessionId }">
              {{ sessionId || '❌ 空' }}
            </span>
          </div>
          <div class="debug-item">
            <span class="debug-label">conversationId:</span>
            <span class="debug-value">{{ conversationId || '(未创建)' }}</span>
          </div>
          <div class="debug-item">
            <span class="debug-label">模式:</span>
            <span class="debug-value">{{ interviewMode }}</span>
          </div>
          <div class="debug-item">
            <span class="debug-label">候选人:</span>
            <span class="debug-value">{{ candidateName }}</span>
          </div>
        </div>

        <div class="debug-section">
          <h4>最近请求</h4>
          <pre v-if="debugInfo.lastRequest">{{ JSON.stringify(debugInfo.lastRequest, null, 2) }}</pre>
          <span v-else class="text-gray-500">暂无</span>
        </div>

        <div class="debug-section">
          <h4>最近响应</h4>
          <pre v-if="debugInfo.lastApiResponse">{{ JSON.stringify(debugInfo.lastApiResponse, null, 2) }}</pre>
          <span v-else class="text-gray-500">暂无</span>
        </div>

        <!-- Coze 调试链接 -->
        <div class="debug-section" v-if="debugInfo.lastApiResponse?.debugInfo">
          <h4>🔗 Coze 工作流 B 调试</h4>
          <div class="debug-item">
            <span class="debug-label">conversation_id:</span>
            <span class="debug-value text-blue-400">{{ debugInfo.lastApiResponse.debugInfo.conversation_id || '空' }}</span>
          </div>
          <div class="debug-item">
            <span class="debug-label">chat_id:</span>
            <span class="debug-value">{{ debugInfo.lastApiResponse.debugInfo.chat_id || '空' }}</span>
          </div>
          <div class="debug-item">
            <span class="debug-label">session_id:</span>
            <span class="debug-value" :class="debugInfo.lastApiResponse.debugInfo.session_id ? 'text-green-400' : 'text-red-400'">
              {{ debugInfo.lastApiResponse.debugInfo.session_id || '❌ 空' }}
            </span>
          </div>
          <div class="debug-item" v-if="debugInfo.lastApiResponse.debugInfo.coze_bot_url">
            <a 
              :href="debugInfo.lastApiResponse.debugInfo.coze_bot_url" 
              target="_blank" 
              class="text-blue-400 hover:underline"
            >
              👉 打开 Coze Bot 后台
            </a>
          </div>
          <div class="debug-item text-xs text-gray-400 mt-2" v-if="debugInfo.lastApiResponse.debugInfo.search_hint">
            💡 {{ debugInfo.lastApiResponse.debugInfo.search_hint }}
          </div>
        </div>

        <!-- 语音模式调试信息 -->
        <div class="debug-section" v-if="interviewMode === 'voice'">
          <h4>🎤 语音 RTC 调试 (Coze Realtime)</h4>
          
          <!-- session.update 事件状态（关键！） -->
          <div class="debug-item">
            <span class="debug-label">session.update:</span>
            <span class="debug-value" :class="isSessionUpdateSent ? 'text-green-400' : 'text-red-400'">
              {{ isSessionUpdateSent ? '✅ 已发送' : '❌ 未发送' }}
            </span>
          </div>
          <div class="debug-item">
            <span class="debug-label">RTC连接:</span>
            <span class="debug-value" :class="connectionState === 'connected' ? 'text-green-400' : 'text-yellow-400'">
              {{ connectionState }}
            </span>
          </div>
          <div class="debug-item">
            <span class="debug-label">session_id:</span>
            <span class="debug-value" :class="sessionId ? 'text-green-400' : 'text-red-400'">
              {{ sessionId || '❌ 空' }}
            </span>
          </div>
          
          <!-- Coze SDK 调试摘要 -->
          <div v-if="cozeDebugSummary" class="mt-2 text-xs">
            <div class="debug-item" v-if="cozeDebugSummary.eventsSent?.length">
              <span class="debug-label">发送方法:</span>
              <span class="debug-value text-cyan-400">{{ cozeDebugSummary.eventsSent.join(', ') }}</span>
            </div>
            <div class="debug-item" v-if="cozeDebugSummary.errors?.length">
              <span class="debug-label">发送错误:</span>
              <span class="debug-value text-red-400">{{ cozeDebugSummary.errors.join('; ') }}</span>
            </div>
          </div>
        </div>

        <!-- 📊 通讯时间线 -->
        <div class="debug-section" v-if="interviewMode === 'voice' && cozeTimeline?.length">
          <h4>📊 通讯时间线 (最近 {{ cozeTimeline.length }} 条)</h4>
          <div class="timeline-container">
            <div 
              v-for="(item, idx) in cozeTimeline" 
              :key="idx"
              class="timeline-item"
              :class="{
                'timeline-send': item.type === 'send',
                'timeline-receive': item.type === 'receive',
                'timeline-audio': item.type === 'audio',
                'timeline-system': item.type === 'system',
                'timeline-error': item.type === 'error',
              }"
            >
              <span class="timeline-time">{{ item.time }}</span>
              <span class="timeline-event">{{ item.event }}</span>
              <span class="timeline-detail" v-if="item.detail">{{ item.detail }}</span>
            </div>
          </div>
        </div>

        <!-- 后端返回的调试信息 -->
        <div class="debug-section" v-if="interviewMode === 'voice' && voiceDebugInfo">
          <h4>🔗 后端信息</h4>
          <div class="debug-item">
            <span class="debug-label">bot_id:</span>
            <span class="debug-value">{{ voiceDebugInfo.bot_id || '空' }}</span>
          </div>
          <div class="debug-item" v-if="voiceDebugInfo.coze_bot_url">
            <a 
              :href="voiceDebugInfo.coze_bot_url" 
              target="_blank" 
              class="text-blue-400 hover:underline"
            >
              👉 打开 Coze Bot 后台
            </a>
          </div>
          <details class="mt-2">
            <summary class="cursor-pointer text-gray-400 text-xs">查看完整请求/响应</summary>
            <pre class="text-xs mt-2">{{ JSON.stringify(voiceDebugInfo, null, 2) }}</pre>
          </details>
        </div>

        <div class="debug-section">
          <h4>最近错误</h4>
          <pre v-if="debugInfo.lastError || debugInfo.voiceError" class="text-red-400">{{ JSON.stringify(debugInfo.lastError || debugInfo.voiceError, null, 2) }}</pre>
          <span v-else class="text-green-400">无错误</span>
        </div>

        <div class="debug-section">
          <h4>初始化信息 (工作流 A)</h4>
          <pre v-if="initDebugInfo">{{ JSON.stringify(initDebugInfo, null, 2) }}</pre>
          <span v-else class="text-gray-500">暂无</span>
        </div>
      </div>
    </div>
    
    <!-- 调试开关已移除，使用快捷键：连按7次'd'键打开调试面板 -->
  </div>
</template>

<style scoped>
.call-page {
  animation: fadeIn 0.5s ease-out;
  max-height: 100vh;
  overflow: hidden;
}

.incoming-call {
  background: white;
  border-radius: 24px;
  padding: 32px 24px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
}

.in-call {
  background: white;
  border-radius: 24px;
  padding: 32px 24px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 100px);
  overflow: hidden;
}

.text-mode {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

.chat-history {
  flex: 1;
  min-height: 200px;
  max-height: calc(100vh - 350px);
}

.chat-history::-webkit-scrollbar {
  width: 4px;
}

.chat-history::-webkit-scrollbar-thumb {
  background: #ddd;
  border-radius: 2px;
}

/* 来电脉冲动画 */
.pulse-ring {
  position: relative;
}

.pulse-ring::before,
.pulse-ring::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: inherit;
  animation: pulse 2s ease-out infinite;
}

.pulse-ring::after {
  animation-delay: 1s;
}

@keyframes pulse {
  0% { transform: scale(1); opacity: 0.5; }
  100% { transform: scale(1.5); opacity: 0; }
}

.animate-ring {
  animation: ring 0.5s ease-in-out infinite alternate;
}

@keyframes ring {
  0% { transform: rotate(-15deg); }
  100% { transform: rotate(15deg); }
}

/* 语音波形 */
.audio-wave {
  display: flex;
  align-items: center;
  gap: 4px;
  height: 40px;
}

.audio-wave span {
  width: 4px;
  background: linear-gradient(to top, #22c55e, #16a34a);
  border-radius: 2px;
  animation: wave 0.5s ease-in-out infinite alternate;
}

.audio-wave span:nth-child(1) { height: 20px; animation-delay: 0s; }
.audio-wave span:nth-child(2) { height: 35px; animation-delay: 0.1s; }
.audio-wave span:nth-child(3) { height: 25px; animation-delay: 0.2s; }
.audio-wave span:nth-child(4) { height: 40px; animation-delay: 0.3s; }
.audio-wave span:nth-child(5) { height: 30px; animation-delay: 0.4s; }

@keyframes wave {
  0% { transform: scaleY(0.5); }
  100% { transform: scaleY(1); }
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: translateY(0); }
}

/* 调试面板 */
.debug-panel {
  position: fixed;
  right: 20px;
  top: 20px;
  width: 450px;
  max-height: calc(100vh - 40px);
  background: #1e1e2d;
  border-radius: 12px;
  overflow: hidden;
  z-index: 1000;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
}

.debug-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  background: #2d2d3d;
  color: #fff;
  font-size: 14px;
  font-weight: 500;
}

.debug-content {
  padding: 16px;
  max-height: calc(100vh - 100px);
  overflow-y: auto;
  font-size: 12px;
}

.debug-section {
  margin-bottom: 16px;
  padding-bottom: 16px;
  border-bottom: 1px solid #3d3d4d;
}

.debug-section:last-child {
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: none;
}

.debug-section h4 {
  color: #8b8bff;
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 8px;
}

.debug-item {
  display: flex;
  margin-bottom: 4px;
}

.debug-label {
  color: #888;
  width: 120px;
  flex-shrink: 0;
}

.debug-value {
  color: #a0f0a0;
  word-break: break-all;
}

.debug-content pre {
  margin: 0;
  font-size: 11px;
  color: #a0f0a0;
  white-space: pre-wrap;
  word-break: break-all;
  font-family: 'Monaco', 'Consolas', monospace;
  background: #2d2d3d;
  padding: 8px;
  border-radius: 4px;
  max-height: 200px;
  overflow-y: auto;
}

.debug-toggle {
  position: fixed;
  right: 20px;
  top: 20px;
  width: 40px;
  height: 40px;
  background: #1e1e2d;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 20px;
  z-index: 1000;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

.debug-toggle:hover {
  background: #2d2d3d;
}

/* 时间线样式 */
.timeline-container {
  max-height: 300px;
  overflow-y: auto;
  font-family: 'Monaco', 'Consolas', monospace;
  font-size: 11px;
}

.timeline-item {
  display: flex;
  align-items: flex-start;
  padding: 4px 8px;
  margin-bottom: 2px;
  border-radius: 4px;
  gap: 8px;
}

.timeline-time {
  color: #888;
  flex-shrink: 0;
  width: 85px;
}

.timeline-event {
  flex-shrink: 0;
  min-width: 120px;
}

.timeline-detail {
  color: #888;
  font-size: 10px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.timeline-send {
  background: rgba(59, 130, 246, 0.2);
}
.timeline-send .timeline-event {
  color: #60a5fa;
}

.timeline-receive {
  background: rgba(34, 197, 94, 0.2);
}
.timeline-receive .timeline-event {
  color: #4ade80;
}

.timeline-audio {
  background: rgba(251, 191, 36, 0.2);
}
.timeline-audio .timeline-event {
  color: #fbbf24;
}

.timeline-system {
  background: rgba(168, 85, 247, 0.2);
}
.timeline-system .timeline-event {
  color: #c084fc;
}

.timeline-error {
  background: rgba(239, 68, 68, 0.2);
}
.timeline-error .timeline-event {
  color: #f87171;
}

/* 音量指示器 */
.volume-indicator {
  display: flex;
  align-items: center;
  justify-content: center;
}

.volume-bar-container {
  width: 120px;
  height: 8px;
  background: #e5e7eb;
  border-radius: 4px;
  overflow: hidden;
}

.volume-bar {
  height: 100%;
  background: #9ca3af;
  border-radius: 4px;
  transition: width 0.05s ease-out;
}

.volume-bar.speaking {
  background: linear-gradient(90deg, #22c55e, #84cc16);
}

.volume-bar-container {
  position: relative;
}

.threshold-line {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  background: #ef4444;
  opacity: 0.5;
}

.user-speaking {
  display: flex;
  align-items: center;
  animation: pulse-glow 1s ease-in-out infinite;
}

@keyframes pulse-glow {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.6; }
}
</style>
