<template>
  <div class="chat-page">
    <header class="chat-header">
      <button class="back-btn" @click="router.back()">‹</button>
      <div class="avatar-heading">
        <div class="avatar-mark">{{ avatar?.emoji || '🤖' }}</div>
        <div>
          <h1>{{ avatar?.displayName || avatar?.name || '数字分身' }}</h1>
          <span class="online-state">● 随时可以和我聊聊</span>
        </div>
      </div>
      <button class="settings-btn" title="编辑分身" @click="router.push(`/avatar/edit/${avatarId}`)">⚙</button>
    </header>

    <main ref="messageList" class="message-list">
      <div v-if="!messages.length" class="welcome-card">
        <div class="welcome-icon">✦</div>
        <h2>你好，我是{{ avatar?.displayName || '你的数字分身' }}</h2>
        <p>我会优先参考标准问答和知识库，再结合自己的理解回答你。</p>
        <div class="starter-list">
          <button v-for="starter in starters" :key="starter" @click="sendMessage(starter)">{{ starter }}</button>
        </div>
      </div>

      <article v-for="(message, index) in messages" :key="`${message.role}-${index}`" class="message-row" :class="message.role">
        <div v-if="message.role === 'assistant'" class="message-avatar">{{ avatar?.emoji || '🤖' }}</div>
        <div class="message-column">
          <div class="message-bubble">{{ message.content }}</div>
          <div v-if="message.source || message.references?.length" class="message-source">
            {{ sourceLabel(message.source) }}
            <span v-if="message.references?.length"> · {{ message.references.map((item) => item.filename).filter(Boolean).join('、') }}</span>
          </div>
        </div>
      </article>

      <div v-if="sending" class="message-row assistant">
        <div class="message-avatar">{{ avatar?.emoji || '🤖' }}</div>
        <div class="message-bubble typing"><i></i><i></i><i></i></div>
      </div>
      <p v-if="errorMessage" class="chat-error">{{ errorMessage }} <button @click="retryLast">重试</button></p>
    </main>

    <form class="composer" @submit.prevent="sendMessage(inputText)">
      <textarea v-model="inputText" rows="1" :disabled="sending" placeholder="输入你想聊的内容…" @keydown.enter.exact.prevent="sendMessage(inputText)"></textarea>
      <button class="send-btn" type="submit" :disabled="sending || !inputText.trim()">发送</button>
    </form>
  </div>
</template>

