import {
    Check,
    ChevronDown,
    Copy,
    Download,
    Mic,
    MoreVertical,
    Paperclip,
    RefreshCw,
    Send,
    Settings,
    Trash2,
    Waves,
    Zap
} from 'lucide-react'
import {useEffect, useRef, useState} from 'react'
import {type Conversation, conversationApi, type Message} from '../api/conversation'
import {type Character} from '../api/character'
import {type AIConfig, aiConfigApi} from '../api/aiConfig'
import {type Preset, presetApi} from '../api/preset'
import MessageContent from './MessageContent'

interface ChatAreaProps {
  conversation: Conversation
  character: Character
  onConversationUpdate: (conversation: Conversation) => void
}

export default function ChatArea({ conversation, character, onConversationUpdate }: ChatAreaProps) {
  const [messages, setMessages] = useState<Message[]>([])
  const [inputValue, setInputValue] = useState('')
  const [sending, setSending] = useState(false)
  const [loading, setLoading] = useState(true)
  const [showMenu, setShowMenu] = useState(false)
  const [copiedId, setCopiedId] = useState<number | null>(null)
  const [aiConfigs, setAiConfigs] = useState<AIConfig[]>([])
  const [selectedConfigId, setSelectedConfigId] = useState<number>()
  const [showModelSelector, setShowModelSelector] = useState(false)
  const [streamEnabled, setStreamEnabled] = useState(true)
  const [presets, setPresets] = useState<Preset[]>([])
  const [selectedPresetId, setSelectedPresetId] = useState<number>()
  const [showPresetSelector, setShowPresetSelector] = useState(false)
  const messagesEndRef = useRef<HTMLDivElement>(null)
  const textareaRef = useRef<HTMLTextAreaElement>(null)
  const modelSelectorRef = useRef<HTMLDivElement>(null)
  const presetSelectorRef = useRef<HTMLDivElement>(null)
  const menuRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      const target = event.target as HTMLElement
      if (showModelSelector && modelSelectorRef.current && !modelSelectorRef.current.contains(target)) {
        setShowModelSelector(false)
      }
      if (showPresetSelector && presetSelectorRef.current && !presetSelectorRef.current.contains(target)) {
        setShowPresetSelector(false)
      }
      if (showMenu && menuRef.current && !menuRef.current.contains(target)) {
        setShowMenu(false)
      }
    }
    document.addEventListener('mousedown', handleClickOutside)
    return () => document.removeEventListener('mousedown', handleClickOutside)
  }, [showModelSelector, showPresetSelector, showMenu])

  useEffect(() => {
    loadMessages()
    loadAIConfigs()
    loadCurrentConfig()
    loadPresets()
    loadCurrentPreset()
  }, [conversation.id])

  useEffect(() => {
    scrollToBottom()
  }, [messages])

  // 监听状态栏按钮点击事件
  useEffect(() => {
    const handleStatusBarAction = (event: CustomEvent) => {
      const action = event.detail
      if (action && typeof action === 'string' && !sending) {
        console.log('[ChatArea] 收到状态栏操作，自动发送消息:', action)
        setInputValue(action)
        // 延迟发送，确保 inputValue 已更新
        setTimeout(() => {
          handleSendMessage(action)
        }, 100)
      }
    }

    window.addEventListener('sendMessageFromStatusBar', handleStatusBarAction as EventListener)
    return () => window.removeEventListener('sendMessageFromStatusBar', handleStatusBarAction as EventListener)
  }, [sending])

  const loadMessages = async () => {
    try {
      setLoading(true)
      const response = await conversationApi.getMessageList(conversation.id, { page: 1, pageSize: 100 })
      setMessages(response.data.list || [])
    } catch (err) {
      console.error('加载消息失败:', err)
    } finally {
      setLoading(false)
    }
  }

  const loadAIConfigs = async () => {
    try {
      const response = await aiConfigApi.getAIConfigList()
      setAiConfigs(response.data.list.filter(config => config.isActive))
    } catch (err) {
      console.error('加载 AI 配置失败:', err)
    }
  }

  const loadCurrentConfig = () => {
    if (conversation.settings) {
      try {
        const settings = typeof conversation.settings === 'string'
          ? JSON.parse(conversation.settings)
          : conversation.settings
        if (settings.aiConfigId) setSelectedConfigId(settings.aiConfigId)
      } catch (e) {
        console.error('解析设置失败:', e)
      }
    }
  }

  const loadPresets = async () => {
    try {
      const response = await presetApi.getPresetList({ page: 1, pageSize: 100 })
      setPresets(response.data.list)
    } catch (err) {
      console.error('加载预设失败:', err)
    }
  }

  const loadCurrentPreset = () => {
    if (conversation.presetId) {
      setSelectedPresetId(conversation.presetId)
      return
    }
    if (conversation.settings) {
      try {
        const settings = typeof conversation.settings === 'string'
          ? JSON.parse(conversation.settings)
          : conversation.settings
        if (settings.presetId) {
          setSelectedPresetId(settings.presetId)
          return
        }
      } catch (e) {
        console.error('解析设置失败:', e)
      }
    }
    setSelectedPresetId(undefined)
  }

  const handlePresetChange = async (presetId: number | null) => {
    try {
      const settings = conversation.settings
        ? (typeof conversation.settings === 'string' ? JSON.parse(conversation.settings) : { ...conversation.settings })
        : {}
      if (presetId === null) {
        delete settings.presetId
      } else {
        settings.presetId = presetId
      }
      await conversationApi.updateConversationSettings(conversation.id, { settings })
      setSelectedPresetId(presetId ?? undefined)
      setShowPresetSelector(false)
      const convResp = await conversationApi.getConversationById(conversation.id)
      onConversationUpdate(convResp.data)
    } catch (err) {
      console.error('更新预设失败:', err)
      alert('更新失败，请重试')
    }
  }

  const handleModelChange = async (configId: number | null) => {
    try {
      const settings = conversation.settings
        ? (typeof conversation.settings === 'string' ? JSON.parse(conversation.settings) : { ...conversation.settings })
        : {}
      if (configId === null) {
        delete settings.aiConfigId
      } else {
        settings.aiConfigId = configId
      }
      await conversationApi.updateConversationSettings(conversation.id, { settings })
      setSelectedConfigId(configId ?? undefined)
      setShowModelSelector(false)
      const convResp = await conversationApi.getConversationById(conversation.id)
      onConversationUpdate(convResp.data)
    } catch (err) {
      console.error('更新模型配置失败:', err)
      alert('更新失败，请重试')
    }
  }

  const scrollToBottom = () => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' })
  }

  const handleSendMessage = async (message: string) => {
    if (!message.trim() || sending) return

    const userMessage = message.trim()
    setSending(true)

    const tempUserMessage: Message = {
      id: Date.now(),
      conversationId: conversation.id,
      role: 'user',
      content: userMessage,
      tokenCount: 0,
      createdAt: new Date().toISOString(),
    }
    setMessages(prev => [...prev, tempUserMessage])

    const tempAIMessage: Message = {
      id: Date.now() + 1,
      conversationId: conversation.id,
      role: 'assistant',
      content: '',
      tokenCount: 0,
      createdAt: new Date().toISOString(),
    }

    try {
      if (streamEnabled) {
        setMessages(prev => [...prev, tempAIMessage])
        const response = await fetch(
          `${import.meta.env.VITE_API_BASE_URL || '/api'}/app/conversation/${conversation.id}/message?stream=true`,
          {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
              'Authorization': `Bearer ${localStorage.getItem('token')}`,
            },
            body: JSON.stringify({ content: userMessage }),
          }
        )
        if (!response.ok) throw new Error('流式传输失败')

        const reader = response.body?.getReader()
        const decoder = new TextDecoder()
        if (reader) {
          let fullContent = ''
          let buffer = ''
          while (true) {
            const { done, value } = await reader.read()
            if (done) break
            buffer += decoder.decode(value, { stream: true })
            const lines = buffer.split('\n')
            buffer = lines.pop() || ''
            let currentEvent = ''
            for (const line of lines) {
              if (line.startsWith('event: ')) {
                currentEvent = line.slice(7).trim()
              } else if (line.startsWith('data: ')) {
                const data = line.slice(6).trim()
                if (currentEvent === 'message') {
                  fullContent += data
                  setMessages(prev =>
                    prev.map(m => m.id === tempAIMessage.id ? { ...m, content: fullContent } : m)
                  )
                } else if (currentEvent === 'done') {
                  await loadMessages()
                  break
                } else if (currentEvent === 'error') {
                  throw new Error(data)
                }
                currentEvent = ''
              }
            }
          }
        }
        const convResp = await conversationApi.getConversationById(conversation.id)
        onConversationUpdate(convResp.data)
      } else {
        await conversationApi.sendMessage(conversation.id, { content: userMessage })
        await loadMessages()
        const convResp = await conversationApi.getConversationById(conversation.id)
        onConversationUpdate(convResp.data)
      }
    } catch (err: any) {
      console.error('发送消息失败:', err)
      alert(err.response?.data?.msg || '发送消息失败，请重试')
      setMessages(prev => prev.filter(m => m.id !== tempUserMessage.id && m.id !== tempAIMessage.id))
    } finally {
      setSending(false)
    }
  }

  const handleSend = async () => {
    if (!inputValue.trim() || sending) return
    const userMessage = inputValue.trim()
    setInputValue('')
    await handleSendMessage(userMessage)
  }

  const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
    if (e.key === 'Enter' && !e.shiftKey && !sending && inputValue.trim()) {
      e.preventDefault()
      handleSend()
    }
  }

  const handleCopyMessage = (content: string, id: number) => {
    navigator.clipboard.writeText(content)
    setCopiedId(id)
    setTimeout(() => setCopiedId(null), 2000)
  }

  const handleRegenerateResponse = async () => {
    if (messages.length === 0 || sending) return
    const hasAssistantMsg = messages.some(m => m.role === 'assistant')
    if (!hasAssistantMsg) return

    setSending(true)
    const lastAssistantIndex = [...messages].map(m => m.role).lastIndexOf('assistant')
    if (lastAssistantIndex !== -1) {
      setMessages(prev => prev.filter((_, i) => i !== lastAssistantIndex))
    }

    const tempAIMessage: Message = {
      id: Date.now(),
      conversationId: conversation.id,
      role: 'assistant',
      content: '',
      tokenCount: 0,
      createdAt: new Date().toISOString(),
    }

    try {
      if (streamEnabled) {
        setMessages(prev => [...prev, tempAIMessage])
        const response = await fetch(
          `${import.meta.env.VITE_API_BASE_URL || '/api'}/app/conversation/${conversation.id}/regenerate?stream=true`,
          {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
              'Authorization': `Bearer ${localStorage.getItem('token')}`,
            },
          }
        )
        if (!response.ok) throw new Error('重新生成失败')

        const reader = response.body?.getReader()
        const decoder = new TextDecoder()
        if (reader) {
          let fullContent = ''
          let buffer = ''
          while (true) {
            const { done, value } = await reader.read()
            if (done) break
            buffer += decoder.decode(value, { stream: true })
            const lines = buffer.split('\n')
            buffer = lines.pop() || ''
            let currentEvent = ''
            for (const line of lines) {
              if (line.startsWith('event: ')) {
                currentEvent = line.slice(7).trim()
              } else if (line.startsWith('data: ')) {
                const data = line.slice(6).trim()
                if (currentEvent === 'message') {
                  fullContent += data
                  setMessages(prev =>
                    prev.map(m => m.id === tempAIMessage.id ? { ...m, content: fullContent } : m)
                  )
                } else if (currentEvent === 'done') {
                  await loadMessages()
                  break
                } else if (currentEvent === 'error') {
                  throw new Error(data)
                }
                currentEvent = ''
              }
            }
          }
        }
      } else {
        await conversationApi.regenerateMessage(conversation.id)
        await loadMessages()
      }
      const convResp = await conversationApi.getConversationById(conversation.id)
      onConversationUpdate(convResp.data)
    } catch (err: any) {
      console.error('重新生成失败:', err)
      alert(err.message || '重新生成失败，请重试')
      await loadMessages()
    } finally {
      setSending(false)
    }
  }

  const handleDeleteConversation = async () => {
    if (!confirm('确定要删除这个对话吗？')) return
    try {
      await conversationApi.deleteConversation(conversation.id)
      window.location.href = '/chat'
    } catch (err) {
      console.error('删除对话失败:', err)
      alert('删除失败')
    }
  }

  const handleExportConversation = () => {
    const content = messages.map(msg => `[${msg.role}] ${msg.content}`).join('\n\n')
    const blob = new Blob([content], { type: 'text/plain' })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = `${conversation.title}.txt`
    a.click()
    URL.revokeObjectURL(url)
  }

  const formatTime = (dateString: string) => {
    const date = new Date(dateString)
    const now = new Date()
    const diff = now.getTime() - date.getTime()
    const minutes = Math.floor(diff / 60000)
    const hours = Math.floor(diff / 3600000)
    const days = Math.floor(diff / 86400000)
    if (minutes < 1) return '刚刚'
    if (minutes < 60) return `${minutes}分钟前`
    if (hours < 24) return `${hours}小时前`
    if (days < 7) return `${days}天前`
    return date.toLocaleDateString('zh-CN')
  }

  const selectedConfig = aiConfigs.find(c => c.id === selectedConfigId)
  const selectedPreset = presets.find(p => p.id === selectedPresetId)
  const lastAssistantMsgId = [...messages].reverse().find(m => m.role === 'assistant')?.id

  return (
    <div className="flex-1 flex flex-col min-w-0">
      {/* 顶部工具栏 */}
      <div className="px-4 py-3 glass border-b border-white/10">
        <div className="flex items-center justify-between gap-3">
          {/* 左侧：标题 */}
          <div className="min-w-0 flex-1">
            <h2 className="text-base font-semibold truncate">{conversation.title}</h2>
            <p className="text-xs text-white/50 truncate">与 {character.name} 对话中</p>
          </div>

          {/* 右侧：工具按钮组 */}
          <div className="flex items-center gap-1 flex-shrink-0">

            {/* 模型选择器 */}
            <div className="relative" ref={modelSelectorRef}>
              <button
                onClick={() => {
                  setShowModelSelector(v => !v)
                  setShowPresetSelector(false)
                  setShowMenu(false)
                }}
                className={`flex items-center gap-1.5 px-2.5 py-1.5 rounded-lg text-xs font-medium transition-all cursor-pointer
                  ${showModelSelector ? 'bg-white/15 text-white' : 'glass-hover text-white/70 hover:text-white'}`}
                title="切换模型"
              >
                <Zap className="w-3.5 h-3.5 text-yellow-400 flex-shrink-0" />
                <span className="max-w-[80px] truncate">
                  {selectedConfig ? selectedConfig.name : '默认模型'}
                </span>
                <ChevronDown className={`w-3 h-3 flex-shrink-0 transition-transform ${showModelSelector ? 'rotate-180' : ''}`} />
              </button>

              {showModelSelector && (
                <div className="absolute right-0 top-full mt-1 z-50 w-56 glass rounded-xl shadow-2xl border border-white/15 overflow-hidden">
                  <div className="p-1">
                    <button
                      onClick={() => handleModelChange(null)}
                      className={`w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-left cursor-pointer transition-all
                        ${!selectedConfigId ? 'bg-primary/20 text-white' : 'text-white/60 hover:bg-white/10 hover:text-white'}`}
                    >
                      <span className="flex-1">默认模型</span>
                      {!selectedConfigId && <Check className="w-3.5 h-3.5 text-primary" />}
                    </button>
                    {aiConfigs.length > 0 && <div className="my-1 border-t border-white/10" />}
                    {aiConfigs.map(config => (
                      <button
                        key={config.id}
                        onClick={() => handleModelChange(config.id)}
                        className={`w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-left cursor-pointer transition-all
                          ${selectedConfigId === config.id ? 'bg-primary/20 text-white' : 'text-white/70 hover:bg-white/10 hover:text-white'}`}
                      >
                        <div className="flex-1 min-w-0">
                          <div className="font-medium truncate">{config.name}</div>
                          <div className="text-xs text-white/40 truncate">{config.provider} · {config.defaultModel}</div>
                        </div>
                        {selectedConfigId === config.id && <Check className="w-3.5 h-3.5 text-primary flex-shrink-0" />}
                      </button>
                    ))}
                    {aiConfigs.length === 0 && (
                      <div className="px-3 py-3 text-xs text-white/40 text-center">暂无可用配置</div>
                    )}
                  </div>
                </div>
              )}
            </div>

            {/* 预设选择器 */}
            <div className="relative" ref={presetSelectorRef}>
              <button
                onClick={() => {
                  setShowPresetSelector(v => !v)
                  setShowModelSelector(false)
                  setShowMenu(false)
                }}
                className={`flex items-center gap-1.5 px-2.5 py-1.5 rounded-lg text-xs font-medium transition-all cursor-pointer
                  ${showPresetSelector ? 'bg-white/15 text-white' : 'glass-hover text-white/70 hover:text-white'}`}
                title="选择预设"
              >
                <Settings className="w-3.5 h-3.5 text-purple-400 flex-shrink-0" />
                <span className="max-w-[80px] truncate">
                  {selectedPreset ? selectedPreset.name : '默认预设'}
                </span>
                <ChevronDown className={`w-3 h-3 flex-shrink-0 transition-transform ${showPresetSelector ? 'rotate-180' : ''}`} />
              </button>

              {showPresetSelector && (
                <div className="absolute right-0 top-full mt-1 z-50 w-56 glass rounded-xl shadow-2xl border border-white/15 overflow-hidden">
                  <div className="p-1">
                    <button
                      onClick={() => handlePresetChange(null)}
                      className={`w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-left cursor-pointer transition-all
                        ${!selectedPresetId ? 'bg-primary/20 text-white' : 'text-white/60 hover:bg-white/10 hover:text-white'}`}
                    >
                      <span className="flex-1">默认预设</span>
                      {!selectedPresetId && <Check className="w-3.5 h-3.5 text-primary" />}
                    </button>
                    {presets.length > 0 && <div className="my-1 border-t border-white/10" />}
                    {presets.map(preset => (
                      <button
                        key={preset.id}
                        onClick={() => handlePresetChange(preset.id)}
                        className={`w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-left cursor-pointer transition-all
                          ${selectedPresetId === preset.id ? 'bg-primary/20 text-white' : 'text-white/70 hover:bg-white/10 hover:text-white'}`}
                      >
                        <div className="flex-1 min-w-0">
                          <div className="font-medium truncate">{preset.name}</div>
                          <div className="text-xs text-white/40">温度 {preset.temperature}</div>
                        </div>
                        {selectedPresetId === preset.id && <Check className="w-3.5 h-3.5 text-primary flex-shrink-0" />}
                      </button>
                    ))}
                    {presets.length === 0 && (
                      <div className="px-3 py-3 text-xs text-white/40 text-center">暂无可用预设</div>
                    )}
                  </div>
                </div>
              )}
            </div>

            {/* 分隔线 */}
            <div className="w-px h-5 bg-white/10 mx-1" />

            {/* 流式传输切换 */}
            <button
              onClick={() => setStreamEnabled(v => !v)}
              className={`p-1.5 rounded-lg cursor-pointer transition-all ${
                streamEnabled
                  ? 'text-emerald-400 bg-emerald-400/10 hover:bg-emerald-400/20'
                  : 'text-white/30 glass-hover hover:text-white/60'
              }`}
              title={streamEnabled ? '流式传输已启用（点击关闭）' : '流式传输已关闭（点击开启）'}
            >
              <Waves className="w-4 h-4" />
            </button>

            {/* 更多菜单 */}
            <div className="relative" ref={menuRef}>
              <button
                onClick={() => {
                  setShowMenu(v => !v)
                  setShowModelSelector(false)
                  setShowPresetSelector(false)
                }}
                className={`p-1.5 rounded-lg cursor-pointer transition-all
                  ${showMenu ? 'bg-white/15 text-white' : 'glass-hover text-white/60 hover:text-white'}`}
              >
                <MoreVertical className="w-4 h-4" />
              </button>

              {showMenu && (
                <div className="absolute right-0 top-full mt-1 z-50 w-44 glass rounded-xl shadow-2xl border border-white/15 overflow-hidden">
                  <div className="p-1">
                    <button
                      onClick={() => { handleExportConversation(); setShowMenu(false) }}
                      className="w-full flex items-center gap-2.5 px-3 py-2 rounded-lg text-sm text-left cursor-pointer text-white/70 hover:bg-white/10 hover:text-white transition-all"
                    >
                      <Download className="w-4 h-4" />
                      导出对话
                    </button>
                    <div className="my-1 border-t border-white/10" />
                    <button
                      onClick={() => { handleDeleteConversation(); setShowMenu(false) }}
                      className="w-full flex items-center gap-2.5 px-3 py-2 rounded-lg text-sm text-left cursor-pointer text-red-400 hover:bg-red-400/10 transition-all"
                    >
                      <Trash2 className="w-4 h-4" />
                      删除对话
                    </button>
                  </div>
                </div>
              )}
            </div>
          </div>
        </div>
      </div>

      {/* 消息列表 */}
      <div className="flex-1 overflow-y-auto px-4 py-6 space-y-5">
        {loading ? (
          <div className="flex justify-center items-center py-12">
            <div className="flex gap-1.5">
              {[0, 0.15, 0.3].map((delay, i) => (
                <div key={i} className="w-2 h-2 bg-primary/60 rounded-full animate-bounce" style={{ animationDelay: `${delay}s` }} />
              ))}
            </div>
          </div>
        ) : messages.length === 0 ? (
          <div className="flex flex-col items-center justify-center py-16 text-center">
            {character.avatar && (
              <img src={character.avatar} alt={character.name} className="w-16 h-16 rounded-full object-cover mb-4 ring-2 ring-white/10" />
            )}
            <p className="text-white/50 text-sm">发送第一条消息，开始和 {character.name} 对话吧</p>
          </div>
        ) : (
          messages.map((msg) => {
            const isLastAssistant = msg.id === lastAssistantMsgId
            return (
              <div
                key={msg.id}
                className={`flex ${msg.role === 'user' ? 'justify-end' : 'justify-start'} group`}
              >
                {/* 助手头像 */}
                {msg.role === 'assistant' && (
                  <div className="flex-shrink-0 mr-2.5 mt-1">
                    {character.avatar ? (
                      <img src={character.avatar} alt={character.name} className="w-8 h-8 rounded-full object-cover ring-1 ring-white/10" />
                    ) : (
                      <div className="w-8 h-8 rounded-full bg-primary/30 flex items-center justify-center text-xs font-medium">
                        {character.name[0]}
                      </div>
                    )}
                  </div>
                )}

                <div className={`min-w-0 flex flex-col ${msg.role === 'user' ? 'max-w-[70%] items-end' : 'w-[70%] items-start'}`}>
                  {/* 助手名称 */}
                  {msg.role === 'assistant' && (
                    <span className="text-xs text-white/40 mb-1 ml-1">{character.name}</span>
                  )}

                  {/* 消息气泡 */}
                  <div
                    className={`relative px-4 py-3 rounded-2xl ${
                      msg.role === 'user'
                        ? 'bg-primary/25 border border-primary/20 rounded-br-md'
                        : 'glass rounded-bl-md w-full'
                    }`}
                    style={{ wordBreak: 'break-word', overflowWrap: 'anywhere' }}
                  >
                    <MessageContent
                      content={msg.content}
                      role={msg.role as 'user' | 'assistant'}
                      onChoiceSelect={(choice) => {
                        setInputValue(choice)
                        textareaRef.current?.focus()
                      }}
                    />
                  </div>

                  {/* 底部操作栏 */}
                  <div className={`flex items-center gap-1 mt-1 px-1 opacity-0 group-hover:opacity-100 transition-opacity ${msg.role === 'user' ? 'flex-row-reverse' : ''}`}>
                    <span className="text-xs text-white/25">{formatTime(msg.createdAt)}</span>
                    <button
                      onClick={() => handleCopyMessage(msg.content, msg.id)}
                      className="p-1 rounded hover:bg-white/10 transition-colors cursor-pointer"
                      title="复制"
                    >
                      {copiedId === msg.id
                        ? <Check className="w-3.5 h-3.5 text-emerald-400" />
                        : <Copy className="w-3.5 h-3.5 text-white/40 hover:text-white/70" />
                      }
                    </button>
                    {/* 最后一条 AI 消息显示重新生成按钮 */}
                    {msg.role === 'assistant' && isLastAssistant && (
                      <button
                        onClick={handleRegenerateResponse}
                        disabled={sending}
                        className="p-1 rounded hover:bg-white/10 transition-colors cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed"
                        title="重新生成"
                      >
                        <RefreshCw className={`w-3.5 h-3.5 text-white/40 hover:text-white/70 ${sending ? 'animate-spin' : ''}`} />
                      </button>
                    )}
                  </div>
                </div>

                {/* 用户头像占位 */}
                {msg.role === 'user' && <div className="flex-shrink-0 ml-2.5 mt-1 w-8 h-8 rounded-full bg-white/10 flex items-center justify-center text-xs">我</div>}
              </div>
            )
          })
        )}

        {/* 发送中动画（流式时不需要，已有临时消息） */}
        {sending && !streamEnabled && (
          <div className="flex justify-start">
            <div className="flex-shrink-0 mr-2.5 mt-1 w-8 h-8 rounded-full bg-primary/30 flex items-center justify-center text-xs">
              {character.name[0]}
            </div>
            <div className="glass rounded-2xl rounded-bl-md px-4 py-3">
              <div className="flex items-center gap-1.5">
                {[0, 0.2, 0.4].map((delay, i) => (
                  <div key={i} className="w-1.5 h-1.5 bg-primary/60 rounded-full animate-bounce" style={{ animationDelay: `${delay}s` }} />
                ))}
              </div>
            </div>
          </div>
        )}
        <div ref={messagesEndRef} />
      </div>

      {/* 输入区域 */}
      <div className="px-4 pb-4 pt-2 glass border-t border-white/10">
        <div className="flex items-end gap-2">
          <button className="p-2.5 glass-hover rounded-xl cursor-not-allowed opacity-30" title="附件（开发中）" disabled>
            <Paperclip className="w-5 h-5" />
          </button>

          <div className="flex-1 glass rounded-2xl px-4 py-2.5 focus-within:ring-1 focus-within:ring-primary/50 transition-all">
            <textarea
              ref={textareaRef}
              value={inputValue}
              onChange={(e) => {
                setInputValue(e.target.value)
                if (textareaRef.current) {
                  textareaRef.current.style.height = 'auto'
                  textareaRef.current.style.height = Math.min(textareaRef.current.scrollHeight, 120) + 'px'
                }
              }}
              onKeyDown={handleKeyDown}
              placeholder={sending ? 'AI 正在思考...' : `和 ${character.name} 说点什么... (Enter 发送，Shift+Enter 换行)`}
              rows={1}
              className="w-full bg-transparent resize-none focus:outline-none text-sm placeholder:text-white/25"
              style={{ maxHeight: '120px', minHeight: '22px' }}
              disabled={sending}
            />
          </div>

          <button className="p-2.5 glass-hover rounded-xl cursor-not-allowed opacity-30" title="语音（开发中）" disabled>
            <Mic className="w-5 h-5" />
          </button>

          <button
            onClick={handleSend}
            disabled={!inputValue.trim() || sending}
            className="p-2.5 bg-gradient-to-br from-primary to-secondary rounded-xl hover:opacity-90 active:scale-95 transition-all cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed disabled:active:scale-100"
            title="发送 (Enter)"
          >
            <Send className="w-5 h-5" />
          </button>
        </div>

        <div className="flex items-center justify-between mt-2 px-1 text-xs text-white/25">
          <span>{conversation.messageCount} 条消息 · {conversation.tokenCount} tokens</span>
          {sending && <span className="text-primary/70 animate-pulse">AI 正在思考...</span>}
        </div>
      </div>
    </div>
  )
}
