<template>
  <div class="research-create-page">
    <div class="create-layout">
      <!-- Left: main form area -->
      <main class="create-main">
        <a-alert
          v-if="continueFromSectionTitle"
          type="warning"
          show-icon
          style="margin-bottom: 16px; border-radius: 12px"
          :message="'已从章节「' + continueFromSectionTitle + '」衍生新研究'"
          description="系统已预填主题与问题。你可以继续补充范围、目标或切换模板后再生成计划。"
        />



        <TaskEditor
          :task="task"
          :is-planning="store.isPlanning"
          :is-running="false"
          :can-run="!!plan"
          :preset-tasks="presetTasks"
          @generate-plan="handleGeneratePlan"
          @run-research="handleStartResearch"
          @apply-preset="applyPreset"
        />

        <!-- F1: Assessment summary -->
        <div v-if="clarifyAssessment" class="assessment-bar" style="margin-top: 12px">
          <div class="assessment-bar__title">可行性评估</div>
          <div class="assessment-bar__items">
            <a-tag :color="assessmentColor(clarifyAssessment.clarity)">
              清晰度: {{ assessmentLabel(clarifyAssessment.clarity) }}
            </a-tag>
            <a-tag :color="assessmentColor(clarifyAssessment.scope)">
              范围: {{ assessmentLabel(clarifyAssessment.scope) }}
            </a-tag>
            <a-tag :color="assessmentColor(clarifyAssessment.feasibility)">
              可行性: {{ assessmentLabel(clarifyAssessment.feasibility) }}
            </a-tag>
            <a-tag :color="assessmentColor(clarifyAssessment.data_coverage)">
              数据覆盖: {{ assessmentLabel(clarifyAssessment.data_coverage) }}
            </a-tag>
            <a-tag :color="blockerColor(clarifyAssessment.blockers)">
              阻塞点: {{ blockerLabel(clarifyAssessment.blockers) }}
            </a-tag>
          </div>
        </div>

        <!-- F1: Clarification dialog -->
        <div v-if="clarifyMessages.length > 0 || clarifyLoading" ref="clarifySectionRef" class="clarify-section" style="margin-top: 18px">
          <a-card :bordered="false" title="需求澄清" style="border-radius: 14px">
            <div class="clarify-messages">
              <div
                v-for="(msg, idx) in clarifyMessages"
                :key="idx"
                class="clarify-msg"
                :class="msg.role === 'user' ? 'clarify-msg--user' : 'clarify-msg--assistant'"
              >
                <div class="clarify-msg__bubble" :class="{ 'clarify-msg__bubble--file': msg.fileAttachment }">
                  <template v-if="msg.fileAttachment">
                    <div class="clarify-msg__file">
                      <PaperClipOutlined class="clarify-msg__file-icon" />
                      <span class="clarify-msg__file-name">{{ msg.fileAttachment.fileName }}</span>
                      <span class="clarify-msg__file-meta">{{ formatCharCount(msg.fileAttachment.charCount) }}</span>
                    </div>
                  </template>
                  <template v-else-if="msg.role === 'assistant' && msg.questions">
                    <div class="clarify-msg__questions">
                      <div v-for="(q, qi) in msg.questions" :key="qi" style="margin-bottom: 6px">
                        {{ qi + 1 }}. {{ q }}
                      </div>
                    </div>
                  </template>
                  <template v-else>
                    <div>{{ msg.content }}</div>
                  </template>
                  <div v-if="msg.note" style="color: rgba(0,0,0,0.45); font-size: 12px; margin-top: 6px">{{ msg.note }}</div>
                </div>
              </div>
              <!-- Thinking indicator -->
              <div v-if="clarifyLoading" class="clarify-msg clarify-msg--assistant">
                <div class="clarify-msg__bubble clarify-thinking">
                  <span class="clarify-thinking__dot"></span>
                  <span class="clarify-thinking__dot"></span>
                  <span class="clarify-thinking__dot"></span>
                  <span class="clarify-thinking__label">正在分析...</span>
                </div>
              </div>
            </div>
            <div v-if="clarifyWaiting" style="margin-top: 12px">
              <!-- Uploaded files list -->
              <div v-if="uploadedMaterials.length > 0" class="clarify-uploads">
                <a-tag
                  v-for="item in uploadedMaterials"
                  :key="item.fileId"
                  :color="item.status === 'error' ? 'error' : item.status === 'uploading' ? 'processing' : 'success'"
                  closable
                  @close="removeUploadedMaterial(item.fileId)"
                >
                  <template #icon>
                    <LoadingOutlined v-if="item.status === 'uploading'" />
                    <PaperClipOutlined v-else />
                  </template>
                  {{ item.originalFilename }}
                  <span v-if="item.status === 'done'" style="color: rgba(0,0,0,0.35); margin-left: 4px">
                    {{ formatCharCount(item.charCount) }}
                  </span>
                  <span v-if="item.status === 'error'" style="margin-left: 4px">
                    {{ item.errorMsg || '上传失败' }}
                  </span>
                </a-tag>
              </div>
              <div class="clarify-input-wrap">
                <a-upload
                  :show-upload-list="false"
                  :before-upload="handleFileUpload"
                  :multiple="true"
                  accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.png,.jpg,.jpeg,.tiff,.bmp,.txt,.md"
                >
                  <a-button size="small" :disabled="clarifyLoading || !store.recordId" class="clarify-upload-btn" title="上传文件">
                    <template #icon><PaperClipOutlined /></template>
                  </a-button>
                </a-upload>
                <a-textarea
                  v-model:value="clarifyInput"
                  placeholder="回答澄清问题...（Shift+Enter 换行）"
                  :disabled="clarifyLoading"
                  :auto-size="{ minRows: 1, maxRows: 6 }"
                  @keydown="handleClarifyKeydown"
                />
                <a-button type="primary" size="small" :loading="clarifyLoading" @click="submitClarifyAnswer" class="clarify-send-btn">
                  发送
                </a-button>
              </div>
            </div>
          </a-card>
        </div>

        <div v-if="plan" style="margin-top: 18px">
          <PlanViewer
            :plan="plan"
            :record-id="store.recordId ?? undefined"
            @plan-saved="(p) => { plan = p }"
          >
            <template #actions="{ editing, saving, startEdit, cancelEdit, saveEdit }">
              <a-space>
                <!-- editing mode -->
                <a-button v-if="editing" :disabled="saving" @click="cancelEdit">取消</a-button>
                <a-button v-if="editing" type="primary" :loading="saving" @click="saveEdit">
                  <SaveOutlined /> 保存计划
                </a-button>
                <!-- normal mode -->
                <a-button v-if="!editing" :disabled="store.isRunning || store.isPlanning" @click="startEdit">
                  <EditOutlined /> 编辑计划
                </a-button>
                <a-button v-if="!editing" :loading="store.isPlanning" :disabled="store.isRunning" @click="handleGeneratePlan">
                  <ReloadOutlined /> 重新生成
                </a-button>
                <a-button
                  v-if="!editing"
                  type="primary"
                  :disabled="store.isPlanning"
                  @click="handleStartResearch"
                >
                  <PlayCircleOutlined /> 确认并开始研究
                </a-button>
              </a-space>
            </template>
          </PlanViewer>
        </div>
      </main>

      <!-- Right: basket sidebar -->
      <aside class="create-sidebar">
        <div class="basket-panel">
          <div class="basket-panel__header">
            <span class="basket-panel__title">资料篮</span>
            <a-badge :count="basketStore.count" :overflow-count="99" />
          </div>

          <a-empty v-if="basketStore.count === 0" description="暂无资料" :image-style="{ height: '48px' }" />

          <div v-else class="basket-panel__list">
            <div
              v-for="item in basketStore.items.slice(0, 8)"
              :key="getBasketItemKey(item)"
              class="basket-item"
            >
              <div class="basket-item__title">{{ item.title }}</div>
              <div class="basket-item__meta">
                <a-tag :bordered="false" size="small">{{ getItemTypeLabel(item.item_type) }}</a-tag>
                <span>{{ getSourceLabel(item.selected_from) }}</span>
              </div>
            </div>
            <div v-if="basketStore.count > 8" class="basket-panel__more">
              还有 {{ basketStore.count - 8 }} 项...
            </div>
          </div>

          <!-- Uploaded files section -->
          <div v-if="sidebarUploadedFiles.length > 0" class="basket-panel__uploads">
            <div class="basket-panel__uploads-title">已上传文件</div>
            <div
              v-for="uf in sidebarUploadedFiles"
              :key="uf.fileId"
              class="basket-upload-item"
            >
              <div class="basket-upload-item__row">
                <LoadingOutlined v-if="uf.status === 'uploading'" class="basket-upload-item__icon" />
                <PaperClipOutlined v-else class="basket-upload-item__icon" />
                <a
                  v-if="uf.status === 'done' && store.recordId"
                  href="javascript:void(0)"
                  class="basket-upload-item__name"
                  :title="uf.fileName"
                  @click="downloadUploadedFile(store.recordId!, uf.fileId, uf.fileName)"
                >{{ uf.fileName }}</a>
                <span v-else class="basket-upload-item__name" :title="uf.fileName">{{ uf.fileName }}</span>
              </div>
              <div class="basket-upload-item__meta">
                <span v-if="uf.status === 'done'">{{ formatCharCount(uf.charCount) }}</span>
                <span v-else-if="uf.status === 'uploading'" style="color: rgba(0,0,0,0.45)">上传中...</span>
                <span v-else-if="uf.status === 'error'" style="color: #ff4d4f">{{ uf.errorMsg || '失败' }}</span>
                <a-tag :bordered="false" size="small" color="blue">用户上传</a-tag>
              </div>
            </div>
          </div>

          <div class="basket-panel__footer">
            <div class="basket-panel__actions">
              <a-button size="small" @click="basketStore.openDrawer">
                <template #icon><EyeOutlined /></template>
                查看全部
              </a-button>
              <a-upload
                :show-upload-list="false"
                :before-upload="handleBasketFileUpload"
                :multiple="true"
                accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.png,.jpg,.jpeg,.tiff,.bmp,.txt,.md"
              >
                <a-button size="small">
                  <template #icon><UploadOutlined /></template>
                  上传文件
                </a-button>
              </a-upload>
            </div>
            <a-button
              v-if="basketStore.count > 0"
              size="small"
              type="text"
              danger
              @click="basketStore.clearAll"
              class="basket-panel__clear"
            >
              清空资料篮
            </a-button>
          </div>
        </div>

        <!-- KB search toggle -->
        <div class="kb-toggle">
          <div class="kb-toggle__row">
            <a-switch v-model:checked="enableKbSearch" size="small" />
            <span class="kb-toggle__label">开启知识库查询</span>
            <a-tooltip title="开启后，澄清评估和研究执行过程中都会自动检索知识库补充材料；关闭则仅使用资料篮中的文档">
              <QuestionCircleOutlined style="color: rgba(0,0,0,0.35); font-size: 13px" />
            </a-tooltip>
          </div>
          <div class="kb-toggle__hint">
            {{ enableKbSearch ? '系统将自动检索知识库补充研究材料' : '仅使用资料篮中的文档进行研究' }}
          </div>
        </div>
      </aside>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, reactive, onMounted, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { message } from 'ant-design-vue'
