<script setup>
import { computed, nextTick, onMounted, ref, watch } from 'vue'
import { useChat } from '@/composables/useChat'
import { useAppStore } from '@/stores/app'
import { renderMarkdown } from '@/utils/markdown'
import assistantAvatar from '@/assets/sysA.jpeg'

const store = useAppStore()
const {
  sessions, currentSessionId, messages, streaming,
  loadSessions, selectSession, createSession, deleteSession, sendQuestion,
  uploadImage,
} = useChat()

const question = ref('')
const messagesEl = ref(null)
const fileInput = ref(null)
const pendingImages = ref([])
const sessionFilter = ref('')
const deepThinking = ref(false)
const lightboxSrc = ref('')

function onBubbleClick(e) {
  if (e.target?.tagName === 'IMG' && e.target.src) {
    lightboxSrc.value = e.target.src
  }
}

function scrollToEnd() {
  nextTick(() => {
    const el = messagesEl.value
    if (el) el.scrollTop = el.scrollHeight
  })
}

async function pickImages() {
  fileInput.value?.click()
}

async function onFilesPicked(event) {
  const files = Array.from(event.target.files || [])
  event.target.value = ''
  for (const f of files) {
    if (!/^image\/(png|jpe?g)$/.test(f.type)) {
      store.toast(`${f.name} 不是 PNG/JPG`, 'warning')
      continue
    }
    if (f.size > 8 * 1024 * 1024) {
      store.toast(`${f.name} 超过 8MB`, 'warning')
      continue
    }
    try {
      const att = await uploadImage(f)
      const data_url = await readAsDataUrl(f)
      pendingImages.value.push({ id: att.id, file_type: f.type, data_url })
    } catch (err) {
      store.toast(`上传失败：${err.message}`, 'error')
    }
  }
}

function readAsDataUrl(file) {
  return new Promise((resolve, reject) => {
    const r = new FileReader()
    r.onload = () => resolve(r.result)
    r.onerror = () => reject(r.error)
    r.readAsDataURL(file)
  })
}

function removePendingImage(idx) {
  pendingImages.value.splice(idx, 1)
}

async function submit() {
  const text = question.value
  const attachments = pendingImages.value.slice()
  if (!text.trim() && attachments.length === 0) return
  question.value = ''
  pendingImages.value = []
  try {
    await sendQuestion(text, attachments)
  } catch (err) {
    store.toast(err.message)
  }
}

function onComposerKeydown(e) {
  if (e.key !== 'Enter') return
  if (e.shiftKey || e.ctrlKey || e.metaKey || e.altKey) return
  if (e.isComposing || e.keyCode === 229) return
  e.preventDefault()
  if (streaming.value) return
  submit()
}

async function onCreateSession() {
  try {
    await createSession()
  } catch (err) {
    store.toast(err.message)
  }
}

async function onDeleteSession(session) {
  try {
    await deleteSession(session)
    store.toast('会话已删除')
  } catch (err) {
    store.toast(err.message)
  }
}

async function onSelectSession(id) {
  try {
    await selectSession(id)
  } catch (err) {
    store.toast(err.message)
  }
}

function copyText(text) {
  if (!text) return
  navigator.clipboard?.writeText(text).then(
    () => store.toast('已复制', 'success'),
    () => store.toast('复制失败', 'warning'),
  )
}

function startOfDay(d) {
  const x = new Date(d)
  x.setHours(0, 0, 0, 0)
  return x.getTime()
}

const sessionGroups = computed(() => {
  const todayStart = startOfDay(new Date())
  const yesterdayStart = todayStart - 86400000
  const kw = sessionFilter.value.trim().toLowerCase()
  const groups = { today: [], yesterday: [], earlier: [] }
  for (const s of sessions.value) {
    if (kw && !(s.title || '').toLowerCase().includes(kw)) continue
    const ts = new Date(s.last_message_at || s.created_at).getTime()
    if (ts >= todayStart) groups.today.push(s)
    else if (ts >= yesterdayStart) groups.yesterday.push(s)
    else groups.earlier.push(s)
  }
  return groups
})

function formatSessionTime(s) {
  const d = new Date(s.last_message_at || s.created_at)
  if (Number.isNaN(d.getTime())) return ''
  const todayStart = startOfDay(new Date())
  if (d.getTime() >= todayStart) {
    return d.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })
  }
  return d.toLocaleDateString('zh-CN', { month: '2-digit', day: '2-digit' }).replace(/\//g, '/')
}

