<template>
  <div class="qa-view">
    <div class="qa-layout">
      <aside class="session-panel">
        <div class="panel-header">
          <div>
            <h3>问答</h3>
            <!-- <span>{{ qaStore.sessions.length }} 个会话</span> -->
          </div>
          <a-button type="primary" @click="createSession">
            <PlusOutlined style="color: #fff" /> 新会话
          </a-button>
        </div>

        <div class="session-list">
          <a-popover
            v-for="session in qaStore.sessions"
            :key="session.id"
            trigger="hover"
            placement="rightTop"
            :arrow="false"
            :overlayStyle="{ padding: 0 }"
          >
            <template #content>
              <div class="session-popover-actions">
                <a-button type="text" size="small" block @click="renameSession(session.id)" :disabled="qaStore.isStreaming">
                  重命名
                </a-button>
                <a-button type="text" danger size="small" block @click="removeSession(session.id)" :disabled="qaStore.isStreaming">
                  删除
                </a-button>
              </div>
            </template>
            <div
              class="session-item"
              :class="{ active: session.id === qaStore.sessionId }"
              @click="switchSession(session.id)"
            >
              <div class="session-item__title">{{ session.title }}</div>
              <div class="session-item__meta">
                <span>{{ formatSessionTime(session.updatedAt) }}</span>
                <span>{{ session.messages.length }} 条消息</span>
              </div>
            </div>
          </a-popover>
        </div>
      </aside>

      <section class="chat-panel">
        <div class="chat-header">
          <div>
            <h2>{{ currentSessionTitle }}</h2>
            <!-- <p>用于快速问答、核对依据和发起追问，结果可继续沉淀到 Research。</p> -->
          </div>
          <a-space>
            <!-- <a-button @click="renameCurrentSession" :disabled="qaStore.isStreaming">重命名</a-button> -->
            <a-button @click="importContextFromBasket" :disabled="!basketStore.items.length">导入资料篮上下文</a-button>
          </a-space>
        </div>

        <div class="message-list" ref="messageListRef">
          <template v-if="qaStore.messages.length === 0">
            <div class="welcome">
              <h3>智能问答助手</h3>
              <p>适合快速问“这份文件讲了什么”“这个事项需要哪些材料”“依据文件有哪些”。</p>
              <div class="quick-prompts">
                <a-tag
                  v-for="prompt in suggestionChips"
                  :key="prompt"
                  color="blue"
                  class="prompt-tag"
                  @click="sendMessage(prompt)"
                >
                  {{ prompt }}
                </a-tag>
              </div>
            </div>
          </template>

          <!-- QAMessage 没有唯一 id 字段，用 role+timestamp+idx 组合作为 key -->
          <ChatMessage
            v-for="(msg, idx) in qaStore.messages"
            :key="`${msg.role}-${msg.timestamp}-${idx}`"
            :message="msg"
            assistant-label="问答助手"
            @reference-click="handleReferenceClick"
          />

          <div v-if="qaStore.isStreaming" class="streaming-message">
            <ChatMessage
              :message="{
                role: 'assistant',
                content: qaStore.currentAssistantContent || '正在回答...',
                references: qaStore.references,
                timestamp: Date.now()
              }"
              assistant-label="问答助手"
              @reference-click="handleReferenceClick"
            />
          </div>
        </div>

        <div class="chat-actions" v-if="latestAssistantMessage">
          <a-space>
            <a-button @click="openAnswerImportDialog">将本轮回答加入资料篮</a-button>
            <a-button @click="copyLatestAnswer">复制当前回答</a-button>
          </a-space>
        </div>

        <div class="input-area">
          <a-textarea
            v-model:value="inputText"
            :auto-size="{ minRows: 1, maxRows: 4 }"
            placeholder="输入问题，如：这份文件的核心要求是什么？办理这个事项需要哪些材料？"
            @pressEnter.exact="handleSend"
            :disabled="qaStore.isStreaming"
          />
          <a-button
            type="primary"
            :loading="qaStore.isStreaming"
            :disabled="!inputText.trim()"
            @click="handleSend"
          >
            <SendOutlined />
          </a-button>
        </div>
      </section>

      <aside class="sidebar">
        <!-- <div class="panel-header panel-header--compact"> -->
          <!-- <div> -->
            <!-- <h3>上下文与依据</h3> -->
            <!-- <span>导入资料、引用文档和建议追问</span> -->
          <!-- </div> -->
        <!-- </div> -->

        <a-tabs v-model:activeKey="sidebarTab" size="small">
          <a-tab-pane key="context" tab="上下文">
            <div class="sidebar-list">
              <a-empty v-if="qaStore.contextItems.length === 0" description="当前没有问答上下文" />
              <a-card v-for="(item, idx) in qaStore.contextItems" :key="`${item.item_type}-${idx}-${item.title}`" size="small" class="context-card">
                <div class="context-card__header">
                  <a-tag color="blue">{{ item.item_type }}</a-tag>
                  <a-button type="link" danger size="small" @click="qaStore.removeContextItem(item)">移除</a-button>
                </div>
                <div class="context-card__title">{{ item.title }}</div>
              </a-card>
            </div>
          </a-tab-pane>

          <a-tab-pane key="refs" tab="引用文档">
            <div class="sidebar-list">
              <a-empty v-if="qaStore.references.length === 0" description="暂无引用文档" />
              <a-alert
                v-else-if="guideReferenceCount"
                type="warning"
                show-icon
                class="guide-alert"
                message="本轮问答包含办事指南结构化证据"
                :description="`当前共有 ${guideReferenceCount} 条 Guide 来源引用，适合快速核对材料、条件、收费、时限和窗口信息。`"
              />
              <div v-for="group in referenceGroups" :key="group.key" class="reference-group">
                <div class="reference-group__header" :class="{ 'reference-group__header--guide': group.key === 'guide' }">
                  <span>{{ group.label }}</span>
                  <a-tag>{{ group.items.length }}</a-tag>
                </div>
                <div v-for="(ref, idx) in group.items" :key="`${group.key}-${ref.doc_id}-${idx}`" class="ref-card-wrap">
                  <CitationCard :reference="ref" :index="idx" @open="openReferenceTarget" />
                </div>
              </div>
            </div>
          </a-tab-pane>

          <a-tab-pane key="suggestions" tab="建议追问">
            <div class="sidebar-list suggestions-list">
              <a-button v-for="prompt in suggestionChips" :key="prompt" block class="suggestion-button" @click="sendMessage(prompt)">
                {{ prompt }}
              </a-button>
            </div>
          </a-tab-pane>
        </a-tabs>
      </aside>
    </div>

    <ImportToResearchDialog
      v-model:open="importDialogOpen"
      :items="pendingImportItems"
      :title="importDialogTitle"
      @confirm="handleImportConfirm"
    />

    <!-- Reference preview modal -->
    <a-modal
      v-model:open="refPreviewOpen"
      :title="refPreviewRef?.title || '引用预览'"
      :footer="null"
      width="640px"
      :bodyStyle="{ maxHeight: '60vh', overflowY: 'auto' }"
    >
      <div v-if="refPreviewRef" style="margin-bottom: 12px">
        <a-space>
          <a-tag v-if="refPreviewRef.doc_number">{{ refPreviewRef.doc_number }}</a-tag>
          <a-tag v-if="refPreviewRef.source_label" color="blue">{{ refPreviewRef.source_label }}</a-tag>
          <a-button type="link" size="small" @click="refPreviewRef && openReferenceTarget(refPreviewRef)">
            查看文档详情 →
          </a-button>
        </a-space>
      </div>
      <div v-if="refPreviewChunks.length > 0">
        <div
          v-for="(chunk, ci) in refPreviewChunks"
          :key="ci"
          style="margin-bottom: 12px; padding: 12px; background: #fafafa; border-radius: 8px; border: 1px solid #f0f0f0"
        >
          <div v-if="chunk.heading_hierarchy?.length" style="margin-bottom: 6px">
            <a-tag v-for="h in chunk.heading_hierarchy" :key="h" :bordered="false" size="small" color="blue">{{ h }}</a-tag>
          </div>
          <div style="font-size: 13px; line-height: 1.7; color: rgba(0,0,0,0.75)" v-html="chunk.text" />
          <div style="margin-top: 6px; font-size: 12px; color: rgba(0,0,0,0.35)">
            <span v-if="chunk.page_number">第 {{ chunk.page_number }} 页</span>
            <span v-if="chunk.chunk_index != null"> · chunk #{{ chunk.chunk_index }}</span>
          </div>
        </div>
      </div>
      <a-empty v-else description="暂无命中片段" />
    </a-modal>

    <a-modal
      v-model:open="renameModalOpen"
      title="重命名会话"
      @ok="confirmRename"
      ok-text="确定"
      cancel-text="取消"
    >
      <a-input v-model:value="renameModalValue" placeholder="输入新的会话名称" @pressEnter="confirmRename" />
    </a-modal>
  </div>