import { EyeOutlined, UploadOutlined, QuestionCircleOutlined, PaperClipOutlined, LoadingOutlined, SaveOutlined, EditOutlined, ReloadOutlined, PlayCircleOutlined } from '@ant-design/icons-vue'
import TaskEditor from '@/views/research/TaskEditor.vue'
import PlanViewer from '@/views/research/PlanViewer.vue'
import { useResearchRecordWorkbenchStore } from '@/stores/researchRecordWorkbench'
import { useBasketStore } from '@/stores/basket'
import { getItemTypeLabel, getSourceLabel, getBasketItemKey } from '@/utils/basketKeys'
import { downloadUploadedFile } from '@/api/researchRecords'
import { createDefaultResearchTask, RESEARCH_DEPTH_OPTIONS, RESEARCH_TEMPLATE_OPTIONS } from '@/types/research'
import type { ResearchPlan, ResearchTaskDraft } from '@/types/research'
import type { PresetTask } from '@/views/research/types'
import type { BasketItem } from '@/types/basket'

const route = useRoute()
const router = useRouter()
const store = useResearchRecordWorkbenchStore()
const basketStore = useBasketStore()

const task = reactive<ResearchTaskDraft>(createDefaultResearchTask())
const plan = ref<ResearchPlan | null>(null)
const importedItems = ref<BasketItem[]>([])
const continueFromSectionTitle = ref('')
// F3: regenerate mode — when navigated from /research/:id with ?from=xxx
const isRegenerate = ref(false)
const regenerateFromId = ref<string | null>(null)