function formatBubbleTime(msg) {
  const ts = msg?.created_at
  const d = ts ? new Date(ts) : new Date()
  if (Number.isNaN(d.getTime())) return ''
  return d.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })
}

const userAvatarInitial = computed(() => (store.currentUser?.name || '我')[0].toUpperCase())

onMounted(async () => {
  if (store.token) {
    try { await loadSessions() } catch (err) { store.toast(err.message) }
  }
})

watch(() => store.token, async (val) => {
  if (val) await loadSessions()
  else {
    sessions.value = []
    messages.value = []
    currentSessionId.value = null
  }
})

watch(messages, scrollToEnd, { deep: true })
</script>

<template>
  <section class="view is-visible chat-layout">
    <div class="welcome-banner">
      <div class="welcome-text">
        <div class="welcome-greeting">您好，欢迎回来！</div>
        <h1 class="welcome-title">我是您的财税<em>AI</em>助手</h1>
        <p class="welcome-subtitle">专注财税咨询 · 智能问答 · 专业可靠</p>
      </div>
      <div class="welcome-art">
        <div class="welcome-art-bubble b1"></div>
        <div class="welcome-art-bubble b2"></div>
        <div class="welcome-art-bubble b3"></div>
        <div class="welcome-art-bubble b4"></div>
        <span class="welcome-art-text">AI</span>
      </div>
    </div>

    <div class="chat-layout-body">
      <section class="conversation-panel">
        <div class="panel-head">
          <h2>历史会话</h2>
        </div>
        <div class="session-toolbar">
          <button class="primary-btn session-new" type="button" @click="onCreateSession">
            <span>+</span>
            <span>新建对话</span>
          </button>
          <div class="session-search">
            <span class="session-search-icon">🔍</span>
            <input v-model="sessionFilter" placeholder="筛选" />
          </div>
        </div>
        <div class="session-list">
          <div v-if="!sessions.length" class="empty-state small">
            {{ store.token ? '暂无会话' : '请先登录' }}
          </div>
          <template v-else>
            <template v-for="group in [
              { key: 'today', label: '今天', items: sessionGroups.today },
              { key: 'yesterday', label: '昨天', items: sessionGroups.yesterday },
              { key: 'earlier', label: '更早', items: sessionGroups.earlier },
            ]" :key="group.key">
              <div v-if="group.items.length" class="session-group">
                <div class="session-group-title">{{ group.label }}</div>
                <div
                  v-for="session in group.items"
                  :key="session.id"
                  class="session-item"
                  :class="{ active: session.id === currentSessionId }"
                >
                  <button class="session-body" type="button" @click="onSelectSession(session.id)">
                    <div class="session-title">{{ session.title || '未命名会话' }}</div>
                  </button>
                  <span class="session-meta">{{ formatSessionTime(session) }}</span>
                  <button
                    class="session-delete"
                    type="button"
                    title="删除会话"
                    aria-label="删除会话"
                    @click.stop="onDeleteSession(session)"
                  >×</button>
                </div>
              </div>
            </template>
          </template>
        </div>
        <div class="session-footer">
          <button class="ghost-btn session-view-all" type="button">⌖ 查看全部记录</button>
        </div>
      </section>

      <section class="chat-panel">
        <div ref="messagesEl" class="messages">
          <div v-if="!messages.length" class="empty-state">
            输入一个财务制度或流程问题开始问答
          </div>
          <div
            v-for="(msg, idx) in messages"
            :key="idx"
            class="message"
            :class="msg.role"
          >
            <div v-if="msg.role === 'assistant'" class="msg-avatar assistant">
              <img :src="assistantAvatar" alt="AI助手" />
            </div>
            <div class="bubble-col">
              <div class="bubble">
                <template v-if="msg.role === 'user'">
                  <div v-if="msg.attachments && msg.attachments.length" class="bubble-images">
                    <a
                      v-for="(att, aIdx) in msg.attachments"
                      :key="aIdx"
                      :href="att.data_url"
                      target="_blank"
                      rel="noopener"
                      class="bubble-image-link"
                    >
                      <img :src="att.data_url" :alt="`附件${aIdx + 1}`" />
                    </a>
                  </div>
                  <div v-if="msg.text" class="bubble-body">{{ msg.text }}</div>
                </template>
                <template v-else>
                  <div
                    v-if="!msg.text && streaming && idx === messages.length - 1"
                    class="typing-indicator"
                    aria-label="AI 正在生成回答"
                  >
                    <span></span><span></span><span></span>
                  </div>
                  <div
                    v-else
                    class="bubble-body markdown-body"
                    v-html="renderMarkdown(msg.text)"
                    @click="onBubbleClick"
                  />
                  <div v-if="msg.references && msg.references.length" class="bubble-references">
                    <div class="bubble-references-title">参考来源</div>
                    <div class="bubble-references-body">
                      <details
                        v-for="(ref, rIdx) in msg.references"
                        :key="rIdx"
                        class="bubble-reference-item"
                      >
                        <summary>
                          <span class="ref-icon">📄</span>
                          <span class="ref-title">{{ rIdx + 1 }}.{{ ref.source_title || '未知来源' }}</span>
                          <small v-if="ref.page_no" class="ref-page">第 {{ ref.page_no }} 页</small>
                          <span class="ref-arrow">›</span>
                        </summary>
                        <a
                          v-if="ref.source_url"
                          :href="ref.source_url"
                          target="_blank"
                          rel="noopener noreferrer"
                          class="ref-url-line"
                          @click.stop
                        >🔗 {{ ref.source_url }}</a>
                        <div v-if="ref.snippet" class="ref-snippet">{{ ref.snippet.trim() }}</div>
                      </details>
                    </div>
                  </div>
                </template>
              </div>
              <div class="bubble-foot">
                <template v-if="msg.role === 'assistant'">
                  <div class="bubble-actions">
                    <button type="button" title="复制" @click="copyText(msg.text)">⎘</button>
                    <button type="button" title="赞">👍</button>
                    <button type="button" title="踩">👎</button>
                    <button type="button" title="分享">↗</button>
                  </div>
                  <span class="bubble-time">{{ formatBubbleTime(msg) }}</span>
                </template>
                <template v-else>
                  <span class="bubble-time">{{ formatBubbleTime(msg) }}</span>
                </template>
              </div>
            </div>
            <div v-if="msg.role === 'user'" class="msg-avatar user">{{ userAvatarInitial }}</div>
          </div>
        </div>

        <form class="composer" @submit.prevent="submit">
          <div v-if="pendingImages.length" class="composer-images">
            <div
              v-for="(img, idx) in pendingImages"
              :key="img.id"
              class="composer-image"
            >
              <img :src="img.data_url" :alt="`图片${idx + 1}`" />
              <button
                class="composer-image-remove"
                type="button"
                title="移除"
                @click="removePendingImage(idx)"
              >×</button>
            </div>
          </div>
          <textarea
            v-model="question"
            rows="2"
            placeholder="输入问题，或上传图片/文件，AI 将为您解答..."
            :disabled="streaming"
            @keydown="onComposerKeydown"
          />
          <div class="composer-row">
            <div class="composer-chips">
              <button type="button" class="composer-chip" :disabled="streaming" @click="pickImages">
                <span>📎</span><span>上传文件</span>
              </button>
              <button type="button" class="composer-chip" :disabled="streaming" @click="pickImages">
                <span>🖼️</span><span>图片识别</span>
              </button>
              <button
                type="button"
                class="composer-chip"
                :class="{ active: deepThinking }"
                @click="deepThinking = !deepThinking"
              >
                <span>🧠</span><span>深度思考</span>
              </button>
            </div>
            <button class="composer-send" type="submit" :disabled="streaming" title="发送">
              <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round">
                <path d="M22 2 11 13" />
                <path d="M22 2l-7 20-4-9-9-4 20-7z" />
              </svg>
            </button>
          </div>
          <input
            ref="fileInput"
            type="file"
            accept="image/png,image/jpeg"
            multiple
            hidden
            @change="onFilesPicked"
          />
        </form>
      </section>
    </div>

    <div
      v-if="lightboxSrc"
      class="image-lightbox"
      role="dialog"
      aria-label="预览图片"
      @click="lightboxSrc = ''"
    >
      <img :src="lightboxSrc" alt="预览" @click.stop />
      <button
        class="image-lightbox-close"
        type="button"
        aria-label="关闭预览"
        @click="lightboxSrc = ''"
      >×</button>
    </div>
  </section>
</template>