</template>

/**
 * 智能问答视图
 * 三栏布局：左侧会话列表、中间聊天对话区、右侧上下文与引用文档面板。
 * 通过 SSE 流式接收 AI 回答，支持导入资料篮上下文、将问答结果沉淀到 Research。
 * 可从文档详情页或事项详情页通过 URL query 参数携带上下文快速发起问答。
 */
<script setup lang="ts">
import { computed, nextTick, onBeforeUnmount, ref, watch } from 'vue'
import { message, Modal } from 'ant-design-vue'
import { useRoute, useRouter } from 'vue-router'
import { PlusOutlined, SendOutlined } from '@ant-design/icons-vue'
import { buildQABody } from '@/api/qa'
import ChatMessage from '@/components/ChatMessage.vue'
import CitationCard from '@/components/CitationCard.vue'
import ImportToResearchDialog from '@/components/ImportToResearchDialog.vue'
import { useResearchImport } from '@/composables/useResearchImport'
import { useSSE } from '@/composables/useSSE'
import { useBasketStore } from '@/stores/basket'
import { useQAStore } from '@/stores/qa'
import type { BasketItem } from '@/types/basket'
import type { ResearchReference } from '@/types/document'
import type { GraphNode, GraphEdge } from '@/types/graph'
import type { ResearchImportDialogPayload } from '@/types/research-import'
import { formatSessionTime } from '@/utils/basketKeys'
import { getReferenceTargetPath } from '@/utils/referenceRouting'