// F1: clarification state
interface ClarifyMessage {
  role: 'user' | 'assistant'
  content: string
  questions?: string[]
  note?: string
  // file attachment
  fileAttachment?: { fileId: string; fileName: string; fileType: string; charCount: number }
}
const clarifyMessages = ref<ClarifyMessage[]>([])
const clarifyWaiting = ref(false)
const clarifyLoading = ref(false)
const clarifyInput = ref('')
const enableKbSearch = ref(true)
const clarifyAssessment = ref<Record<string, string> | null>(null)
const clarifySectionRef = ref<HTMLElement | null>(null)

function scrollToClarifyBottom() {
  nextTick(() => {
    clarifySectionRef.value?.scrollIntoView({ behavior: 'smooth', block: 'end' })
  })
}

function handleClarifyKeydown(e: KeyboardEvent) {
  if (e.key === 'Enter' && !e.shiftKey) {
    e.preventDefault()
    submitClarifyAnswer()
  }
}

// File upload state
interface UploadedMaterial {
  fileId: string
  originalFilename: string
  fileType: string
  charCount: number
  status: 'uploading' | 'done' | 'error'
  errorMsg?: string
}
const uploadedMaterials = ref<UploadedMaterial[]>([])

function formatCharCount(n: number): string {
  if (n >= 10000) return `${(n / 10000).toFixed(1)}万字`
  if (n >= 1000) return `${(n / 1000).toFixed(1)}k字`
  return `${n}字`
}

