<template>
  <div class="ai-chat-container" :style="containerStyle">
    <!-- <div class="chat-header">
      <h3>AI 会话</h3>
      
    </div> -->
    
    <div class="chat-clear" v-if="activeConversations.length">
      <ClearOutlined @click="handleClear"/>
    </div>
    <div class="chat-messages" ref="messagesContainer">
        <div class="messages-list">
            <div 
                v-for="conversation in sortedConversations" 
                :key="conversation.id"
                class="conversation-group"
            >
                <!-- 用户消息 -->
                <div v-if="conversation.question !== 'hi'" class="message-item user-message">
                    <div class="message-avatar user-avatar">
                        <span>我</span>
                    </div>
                    <div class="message-content">
                        <div class="message-bubble user-bubble">
                            <div class="message-text" v-html="conversation.question"></div>
                        </div>
                        <div class="message-time">{{ formatTime(conversation.questionTime) }}</div>
                    </div>
                </div>
                
                <!-- AI回复 -->
                <div class="message-item bot-message">
                    <div class="message-avatar bot-avatar">
                        <SmileOutlined />
                    </div>
                    <div class="message-content">
                        <div class="message-bubble bot-bubble">
                            <div class="message-text" v-html="formatMessage(conversation.answer)"></div>
                            <div v-if="conversation.isStreaming" class="streaming-indicator">
                                <div class="typing-dots">
                                    <span></span>
                                    <span></span>
                                    <span></span>
                                </div>
                            </div>
                        </div>
                        <div class="message-actions" v-if="conversation.answer">
                            <div class="message-time">{{ formatTime(conversation.answerTime) }}</div>
                            <CopyOutlined class="copy-icon" @click="copyToClipboard(conversation.answer)"/>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="input-container">
      <Input.TextArea
        ref="textareaRef"
        v-model:value="question"
        :disabled="isMaxStreamingConversations"
        placeholder="请输入您的问题..."
        class="input-field"
        @keydown="handleKeyDown"
        :auto-size="{ minRows: 1, maxRows: 4 }"
      />
      <div class="input-actions">
        <Button
          type="primary"
          @click="handleSend"
          :style="bgColorStyle"
          class="send-btn"
          :disabled="!question.trim() || isMaxStreamingConversations"
        >
          发送
        </Button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, nextTick, onUnmounted, onMounted } from 'vue'
import Input from 'ant-design-vue/es/input'
import Button from 'ant-design-vue/es/button'
import { CopyOutlined, ClearOutlined, SmileOutlined } from '@ant-design/icons-vue'
import { generateConversationId, formatTime, copyToClipboard } from './utils'
import { apiService } from './api'
import { marked } from 'marked'

const props = defineProps({
  bgColorStyle: {
    type: Object,
    default: () => ({})
  },
  themeColorStyle: {
      type: Array,
      default: () => ['#667eea', '#764ba2']
  },
  pollingInterval: {
    type: Number,
    default: 500
  },
  botCode: {
    type: String,
    default: ''
  },
  userName: {
    type: String,
    default: ''
  }
})


// 类型定义
interface Conversation {
  id: string
  question: string
  answer: string
  questionTime: number
  answerTime: number
  streamId: string
  isStreaming: boolean
}

// 响应式数据
const activeConversations = ref<Conversation[]>([])
const messagesContainer = ref<HTMLElement>()
const question = ref('')
const textareaRef = ref<HTMLTextAreaElement>()

// 定时器跟踪
const activeTimers = ref<Set<ReturnType<typeof setTimeout>>>(new Set())

// 计算属性 - 按时间排序的对话列表
const sortedConversations = computed(() => {
  return [...activeConversations.value].sort((a, b) => a.questionTime - b.questionTime)
})

const isMaxStreamingConversations = computed(() => {
   const streamingConversations = activeConversations.value.filter(conversation => conversation.isStreaming)
   console.log('streamingConversations', streamingConversations.length)
   return streamingConversations.length >= 5
})

// 动态设置CSS变量
const containerStyle = computed(() => ({
  '--input-border-color': props.themeColorStyle[0] as string
}))

// 发送消息
const handleSend = async () => {
  console.log('handleSend', question.value)
  if (!question.value.trim() || isMaxStreamingConversations.value) return
  console.log('handleSend', isMaxStreamingConversations.value)
  const questionText = question.value.trim()
  question.value = ''
  console.log('handleSend', questionText)
  // 创建新的对话
  const conversationId = generateConversationId()
  const newConversation: Conversation = {
    id: conversationId,
    question: questionText,
    answer: '',
    questionTime: Date.now(),
    answerTime: Date.now(),
    streamId: '',
    isStreaming: true
  }

  activeConversations.value.push(newConversation)
  await scrollToBottom()

  // 开始流式回答
  await startStreamingAnswer(newConversation, activeConversations.value?.length-1)
}

// 开始流式回答
const startStreamingAnswer = async (params: Conversation, index: number) => {
  try {
    // 调用真实API接口
    const response = await apiService.sendMessage({
      botCode: props.botCode,
      userName: props.userName,
      streamId: params.streamId,
      question: params.question
    })

    if (response.status.code === 0) {
      // 更新streamId - 直接更新数组中的对象
      const currentConversation = activeConversations.value[index]
      currentConversation.answer = response.body.content
      currentConversation.streamId = response.body.streamId
      currentConversation.answerTime = Date.now()
      // 如果未完成，继续调用接口
      if (!response.body.finish && !!response.body.streamId) {
        currentConversation.isStreaming = true
        // 添加轮询延迟
        const timerId = setTimeout(() => {
          activeTimers.value.delete(timerId)
          startStreamingAnswer(currentConversation, index)
        }, props.pollingInterval)
        activeTimers.value.add(timerId)
      } else {
        currentConversation.isStreaming = false
      }
    } else {
      throw new Error(response.status.detail || '请求失败')
    }
  } catch (error) {
    console.error('发送消息失败:', error)
    const currentConversation = activeConversations.value[index]
    currentConversation.isStreaming = false
    currentConversation.answer = '抱歉，发生了错误，请稍后重试。'
  }

  await scrollToBottom()
}