const route = useRoute()
const router = useRouter()
const qaStore = useQAStore()
const basketStore = useBasketStore()
const { connect, disconnect } = useSSE()
const { applyImport } = useResearchImport()

const inputText = ref('')
const sidebarTab = ref('refs') // 右侧面板默认展示"引用文档"标签
const messageListRef = ref<HTMLElement>()
const importDialogOpen = ref(false)
const importDialogTitle = ref('将问答结果加入资料篮')
const pendingImportItems = ref<BasketItem[]>([])
const lastLaunchKey = ref('') // 防止同一 launchKey 重复触发会话创建

// Reference preview state
const refPreviewOpen = ref(false)
const refPreviewRef = ref<ResearchReference | null>(null)
const refPreviewChunks = ref<any[]>([])

const currentSessionTitle = computed(() => {
  return qaStore.sessions.find((item) => item.id === qaStore.sessionId)?.title || '智能问答'
})

const latestAssistantMessage = computed(() => {
  return [...qaStore.messages].reverse().find((item) => item.role === 'assistant')
})

const referenceGroups = computed(() => {
  const order = ['guide', 'seed', 'search', 'graph']
  const labelMap: Record<string, string> = {
    guide: '办事指南结构化证据',
    seed: '显式纳入资料',
    search: '混合检索命中',
    graph: '图谱补充材料',
  }
  const groupMap = new Map<string, { key: string; label: string; items: ResearchReference[] }>()

  qaStore.references.forEach((item) => {
    const key = item.source_group || 'search'
    if (!groupMap.has(key)) {
      groupMap.set(key, {
        key,
        label: item.source_label || labelMap[key] || '混合检索命中',
        items: [],
      })
    }
    groupMap.get(key)?.items.push(item)
  })

  return [...groupMap.values()].sort((left, right) => {
    const leftIndex = order.includes(left.key) ? order.indexOf(left.key) : order.length
    const rightIndex = order.includes(right.key) ? order.indexOf(right.key) : order.length
    return leftIndex - rightIndex
  })
})

const guideReferenceCount = computed(() => qaStore.references.filter((item) => item.source_group === 'guide').length)

function getLatestUserQuestion() {
  return [...qaStore.messages].reverse().find((item) => item.role === 'user')?.content || ''
}