function handleFileUpload(file: File) {
  const MAX_SIZE = 20 * 1024 * 1024 // 20MB
  if (file.size > MAX_SIZE) {
    message.error(`文件 ${file.name} 超过 20MB 限制`)
    return false
  }
  if (!store.recordId) {
    message.warning('请先生成计划后再上传文件')
    return false
  }
  doUploadFile(file)
  return false // prevent default upload
}

async function doUploadFile(file: File) {
  const tempId = `tmp_${Date.now()}`
  uploadedMaterials.value.push({
    fileId: tempId,
    originalFilename: file.name,
    fileType: '',
    charCount: 0,
    status: 'uploading',
  })

  // Always update through the reactive array by index — mutating the captured
  // plain-object reference bypasses Vue's Proxy and won't trigger re-render.
  const getIdx = () => uploadedMaterials.value.findIndex((m) => m.fileId === tempId)

  try {
    const { uploadMaterial } = await import('@/api/researchRecords')
    const result = await uploadMaterial(store.recordId!, file)
    const idx = getIdx()
    if (idx !== -1) {
      uploadedMaterials.value[idx] = {
        fileId: result.fileId,
        originalFilename: result.originalFilename,
        fileType: result.fileType,
        charCount: result.charCount,
        status: 'done',
      }
    }
    // Push file attachment into conversation timeline, then remove from uploads bar
    clarifyMessages.value.push({
      role: 'user',
      content: '',
      fileAttachment: {
        fileId: result.fileId,
        fileName: result.originalFilename,
        fileType: result.fileType,
        charCount: result.charCount,
      },
    })
    uploadedMaterials.value = uploadedMaterials.value.filter((m) => m.fileId !== result.fileId)
    // Also show in sidebar uploaded files list
    sidebarUploadedFiles.value.push({
      fileId: result.fileId,
      fileName: result.originalFilename,
      fileType: result.fileType,
      charCount: result.charCount,
      status: 'done',
    })
    scrollToClarifyBottom()
    message.success(`已提取 ${file.name} 的文本内容（${formatCharCount(result.charCount)}）`)
  } catch (err: any) {
    const idx = getIdx()
    if (idx !== -1) {
      uploadedMaterials.value[idx] = {
        ...uploadedMaterials.value[idx],
        status: 'error',
        errorMsg: err?.response?.data?.detail || err.message || '上传失败',
      }
    }
    message.error(`文件 ${file.name} 处理失败`)
  }
}

function removeUploadedMaterial(fileId: string) {
  uploadedMaterials.value = uploadedMaterials.value.filter((m) => m.fileId !== fileId)
}

// Sidebar uploaded files — shows all uploaded files (from clarify dialog + basket)
interface SidebarUploadedFile {
  fileId: string
  fileName: string
  fileType: string
  charCount: number
  status: 'uploading' | 'done' | 'error'
  errorMsg?: string
}
const sidebarUploadedFiles = ref<SidebarUploadedFile[]>([])

function handleBasketFileUpload(file: File) {
  const MAX_SIZE = 20 * 1024 * 1024
  if (file.size > MAX_SIZE) {
    message.error(`文件 ${file.name} 超过 20MB 限制`)
    return false
  }
  if (!store.recordId) {
    message.warning('请先生成计划后再上传文件')
    return false
  }
  doBasketUpload(file)
  return false
}

