<script setup>
import { ref, onMounted, nextTick } from 'vue'
import { Search } from '@element-plus/icons-vue'
import MarkdownIt from 'markdown-it'

// 初始化Markdown解析器
const md = MarkdownIt({
  html: true,
  linkify: true,
  typographer: true
})

// 消息模型
const messages = ref([
  {
    id: 1,
    text: '您好！我是智能AI助手，很高兴为您服务。我可以回答各种问题，例如科技、编程、生活常识等。请问有什么可以帮您的吗？',
    mdText:
      '您好！我是智能AI助手，很高兴为您服务。我可以回答各种问题，例如科技、编程、生活常识等。请问有什么可以帮您的吗？',
    sender: 'ai',
    time: new Date().toLocaleTimeString([], {
      hour: '2-digit',
      minute: '2-digit'
    }),
    avatar: 'AI'
  }
])

// 用户输入
const userInput = ref('')
const isThinking = ref(false)
const chatContainer = ref(null)
const isLoading = ref(false)
const currentAiMessageId = ref(null)

// 添加用户消息
const addUserMessage = (message) => {
  if (!message.trim()) return

  const now = new Date()
  messages.value.push({
    id: Date.now(),
    text: message.trim(),
    mdText: message.trim(),
    sender: 'user',
    time: now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
    avatar: 'U'
  })

  userInput.value = ''
  isThinking.value = true
  scrollToBottom()

  // 调用后端API
  callBackendAPI(message)
}

// 调用后端API
const callBackendAPI = async (userMessage) => {
  isLoading.value = true

  try {
    createAiMessage()

    // 调用后端API
    const response = await fetch('http://localhost:8080/api/ai/chat', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        question: userMessage
      })
    })

    if (!response.ok) {
      throw new Error(`请求失败: ${response.status}`)
    }

    // 处理流式响应
    const reader = response.body.getReader()
    const decoder = new TextDecoder('utf-8')
    let partialData = ''

    var dataStr = 'start'
    while (dataStr !== '[DONE]') {
      const { value, done } = await reader.read()
      if (done) break

      const chunk = decoder.decode(value, { stream: true })
      partialData += chunk

      // 处理SSE格式
      const lines = partialData.split('\n')
      partialData = lines.pop() || ''

      for (const line of lines) {
        if (line.trim() === '') continue

        if (line.startsWith('data: ')) {
          dataStr = line.substring(6).trim()

          // if (dataStr === '[DONE]') {
          //   break
          // }

          try {
            const data = JSON.parse(dataStr)
            const content = data.content || ''
            if (content) {
              updateAiMessage(content)
            }
          } catch (error) {
            console.warn('JSON解析错误:', error)
          }
        }
      }
    }
  } catch (error) {
    console.error('API调用失败:', error)
    const aiMessageIndex = messages.value.findIndex(
      (msg) => msg.id === currentAiMessageId.value
    )
    if (aiMessageIndex !== -1) {
      messages.value[aiMessageIndex].mdText =
        `抱歉，处理请求时出错: ${error.message}`
      messages.value[aiMessageIndex].text = md.render(
        messages.value[aiMessageIndex].mdText
      )
      scrollToBottom()
    }
  } finally {
    isLoading.value = false
    isThinking.value = false
  }
}

// 创建初始AI消息
const createAiMessage = () => {
  const now = new Date()
  const newMessage = {
    id: Date.now(),
    text: '',
    mdText: '',
    sender: 'ai',
    time: now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
    avatar: 'AI'
  }

  messages.value.push(newMessage)
  currentAiMessageId.value = newMessage.id
  scrollToBottom()
}

// 更新AI消息内容
const updateAiMessage = (contentChunk) => {
  const aiMessageIndex = messages.value.findIndex(
    (msg) => msg.id === currentAiMessageId.value
  )

  if (aiMessageIndex !== -1) {
    messages.value[aiMessageIndex].mdText += contentChunk
    messages.value[aiMessageIndex].text = md.render(
      messages.value[aiMessageIndex].mdText
    )
    scrollToBottom()
  }
}

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

// 发送消息
const sendMessage = () => {
  if (!userInput.value.trim() || isThinking.value) return
  addUserMessage(userInput.value)
}

// 快捷键发送（Ctrl+Enter）
const handleKeydown = (e) => {
  if (e.ctrlKey && e.key === 'Enter' && userInput.value.trim()) {
    sendMessage()
  }
}

// 初始化时滚动到底部
onMounted(() => {
  scrollToBottom()
})
</script>

<template>
  <page-container title="AI对话助手">
    <div class="chat-container">
      <div ref="chatContainer" class="chat-messages">
        <div
          v-for="message in messages"
          :key="message.id"
          class="message"
          :class="message.sender"
        >
          <div class="avatar">{{ message.avatar }}</div>
          <div class="content">
            <div class="text" v-html="message.text"></div>
            <div class="time">{{ message.time }}</div>
          </div>
        </div>
        <div v-if="isThinking" class="message ai">
          <div class="avatar">AI</div>
          <div class="content">
            <div class="text">思考中...</div>
          </div>
        </div>
      </div>
      <div class="input-area">
        <el-input
          v-model="userInput"
          type="textarea"
          :rows="3"
          placeholder="请输入问题，按Ctrl+Enter发送"
          @keydown="handleKeydown"
          :disabled="isThinking"
        ></el-input>
        <el-button
          type="primary"
          :icon="Search"
          class="send-button"
          @click="sendMessage"
          :loading="isLoading"
          >发送</el-button
        >
      </div>
    </div>
  </page-container>
</template>

<style scoped>
.chat-container {
  display: flex;
  flex-direction: column;
  height: calc(100vh - 100px);
  max-width: 800px;
  margin: 0 auto;
  border: 1px solid #ebeef5;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.chat-messages {
  flex: 1;
  padding: 20px;
  overflow-y: auto;
  background-color: #fafafa;
}

.message {
  display: flex;
  margin-bottom: 20px;
}

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

.avatar {
  width: 40px;
  height: 40px;
  line-height: 40px;
  border-radius: 50%;
  background-color: #409eff;
  color: white;
  text-align: center;
  font-weight: bold;
  margin: 0 10px;
}

.content {
  max-width: 70%;
  padding: 10px 15px;
  border-radius: 4px;
  background-color: #fff;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.message.user .content {
  background-color: #d9ecff;
}

.text {
  word-wrap: break-word;
}

.time {
  font-size: 12px;
  color: #999;
  text-align: right;
  margin-top: 5px;
}

.input-area {
  display: flex;
  padding: 20px;
  background-color: #fff;
  border-top: 1px solid #ebeef5;
}

.input-area :deep(.el-textarea__inner) {
  resize: none;
}

.send-button {
  margin-left: 10px;
  height: auto;
}
</style>