// 根据当前上下文类型动态生成建议追问提示（事项/文档/通用）
const suggestionChips = computed(() => {
  const firstContext = qaStore.contextItems[0]
  if (firstContext?.item_type === 'matter') {
    return [
      '这个事项需要哪些材料？',
      '这个事项的办理时限是什么？',
      '这个事项的主要依据文件有哪些？',
    ]
  }
  if (firstContext?.item_type === 'document') {
    return [
      '这份文件的核心要求是什么？',
      '这份文件适用于哪些对象？',
      '这份文件的主要依据链是什么？',
    ]
  }
  return [
    '请概括这个问题的核心结论',
    '请列出主要依据文件',
    '请说明执行要点和注意事项',
  ]
})

/**
 * Handle reference click from LLM output [N].
 *
 * LLM numbers passages sequentially across all documents:
 *   Doc A (3 chunks) → [1] [2] [3]
 *   Doc B (2 chunks) → [4] [5]
 *
 * But qaStore.references is document-level. We flatten matched_chunks
 * to build a passage-level index matching LLM's numbering.
 */
function handleReferenceClick(index: number) {
  // Build flat passage list: each entry = { parentRef, chunk }
  const flatPassages: { parentRef: ResearchReference; chunk: any }[] = []
  for (const ref of qaStore.references) {
    const chunks = Array.isArray(ref.matched_chunks) ? ref.matched_chunks : []
    if (chunks.length === 0) {
      // Document with no chunks still occupies one slot
      flatPassages.push({ parentRef: ref, chunk: null })
    } else {
      for (const chunk of chunks) {
        flatPassages.push({ parentRef: ref, chunk })
      }
    }
  }

  const passage = flatPassages[index - 1]
  if (!passage) return

  refPreviewRef.value = passage.parentRef
  refPreviewChunks.value = passage.chunk ? [passage.chunk] : []
  refPreviewOpen.value = true
  sidebarTab.value = 'refs'
}

function scrollToBottom() {
  nextTick(() => {
    if (messageListRef.value) {
      messageListRef.value.scrollTop = messageListRef.value.scrollHeight
    }
  })
}

watch(() => qaStore.currentAssistantContent, scrollToBottom)
watch(() => qaStore.messages.length, scrollToBottom)

/** 发送问答消息：通过 SSE 流式接收 AI 回答，逐块拼接文本、收集引用文档和图谱数据 */
async function sendMessage(text?: string) {
  const question = (text || inputText.value).trim()
  if (!question || qaStore.isStreaming) return

  inputText.value = ''
  qaStore.addUserMessage(question)
  qaStore.startStreaming()
  scrollToBottom()

  await connect({
    url: '/api/ai/v1/qa',
    body: buildQABody(question, qaStore.sessionId, qaStore.getSeedDocIds()),
    onMessage(data) {
      if (data.type === 'text') {
        qaStore.appendStreamChunk(data.content ?? '') // 逐块追加文本
      } else if (data.type === 'reference') {
        const payload = (data.payload || {}) as Record<string, unknown>
        qaStore.addReference({
          doc_id: data.doc_id ?? '',
          title: data.title ?? '',
          doc_number: data.doc_number,
          relevance_score: data.relevance_score,
          source_group: payload.source_group as string | undefined,
          source_label: payload.source_label as string | undefined,
          summary: payload.summary as string | undefined,
          profile_id: payload.profile_id as string | undefined,
          matched_fields: payload.matched_fields as string[] | undefined,
          matched_field_labels: payload.matched_field_labels as string[] | undefined,
          matched_chunks: Array.isArray(payload.matched_chunks) ? payload.matched_chunks as any[] : undefined,
        })
        if ((payload.source_group as string | undefined) === 'guide') {
          sidebarTab.value = 'refs'
        }
      } else if (data.type === 'graph') {
        qaStore.setGraphData({
          nodes: (data.nodes ?? []) as GraphNode[],
          edges: (data.edges ?? []) as GraphEdge[],
        })
      }
    },
    onError(err) {
      qaStore.appendStreamChunk('\n\n[请求出错，请稍后重试]')
      console.error('QA SSE error:', err)
    },
    onDone() {
      qaStore.finishStreaming()
      scrollToBottom()
    },
  })
}

function handleSend(e: Event) {
  e.preventDefault()
  sendMessage()
}

function createSession() {
  disconnect()
  qaStore.createSession()
}

function switchSession(id: string) {
  disconnect()
  qaStore.switchSession(id)
}

function removeSession(id: string) {
  Modal.confirm({
    title: '确认删除会话？',
    content: '删除后不可恢复。',
    okText: '删除',
    okType: 'danger',
    cancelText: '取消',
    onOk() {
      disconnect()
      qaStore.deleteSession(id)
    },
  })
}