async function doBasketUpload(file: File) {
  const tempId = `tmp_basket_${Date.now()}`
  sidebarUploadedFiles.value.push({
    fileId: tempId,
    fileName: file.name,
    fileType: '',
    charCount: 0,
    status: 'uploading',
  })

  const getIdx = () => sidebarUploadedFiles.value.findIndex((m) => m.fileId === tempId)

  try {
    const { uploadMaterial } = await import('@/api/researchRecords')
    const result = await uploadMaterial(store.recordId!, file)
    const idx = getIdx()
    if (idx !== -1) {
      sidebarUploadedFiles.value[idx] = {
        fileId: result.fileId,
        fileName: result.originalFilename,
        fileType: result.fileType,
        charCount: result.charCount,
        status: 'done',
      }
    }
    message.success(`已提取 ${file.name} 的文本内容（${formatCharCount(result.charCount)}）`)
  } catch (err: any) {
    const idx = getIdx()
    if (idx !== -1) {
      sidebarUploadedFiles.value[idx] = {
        ...sidebarUploadedFiles.value[idx],
        status: 'error',
        errorMsg: err?.response?.data?.detail || err.message || '上传失败',
      }
    }
    message.error(`文件 ${file.name} 处理失败`)
  }
}

function assessmentColor(val: string) {
  if (val === 'sufficient') return 'green'
  if (val === 'partial') return 'gold'
  return 'red'
}
function assessmentLabel(val: string) {
  if (val === 'sufficient') return '充分'
  if (val === 'partial') return '部分'
  return '不足'
}
function blockerColor(val: string) {
  if (val === 'none') return 'green'
  if (val === 'minor') return 'gold'
  return 'red'
}
function blockerLabel(val: string) {
  if (val === 'none') return '无'
  if (val === 'minor') return '轻微'
  return '严重'
}

const previewItems = computed(() => importedItems.value.slice(0, 4))
const currentTemplateLabel = computed(() => RESEARCH_TEMPLATE_OPTIONS.find((item) => item.value === task.outputTemplate)?.label || '综合研究报告')
const currentDepthLabel = computed(() => RESEARCH_DEPTH_OPTIONS.find((item) => item.value === task.depthLevel)?.label || '深入')

const presetTasks: PresetTask[] = [
  {
    label: '政策链条梳理',
    description: '适合追踪上位依据、配套通知和执行延伸。',
    topic: '政策链条梳理',
    question: '梳理近一年围绕某项重点工作的政策链条、执行要求与配套文件。',
    goal: '形成可用于汇报的政策依据链和执行重点。',
    outputTemplate: 'policy_brief',
    depthLevel: 'deep',
  },
  {
    label: '执行研判',
    description: '适合识别执行口径、关键步骤和风险点。',
    topic: '执行研判',
    question: '围绕当前专题识别执行要求、落地链条和风险缺口。',
    goal: '提炼当前执行重点、堵点和建议动作。',
    outputTemplate: 'implementation',
    depthLevel: 'deep',
  },
  {
    label: '阶段演进',
    description: '适合按时间线看政策演化和重点变化。',
    topic: '阶段演进',
    question: '梳理 2024 年以来相关政策文件的阶段演进和重点变化。',
    goal: '形成时间线和阶段性判断。',
    outputTemplate: 'timeline',
    depthLevel: 'standard',
  },
]

function applyPreset(preset: PresetTask) {
  task.topic = preset.topic
  task.question = preset.question
  task.goal = preset.goal
  task.outputTemplate = preset.outputTemplate
  task.depthLevel = preset.depthLevel
}

function materialKey(item: BasketItem) {
  return getBasketItemKey(item)
}