// 滚动到底部
const scrollToBottom = async () => {
  await nextTick()
  if (messagesContainer.value) {
    messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
  }
}


// 格式化消息内容 - 使用 marked 库解析 markdown
const formatMessage = (content: string) => {
  if (!content) return ''
  
  try {
    // 使用 marked 解析 markdown
    return marked(content) as string
  } catch (error) {
    console.error('Markdown parsing error:', error)
    // 如果解析失败，返回原始内容（转义 HTML）
    return content.replace(/[<>&"']/g, (match) => {
      const escapeMap: { [key: string]: string } = {
        '<': '&lt;',
        '>': '&gt;',
        '&': '&amp;',
        '"': '&quot;',
        "'": '&#39;'
      }
      return escapeMap[match]
    })
  }
}


// 处理键盘事件
const handleKeyDown = (event: KeyboardEvent) => {
  console.log('handleKeyDown', event)
  if (event.key === 'Enter' && !event.shiftKey) {
    event.preventDefault()
    handleSend()
  }
}

// 处理输入事件，自动调整高度
const handleClear = async () => {
    activeConversations.value = []
    question.value = 'hi'
    handleSend()
}

// 清理所有定时器
const clearAllTimers = () => {
  activeTimers.value.forEach(timerId => {
    clearTimeout(timerId)
  })
  activeTimers.value.clear()
}

// 组件销毁时清理定时器
onUnmounted(() => {
  clearAllTimers()
})

onMounted(() => {
  activeConversations.value = []
  question.value = 'hi'
  handleSend()
})


</script>

<style scoped>
.ai-chat-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  /* max-width: 1200px; */
  width: 450px;
  margin: 0 auto;
  background: #f5f5f5;
  position: fixed;
  bottom: 0;
  right: 20px;
  z-index: 1000;
  /* CSS变量定义 */
  --input-border-color: #d9d9d9;
}

.chat-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  background: white;
  border-bottom: 1px solid #e0e0e0;
}

.chat-header h3 {
  margin: 0;
  color: #333;
}

.session-info {
  color: #666;
  font-size: 14px;
}

.conversation-group {
    margin-bottom: 16px;
}

.chat-messages {
  position: relative;
  flex: 1;
  overflow-y: auto;
  padding: 20px;
  background: #f5f5f5;
}

.messages-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.message-item {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-bottom: 8px;
}

.message-item.user-message {
  flex-direction: row-reverse;
}

.message-item.bot-message {
  flex-direction: row;
}

.message-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 500;
  flex-shrink: 0;
}

.user-avatar {
  background: var(--input-border-color, #1890ff);
  color: white;
}

.bot-avatar {
  background: #f0f0f0;
  color: #666;
  font-size: 26px;
  color: var(--input-border-color)
}

.message-content {
  max-width: 90%;
  display: flex;
  flex-direction: column;
  gap: 4px;
  word-break: break-all;
}

.message-bubble {
  padding: 8px 12px;
  border-radius: 12px;
  word-break: break-word;
  position: relative;
}

.user-bubble {
  background: var(--input-border-color, #1890ff);
  color: white;
  border-bottom-right-radius: 4px;
}

.bot-bubble {
  background: white;
  color: #333;
  border: 1px solid #e8e8e8;
  border-bottom-left-radius: 4px;
}

.message-text {
  line-height: 1.4;
}

.message-text :deep(li) {
  word-break: break-all;
}

.message-text :deep(a) {
  color: var(--input-border-color, #1890ff);
  display: inline;
}

.message-time {
  font-size: 11px;
  color: #999;
  margin: 0;
}

.user-message .message-time {
  text-align: right;
}

.bot-message .message-time {
  text-align: left;
}



.chat-clear {
  position: absolute;
  right: 2px;
  bottom: 80px;
  z-index: 1000;
}

.streaming-indicator {
  margin: 4px 0;
}

.message-actions {
    display: flex;
    align-items: center;
    gap: 8px;
}

.copy-icon {
    font-size: 12px;
    color: #999;
    cursor: pointer;
    padding: 2px;
    border-radius: 2px;
    transition: all 0.2s;
}

.copy-icon:hover {
    color: var(--input-border-color, #1890ff);
    background: rgba(24, 144, 255, 0.1);
}

.message-time {
  font-size: 12px;
  color: #999;
  margin-bottom: 0;
}

.input-container {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  padding: 12px 16px;
  background: white;
  border: 1px solid #f5f5f5;
}

.typing-dots {
  display: flex;
  align-items: center;
  gap: 4px;
}

.typing-dots span {
  width: 6px;
  height: 6px;
  background: var(--input-border-color);
  border-radius: 50%;
  animation: typing 1.4s infinite ease-in-out;
}

.typing-dots span:nth-child(2) {
  animation-delay: 0.2s;
}

.typing-dots span:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes typing {
  0%, 60%, 100% {
    transform: translateY(0);
    opacity: 0.4;
  }
  30% {
    transform: translateY(-6px);
    opacity: 1;
  }
}

:deep(.ant-input):focus, :deep(.ant-input):hover {
  border-color: var(--input-border-color, inherit);
}
</style>