// ── Rename modal ──────────────────────────────────────────────────────────
const renameModalOpen = ref(false)
const renameModalValue = ref('')
const renameTargetId = ref('')

function renameCurrentSession() {
  renameSession(qaStore.sessionId || '')
}

function renameSession(id: string) {
  const session = qaStore.sessions.find(s => s.id === id)
  renameTargetId.value = id
  renameModalValue.value = session?.title || ''
  renameModalOpen.value = true
}

function confirmRename() {
  if (renameModalValue.value.trim()) {
    qaStore.renameSession(renameTargetId.value, renameModalValue.value.trim())
  }
  renameModalOpen.value = false
}

function importContextFromBasket() {
  const added = qaStore.addContextItems(basketStore.items)
  if (!added) {
    message.info('资料篮中没有新的上下文可导入')
    return
  }
  sidebarTab.value = 'context'
  message.success(`已导入 ${added} 条问答上下文`)
}

function openReferenceTarget(reference: ResearchReference) {
  router.push(getReferenceTargetPath(reference))
}

function openReferenceImportDialog(reference: ResearchReference) {
  pendingImportItems.value = [
    {
      item_type: 'document',
      title: reference.title,
      selected_from: 'qa',
      importance: 'reference',
      doc_id: reference.doc_id,
      doc_code: reference.doc_number,
      added_at: Date.now(),
    },
  ]
  importDialogTitle.value = `将《${reference.title}》加入 Research`
  importDialogOpen.value = true
}

function openAnswerImportDialog() {
  if (!latestAssistantMessage.value) return
  pendingImportItems.value = buildAnswerImportItems()
  importDialogTitle.value = '将本轮问答结果加入 Research'
  importDialogOpen.value = true
}

/** 将最新一轮问答结果（回答 + 引用文档）组装为资料篮条目，用于导入 Research */
function buildAnswerImportItems(): BasketItem[] {
  const answer = latestAssistantMessage.value
  if (!answer) return []
  const latestQuestion = getLatestUserQuestion()
  return [
    {
      item_type: 'answer',
      title: `问答：${(latestQuestion || '未命名问题').slice(0, 24)}`,
      selected_from: 'qa',
      importance: 'reference',
      answer: answer.content,
      question: latestQuestion || undefined,
      references: qaStore.references.map((item) => ({
        doc_id: item.doc_id,
        title: item.title,
        doc_number: item.doc_number,
      })),
      added_at: Date.now(),
    },
    ...qaStore.references.map<BasketItem>((item) => ({
      item_type: 'document',
      title: item.title,
      selected_from: 'qa',
      importance: 'reference',
      doc_id: item.doc_id,
      doc_code: item.doc_number,
      added_at: Date.now(),
    })),
  ]
}

function handleImportConfirm(payload: ResearchImportDialogPayload) {
  applyImport(pendingImportItems.value, payload)
}

async function copyLatestAnswer() {
  if (!latestAssistantMessage.value) return
  try {
    await navigator.clipboard.writeText(latestAssistantMessage.value.content)
    message.success('回答已复制')
  } catch {
    message.warning('复制失败，请手动复制')
  }
}

// ── URL query 参数解析与快速发起问答 ─────────────────────────

/** 从 route.query 中安全提取单个字符串值（兼容数组形式） */
function getSingleQueryValue(value: unknown): string {
  if (Array.isArray(value)) return String(value[0] || '')
  return typeof value === 'string' ? value : ''
}

/** 根据 URL query 参数构建上下文条目（文档或事项），用于从外部页面跳转进入问答 */
function buildLaunchItem(): BasketItem | null {
  const kind = getSingleQueryValue(route.query.kind)
  if (kind === 'document') {
    const docId = getSingleQueryValue(route.query.docId)
    const title = getSingleQueryValue(route.query.title)
    if (!docId || !title) return null
    return {
      item_type: 'document',
      title,
      selected_from: 'detail',
      importance: 'core',
      doc_id: docId,
      doc_code: getSingleQueryValue(route.query.docCode) || undefined,
      added_at: Date.now(),
    }
  }
  if (kind === 'matter') {
    const matterId = getSingleQueryValue(route.query.matterId)
    const title = getSingleQueryValue(route.query.title)
    if (!matterId || !title) return null
    return {
      item_type: 'matter',
      title,
      selected_from: 'matter',
      importance: 'core',
      matter_id: matterId,
      governing_doc_ids: getSingleQueryValue(route.query.governingDocIds)
        .split(',')
        .filter(Boolean),
      added_at: Date.now(),
    }
  }
  return null
}