onMounted(async () => {
  store.reset()

  // F3: Regenerate mode — prefill from existing record
  const fromId = route.query.from as string | undefined
  if (fromId) {
    try {
      const { fetchRecordDetail } = await import('@/api/researchRecords')
      const detail = await fetchRecordDetail(fromId)
      if (detail?.task) {
        isRegenerate.value = true
        regenerateFromId.value = fromId
        // Prefill task from original record
        Object.assign(task, detail.task)
      }
    } catch {
      message.warning('无法加载原始记录')
    }
  }

  const continueRaw = sessionStorage.getItem('research-continue-from-section')
  if (continueRaw) {
    try {
      const payload = JSON.parse(continueRaw)
      continueFromSectionTitle.value = payload.topic || ''
      task.topic = payload.topic || task.topic
      task.question = payload.question || task.question
      task.requiredDocIds = Array.isArray(payload.sourceDocIds) ? payload.sourceDocIds : []
    } catch {
      // ignore
    }
    sessionStorage.removeItem('research-continue-from-section')
  }

  const raw = sessionStorage.getItem('research-import-items')
  if (raw) {
    try {
      const items = JSON.parse(raw)
      if (Array.isArray(items) && items.length > 0) {
        importedItems.value = items
        const firstTitle = items[0]?.title || items[0]?.doc_id || ''
        if (firstTitle && !task.topic) {
          task.topic = firstTitle
          task.question = `关于"${firstTitle}"的研究分析`
        }
      }
      sessionStorage.setItem('research-import-items-parsed', raw)
    } catch { /* ignore */ }
    sessionStorage.removeItem('research-import-items')
  }

  if (basketStore.count > 0 && importedItems.value.length === 0) {
    importedItems.value = [...basketStore.items]
  }
})

async function handleGeneratePlan() {
  if (!task.topic || !task.question) {
    message.warning('请填写研究主题和核心问题')
    return
  }

  if (!store.recordId) {
    try {
      if (isRegenerate.value && regenerateFromId.value) {
        // F3: Create new version via regenerate API
        const { regenerateRecord } = await import('@/api/researchRecords')
        const snakeTask = {
          mode: task.mode,
          topic: task.topic,
          question: task.question,
          goal: task.goal || undefined,
          time_range: task.timeRange || undefined,
          region_scope: task.regionScope || undefined,
          org_scope: task.orgScope || undefined,
          output_template: task.outputTemplate,
          depth_level: task.depthLevel,
          required_doc_ids: task.requiredDocIds || [],
          required_matter_ids: task.requiredMatterIds || [],
          enable_kb_search: enableKbSearch.value,
        }
        const result = await regenerateRecord(regenerateFromId.value, snakeTask)
        store.recordId = result.id
        message.success(`已创建新版本 v${result.versionNo}`)
      } else {
        // Normal create
        const importedRaw = sessionStorage.getItem('research-import-items-parsed')
        let finalItems = importedRaw ? JSON.parse(importedRaw) : undefined
        if (!finalItems && importedItems.value.length > 0) {
          finalItems = importedItems.value
        }
        await store.createNewRecord({
          title: task.topic,
          task: { ...task, enable_kb_search: enableKbSearch.value },
          importedItems: finalItems,
        })
        sessionStorage.removeItem('research-import-items-parsed')
      }
    } catch (err: any) {
      message.error(err.message || '创建记录失败')
      return
    }
  }

  // F1: Run clarification first (skip if already clarified or regenerate mode)
  if (!plan.value && !isRegenerate.value && clarifyMessages.value.length === 0) {
    await runClarify([])
    // If clarify returned questions (not ready), stop here — user must answer
    if (clarifyWaiting.value) return
  }

  const result = await store.generatePlan()
  if (result) {
    plan.value = result
  }
}

function handleStartResearch() {
  console.log('[handleStartResearch] called, recordId=', store.recordId)
  if (!store.recordId) {
    message.error('记录 ID 缺失，无法开始研究')
    return
  }
  router.push(`/research/${store.recordId}?autoRun=true`)
}