<script setup lang="ts">
import { nextTick, onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { getAvatarDetail, sendAvatarChat, type ChatMessage } from '@/api'
import { useAvatarStore } from '@/store/avatar'

type DisplayMessage = ChatMessage & {
  source?: 'qa' | 'knowledge' | 'qwen'
  references?: Array<{ filename?: string }>
}

const route = useRoute()
const router = useRouter()
const store = useAvatarStore()
const avatarId = String(route.params.id || '')
const avatar = ref<any>(null)
const messages = ref<DisplayMessage[]>([])
const inputText = ref('')
const sending = ref(false)
const errorMessage = ref('')
const lastQuestion = ref('')
const messageList = ref<HTMLElement | null>(null)
const starters = ['介绍一下你自己', '你能帮我做什么？', '请根据我的知识库回答一个问题']

const sourceLabel = (source?: DisplayMessage['source']) => ({
  qa: '标准问答对',
  knowledge: '参考文件知识库',
  qwen: 'Qwen 智能回答'
}[source || ''] || '')

const scrollToBottom = async () => {
  await nextTick()
  if (messageList.value) messageList.value.scrollTop = messageList.value.scrollHeight
}

const loadAvatar = async () => {
  avatar.value = store.avatars.find((item) => String(item.id) === avatarId)
  if (!avatar.value) avatar.value = await getAvatarDetail(avatarId)
}

const sendMessage = async (value: string) => {
  const question = value.trim()
  if (!question || sending.value) return
  lastQuestion.value = question
  inputText.value = ''
  errorMessage.value = ''
  messages.value.push({ role: 'user', content: question })
  sending.value = true
  await scrollToBottom()
  try {
    const response = await sendAvatarChat(avatarId, {
      message: question,
      history: messages.value.slice(-10).map(({ role, content }) => ({ role, content }))
    })
    messages.value.push({ role: 'assistant', content: response.answer, source: response.source, references: response.references })
    await scrollToBottom()
  } catch (error: any) {
    errorMessage.value = error?.message || '暂时无法回答，请稍后重试'
  } finally {
    sending.value = false
  }
}

const retryLast = () => {
  if (!lastQuestion.value || sending.value) return
  const last = messages.value[messages.value.length - 1]
  if (last?.role === 'user') messages.value.pop()
  sendMessage(lastQuestion.value)
}

onMounted(loadAvatar)
</script>

<style scoped>
.chat-page { min-height: 100dvh; display: flex; flex-direction: column; background: #FFF8F1; color: #3B2417; }
.chat-header { flex: 0 0 auto; display: flex; align-items: center; gap: 12px; padding: 14px 18px; color: white; background: linear-gradient(135deg, #F97316, #FB923C); box-shadow: 0 5px 18px rgba(249, 115, 22, .2); }
.back-btn, .settings-btn { border: 0; background: transparent; color: white; cursor: pointer; font-size: 25px; padding: 2px 6px; }
.settings-btn { font-size: 20px; margin-left: auto; }
.avatar-heading { display: flex; align-items: center; gap: 10px; }
.avatar-mark { width: 38px; height: 38px; display: grid; place-items: center; border-radius: 13px; background: rgba(255,255,255,.24); font-size: 23px; }
.avatar-heading h1 { margin: 0; font-size: 17px; }
.online-state { display: block; margin-top: 3px; font-size: 11px; opacity: .86; }
.message-list { flex: 1 1 auto; width: min(760px, 100%); box-sizing: border-box; margin: 0 auto; padding: 24px 18px 120px; overflow-y: auto; }
.welcome-card { padding: 28px 20px; text-align: center; background: rgba(255,255,255,.72); border: 1px solid #FFE1C2; border-radius: 22px; box-shadow: 0 10px 28px rgba(181, 99, 35, .08); }
.welcome-icon { color: #F97316; font-size: 30px; }
.welcome-card h2 { margin: 9px 0 8px; font-size: 20px; }
.welcome-card p { margin: 0 auto 20px; max-width: 420px; color: #8B6B58; line-height: 1.6; font-size: 14px; }
.starter-list { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.starter-list button { border: 1px solid #FFD1A8; color: #C15F18; background: #FFF4E8; border-radius: 20px; padding: 8px 12px; cursor: pointer; }
.message-row { display: flex; gap: 9px; margin: 18px 0; align-items: flex-end; }
.message-row.user { justify-content: flex-end; }
.message-avatar { flex: 0 0 auto; width: 30px; height: 30px; display: grid; place-items: center; border-radius: 10px; background: #FFE4C7; }
.message-column { max-width: min(78%, 560px); }
.message-bubble { padding: 12px 14px; white-space: pre-wrap; line-height: 1.6; font-size: 15px; border-radius: 16px 16px 16px 4px; background: white; box-shadow: 0 3px 12px rgba(96, 52, 21, .07); }
.user .message-bubble { color: white; border-radius: 16px 16px 4px 16px; background: #F97316; }
.message-source { margin: 5px 4px 0; font-size: 11px; color: #A77A5B; }
.typing { display: flex; gap: 4px; padding: 14px 16px; }
.typing i { width: 5px; height: 5px; border-radius: 50%; background: #F97316; animation: blink 1s infinite alternate; }
.typing i:nth-child(2) { animation-delay: .2s; }.typing i:nth-child(3) { animation-delay: .4s; }
@keyframes blink { from { opacity: .25; } to { opacity: 1; } }
.chat-error { margin: 4px auto; color: #B42318; font-size: 13px; }.chat-error button { border: 0; background: none; color: #C15F18; cursor: pointer; text-decoration: underline; }
.composer { position: fixed; left: 0; right: 0; bottom: 0; display: flex; gap: 10px; padding: 12px max(18px, calc((100vw - 760px) / 2 + 18px)); background: rgba(255,255,255,.92); border-top: 1px solid #F4DCC7; backdrop-filter: blur(12px); }
.composer textarea { flex: 1; resize: none; min-height: 22px; max-height: 100px; padding: 11px 13px; border: 1px solid #EED8C5; border-radius: 13px; font: inherit; color: #3B2417; outline: none; }.composer textarea:focus { border-color: #F97316; }
.send-btn { align-self: flex-end; padding: 11px 18px; border: 0; border-radius: 12px; color: white; background: #F97316; cursor: pointer; }.send-btn:disabled { opacity: .45; cursor: not-allowed; }
</style>