// 监听 launchKey 变化：从文档详情/事项详情跳转过来时自动创建新会话并预填提示语
watch(
  () => route.query.launchKey,
  async (launchKey) => {
    const normalized = getSingleQueryValue(launchKey)
    if (!normalized || normalized === lastLaunchKey.value) return

    lastLaunchKey.value = normalized
    const prompt = getSingleQueryValue(route.query.prompt)
    const launchItem = buildLaunchItem()

    qaStore.createSession(getSingleQueryValue(route.query.title) || '新问答会话')
    if (launchItem) {
      qaStore.addContextItems([launchItem])
      sidebarTab.value = 'context'
    }

    if (prompt) {
      inputText.value = prompt
      message.success('已带入对象上下文到问答会话')
    }

    await router.replace({ path: route.path, query: {} })
  },
  { immediate: true },
)

onBeforeUnmount(() => {
  disconnect()
})

</script>

<style scoped lang="less">
.qa-view {
  height: calc(100vh - 124px);
  overflow: hidden;
}

.qa-layout {
  height: 100%;
  display: grid;
  grid-template-columns: 280px minmax(0, 1fr) 340px;
  background: #fff;
}

.session-panel,
.chat-panel,
.sidebar {
  min-height: 0;
}

.session-panel {
  border-right: 1px solid #f0f0f0;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.chat-panel {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.sidebar {
  border-left: 1px solid #f0f0f0;
  padding: 16px;
  overflow: hidden;
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;

  h3,
  h2 {
    margin: 0;
  }

  span,
  p {
    color: #8c8c8c;
    margin: 4px 0 0;
    font-size: 12px;
  }
}

.panel-header--compact {
  margin-bottom: 12px;
}

.session-list,
.sidebar-list {
  flex: 1;
  overflow-y: auto;
}

.session-item {
  padding: 10px 12px;
  border: 1px solid #f0f0f0;
  border-radius: 10px;
  cursor: pointer;
  margin-bottom: 8px;
  transition: all 0.2s ease;

  &:hover,
  &.active {
    border-color: #1677ff;
    background: #f0f7ff;
  }
}

.session-popover-actions {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 80px;
}

.session-item__title {
  font-weight: 600;
}

.session-item__meta {
  margin-top: 4px;
  color: #8c8c8c;
  font-size: 12px;
  display: flex;
  justify-content: space-between;
}

.chat-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  padding: 16px 24px;
  border-bottom: 1px solid #f0f0f0;

  h2 {
    margin: 0;
    font-size: 20px;
  }

  p {
    margin: 4px 0 0;
    color: #8c8c8c;
  }
}

.message-list {
  flex: 1;
  overflow-y: auto;
  padding: 16px 24px;
}

.welcome {
  text-align: center;
  padding: 60px 0 30px;
}

.quick-prompts {
  .prompt-tag {
    cursor: pointer;
    margin: 4px;
    padding: 4px 12px;
    font-size: 13px;
  }
}

.chat-actions {
  padding: 0 24px 12px;
}

.input-area {
  display: flex;
  gap: 8px;
  padding: 16px 24px;
  border-top: 1px solid #f0f0f0;
  background: #fafafa;

  :deep(.ant-input) {
    flex: 1;
    border-radius: 8px;
  }
}

.context-card,
.ref-card-wrap {
  margin-bottom: 8px;
}

.guide-alert {
  margin-bottom: 12px;
  border-radius: 12px;
}

.reference-group + .reference-group {
  margin-top: 16px;
}

.reference-group__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
  font-weight: 600;
}

.reference-group__header--guide {
  padding: 10px 12px;
  border-radius: 12px;
  background: linear-gradient(180deg, #fff8e1 0%, #fffdf5 100%);
  color: #ad6800;
}

.context-card__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.context-card__title {
  margin-top: 6px;
  font-weight: 600;
}

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

.suggestion-button {
  text-align: left;
  height: auto;
  white-space: normal;
}

@media (max-width: 1280px) {
  .qa-layout {
    grid-template-columns: 240px minmax(0, 1fr) 300px;
  }
}
</style>