// F1: Clarification flow
async function runClarify(userMessages: { role: string; content: string }[]) {
  if (!store.recordId) return
  clarifyLoading.value = true
  scrollToClarifyBottom()
  try {
    const { buildClarifyUrl } = await import('@/api/researchRecords')
    const url = buildClarifyUrl(store.recordId)
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${localStorage.getItem('token') || ''}`,
      },
      body: JSON.stringify({ messages: userMessages, enable_kb_search: enableKbSearch.value }),
    })
    if (!response.ok) throw new Error('Clarify request failed')
    const reader = response.body?.getReader()
    if (!reader) return
    const decoder = new TextDecoder()
    let buffer = ''
    const questions: string[] = []
    let note = ''
    let ready = false

    while (true) {
      const { done, value } = await reader.read()
      if (done) break
      buffer += decoder.decode(value, { stream: true })
      const lines = buffer.split('\n')
      buffer = lines.pop() || ''
      for (const line of lines) {
        if (!line.startsWith('data: ')) continue
        try {
          const chunk = JSON.parse(line.slice(6))
          if (chunk.type === 'clarification_question') {
            questions.push(chunk.content)
          } else if (chunk.type === 'clarification_note') {
            note = chunk.content
          } else if (chunk.type === 'ready_signal') {
            ready = true
          } else if (chunk.type === 'assessment') {
            try {
              clarifyAssessment.value = JSON.parse(chunk.content)
            } catch { /* ignore */ }
          } else if (chunk.type === 'task_patch') {
            try {
              const patch = JSON.parse(chunk.content)
              if (patch.topic) task.topic = patch.topic
              if (patch.question) task.question = patch.question
              if (patch.goal) task.goal = patch.goal
            } catch { /* ignore parse error */ }
          }
        } catch { /* ignore parse error */ }
      }
    }

    if (ready) {
      clarifyMessages.value.push({ role: 'assistant', content: '任务信息充分，可以生成研究计划。', note })
      clarifyWaiting.value = false
      scrollToClarifyBottom()
      // Don't auto-generate here — let the caller (handleGeneratePlan or submitClarifyAnswer) proceed
    } else if (questions.length > 0) {
      clarifyMessages.value.push({ role: 'assistant', content: '', questions, note })
      clarifyWaiting.value = true
      scrollToClarifyBottom()
    }
  } catch (err: any) {
    message.error('澄清请求失败')
  } finally {
    clarifyLoading.value = false
  }
}

async function submitClarifyAnswer() {
  const text = clarifyInput.value.trim()
  if (!text) return
  clarifyMessages.value.push({ role: 'user', content: text })
  clarifyInput.value = ''
  clarifyWaiting.value = false
  scrollToClarifyBottom()
  await runClarify([{ role: 'user', content: text }])
  // If clarify returned ready (not waiting), auto-generate plan
  if (!clarifyWaiting.value && store.recordId) {
    const result = await store.generatePlan()
    if (result) plan.value = result
  }
}
</script>

<style scoped lang="less">
.research-create-page {
  max-width: 1200px;
  margin: 0 auto;
  padding: 24px;
}

.create-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 280px;
  gap: 20px;
  align-items: start;
}

.create-main {
  min-width: 0;
}

.create-sidebar {
  position: sticky;
  top: 24px;
}

.basket-panel {
  background: #fff;
  border: 1px solid #f0f0f0;
  border-radius: 12px;
  padding: 16px;

  &__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
  }

  &__title {
    font-size: 14px;
    font-weight: 600;
  }

  &__list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-height: 420px;
    overflow-y: auto;
  }

  &__more {
    margin-top: 8px;
    font-size: 12px;
    color: rgba(0, 0, 0, 0.45);
    text-align: center;
  }

  &__footer {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid #f5f5f5;
  }

  &__actions {
    display: flex;
    gap: 8px;

    > .ant-btn {
      flex: 1;
    }
  }

  &__clear {
    display: block;
    margin: 6px auto 0;
    font-size: 12px;
  }

  &__uploads {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px dashed #e8e8e8;
  }

  &__uploads-title {
    font-size: 12px;
    font-weight: 600;
    color: rgba(0, 0, 0, 0.65);
    margin-bottom: 8px;
  }
}

.basket-upload-item {
  padding: 8px 10px;
  background: #f6f8fa;
  border-radius: 6px;
  margin-bottom: 6px;
  border: 1px solid #f0f0f0;

  &__row {
    display: flex;
    align-items: center;
    gap: 6px;
  }

  &__icon {
    color: rgba(0, 0, 0, 0.35);
    font-size: 13px;
    flex-shrink: 0;
  }

  &__name {
    font-size: 13px;
    color: rgba(0, 0, 0, 0.85);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 180px;

    a& {
      color: #1677ff;
      cursor: pointer;
      &:hover {
        text-decoration: underline;
      }
    }
  }

  &__meta {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 4px;
    font-size: 12px;
    color: rgba(0, 0, 0, 0.45);
  }
}

.basket-item {
  padding: 10px 12px;
  background: #fafafa;
  border-radius: 8px;
  border: 1px solid #f0f0f0;

  &__title {
    font-size: 13px;
    font-weight: 500;
    color: rgba(0, 0, 0, 0.85);
    line-height: 1.4;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  &__meta {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 6px;
    font-size: 12px;
    color: rgba(0, 0, 0, 0.45);
  }
}

.material-panel {
  margin-bottom: 18px;
  padding: 18px;
  background: #fff;
  border: 1px solid #f0f0f0;
  border-radius: 12px;
}

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

.panel-head__title {
  font-size: 15px;
  font-weight: 600;
}

.panel-head__desc {
  margin-top: 4px;
  font-size: 12px;
  color: rgba(0, 0, 0, 0.45);
}

.material-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin-top: 14px;
}

.material-card {
  padding: 12px;
  border-radius: 8px;
  background: #fafafa;
  border: 1px solid #f0f0f0;

  &__top {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    align-items: center;
  }

  &__source {
    font-size: 12px;
    color: rgba(0, 0, 0, 0.45);
  }

  &__title {
    margin-top: 8px;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.4;
  }

  &__meta {
    margin-top: 6px;
    font-size: 12px;
    line-height: 1.6;
    color: rgba(0, 0, 0, 0.45);
  }
}

.material-panel__more {
  margin-top: 10px;
  font-size: 12px;
  color: rgba(0, 0, 0, 0.45);
}

@media (max-width: 900px) {
  .create-layout {
    grid-template-columns: 1fr;
  }

  .material-grid {
    grid-template-columns: 1fr;
  }
}

// F1: Clarification styles
.clarify-messages {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.clarify-msg {
  display: flex;

  &--user {
    justify-content: flex-end;
  }
  &--assistant {
    justify-content: flex-start;
  }
}

.clarify-msg__bubble {
  max-width: 80%;
  padding: 10px 14px;
  border-radius: 12px;
  font-size: 13px;
  line-height: 1.6;

  .clarify-msg--user & {
    background: #e6f4ff;
    color: rgba(0, 0, 0, 0.88);
  }
  .clarify-msg--assistant & {
    background: #f5f5f5;
    color: rgba(0, 0, 0, 0.88);
  }
}

.clarify-msg__questions {
  font-weight: 500;
}

.clarify-msg__bubble--file {
  background: #f0f7ff !important;
  border: 1px solid #bae0ff;
  padding: 8px 12px;
}

.clarify-msg__file {
  display: flex;
  align-items: center;
  gap: 7px;

  &-icon {
    font-size: 15px;
    color: #1677ff;
    flex-shrink: 0;
  }

  &-name {
    font-size: 13px;
    font-weight: 500;
    color: rgba(0, 0, 0, 0.85);
    word-break: break-all;
  }

  &-meta {
    font-size: 11px;
    color: rgba(0, 0, 0, 0.35);
    flex-shrink: 0;
  }
}

.clarify-thinking {
  display: flex;
  align-items: center;
  gap: 4px;

  &__dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.25);
    animation: clarify-bounce 1.4s ease-in-out infinite;

    &:nth-child(2) {
      animation-delay: 0.2s;
    }
    &:nth-child(3) {
      animation-delay: 0.4s;
    }
  }

  &__label {
    margin-left: 6px;
    font-size: 12px;
    color: rgba(0, 0, 0, 0.35);
  }
}

@keyframes clarify-bounce {
  0%, 80%, 100% {
    transform: scale(0.6);
    opacity: 0.4;
  }
  40% {
    transform: scale(1);
    opacity: 1;
  }
}

.clarify-uploads {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 8px;
}

.clarify-input-wrap {
  display: flex;
  gap: 8px;
  align-items: flex-end;

  :deep(.ant-input) {
    resize: none;
  }

  .clarify-upload-btn {
    flex-shrink: 0;
    height: 32px;
    width: 32px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .clarify-send-btn {
    flex-shrink: 0;
    height: 32px;
  }
}

.kb-toggle {
  margin-top: 12px;
  padding: 12px 14px;
  background: #fafafa;
  border-radius: 10px;
  border: 1px solid #f0f0f0;

  &__row {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  &__label {
    font-size: 13px;
    color: rgba(0, 0, 0, 0.65);
    font-weight: 500;
  }

  &__hint {
    margin-top: 6px;
    font-size: 12px;
    color: rgba(0, 0, 0, 0.35);
  }
}

.assessment-bar {
  padding: 12px 16px;
  background: #fafafa;
  border-radius: 10px;
  border: 1px solid #f0f0f0;

  &__title {
    font-size: 12px;
    font-weight: 600;
    color: rgba(0, 0, 0, 0.45);
    margin-bottom: 8px;
  }

  &__items {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
  }
}
</style>
