/**
 * 研究记录工作台 Store
 * 管理单条记录详情、计划、报告、SSE 流式累积态。
 * Store 不持有 SSE 连接，只暴露 handleSSEEvent。
 */
import { ref } from 'vue'
import { defineStore } from 'pinia'
import { message } from 'ant-design-vue'
import {
  fetchRecordDetail,
  fetchRecordReport,
  createRecord,
  generateRecordPlan,
} from '@/api/researchRecords'
import { normalizeResearchPlan } from '@/api/research'
import type {
  ResearchRecordDetail,
  ResearchPlan,
  ResearchReport,
  ResearchProgressItem,
  ResearchFinding,
  ResearchConflict,
  ResearchOpenQuestion,
  ResearchSectionResult,
  ResearchTaskDraft,
} from '@/types/research'
import type { ResearchReference } from '@/types/document'
import { createEmptyResearchReport } from '@/types/research'

export const useResearchRecordWorkbenchStore = defineStore('researchRecordWorkbench', () => {
  // Record identity
  const recordId = ref<string | null>(null)
  const record = ref<ResearchRecordDetail | null>(null)

  // Planning state
  const isCreating = ref(false)
  const isPlanning = ref(false)
  const isRunning = ref(false)

  // SSE streaming state (accumulated from chunks)
  const progress = ref<ResearchProgressItem[]>([])
  const report = ref<ResearchReport>(createEmptyResearchReport())
  const references = ref<ResearchReference[]>([])
  // Passage-level citation map: index N-1 → {doc_id, chunk metadata}
  const citationMap = ref<Record<string, unknown>[]>([])

  // ------------------------------------------------------------------
  // Record & report loading
  // ------------------------------------------------------------------

  async function loadRecord(id: string) {
    recordId.value = id
    record.value = await fetchRecordDetail(id)
  }

  async function loadReport(id: string) {
    try {
      const res = await fetchRecordReport(id)
      if (res.report) {
        const r = res.report as Record<string, unknown>
        report.value = {
          executiveSummary: (r.executive_summary as string) || '',
          findings: ((r.findings as ResearchFinding[]) || []),
          conflicts: ((r.conflicts as ResearchConflict[]) || []),
          openQuestions: ((r.open_questions as ResearchOpenQuestion[]) || []),
          sections: ((r.sections as ResearchSectionResult[]) || []),
          onePageSummary: (r.one_page_summary as string) || '',
          recommendedNextSteps: ((r.recommended_next_steps as string[]) || []),
          finalDocumentMd: res.finalDocumentMd || '',
        }
        // Load passage-level citation map for chunk-precise previews
        citationMap.value = Array.isArray(r.citation_map) ? (r.citation_map as Record<string, unknown>[]) : []
      }
    } catch {
      // P1-5: report may not exist yet (404) — keep empty report, don't crash
      report.value = createEmptyResearchReport()
    }
    // Also populate references from record if available
    if (record.value?.references) {
      references.value = record.value.references
    }
  }

  // ------------------------------------------------------------------
  // Record creation & plan generation
  // ------------------------------------------------------------------

  async function createNewRecord(params: {
    title: string
    task: ResearchTaskDraft
    importedItems?: any[]
  }): Promise<string> {
    isCreating.value = true
    try {
      const id = await createRecord({
        title: params.title,
        mode: params.task.mode,
        outputTemplate: params.task.outputTemplate,
        task: params.task,
        importedItems: params.importedItems,
      })
      recordId.value = id
      return id
    } finally {
      isCreating.value = false
    }
  }

  async function generatePlan(): Promise<ResearchPlan | null> {
    if (!recordId.value) return null
    isPlanning.value = true
    try {
      const plan = await generateRecordPlan(recordId.value)
      // Reload record to get updated status
      await loadRecord(recordId.value)
      return plan
    } catch (err: any) {
      message.error(err?.response?.data?.detail || '计划生成失败')
      return null
    } finally {
      isPlanning.value = false
    }
  }

  // ------------------------------------------------------------------
  // SSE event handling  (extracted from ResearchView.vue:311-426)
  // ------------------------------------------------------------------

  function handleSSEEvent(data: Record<string, unknown>) {
    if (data.type === 'plan' && data.payload) {
      // Plan chunk — update record plan
      if (record.value) {
        record.value.plan = normalizeResearchPlan(data.payload as Record<string, unknown>)
      }
      return
    }
    if (data.type === 'progress') {
      progress.value.push({
        stage: (data.stage as string) || 'analysis',
        content: (data.content as string) || '',
        status: (data.status as 'running' | 'completed' | 'error') || 'running',
        timestamp: Date.now(),
      })
      return
    }
    if (data.type === 'source_group') {
      const payload = (data.payload || {}) as Record<string, unknown>
      const group = String(payload.group || '')
      if (group === 'guide') {
        progress.value.push({
          stage: 'guide',
          content: (data.content as string) || '已纳入办事指南结构化证据。',
          status: 'completed',
          timestamp: Date.now(),
        })
      }
      return
    }
    if (data.type === 'reference') {
      const payload = (data.payload || {}) as Record<string, unknown>
      const newRef: ResearchReference = {
        doc_id: data.doc_id as string,
        title: data.title as string,
        doc_number: data.doc_number as string,
        relevance_score: data.relevance_score as number,
        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 ResearchReference['matched_chunks']) : [],
      }
      // Dedup by key (same as getReferenceKey in stores/research.ts:71)
      const key = newRef.source_group === 'guide'
        ? `guide:${newRef.profile_id || newRef.doc_id}`
        : `doc:${newRef.doc_id}`
      const idx = references.value.findIndex((r) => {
        const rKey = r.source_group === 'guide'
          ? `guide:${r.profile_id || r.doc_id}`
          : `doc:${r.doc_id}`
        return rKey === key
      })
      if (idx >= 0) {
        references.value[idx] = newRef
      } else {
        references.value.push(newRef)
      }
      return
    }
    if (data.type === 'summary') {
      report.value.executiveSummary = (data.content as string) || ''
      return
    }
    if (data.type === 'finding') {
      const payload = (data.payload || {}) as Record<string, unknown>
      report.value.findings.push({
        title: (data.title as string) || '关键发现',
        content: (data.content as string) || '',
        strength: (data.strength as 'high' | 'medium' | 'low') || 'medium',
        sourceDocIds: Array.isArray(payload.source_doc_ids) ? payload.source_doc_ids as string[] : [],
      })
      return
    }
    if (data.type === 'conflict') {
      const payload = (data.payload || {}) as Record<string, unknown>
      report.value.conflicts.push({
        title: (data.title as string) || '冲突或缺口',
        content: (data.content as string) || '',
        severity: (data.severity as 'high' | 'medium' | 'low') || 'medium',
        sourceDocIds: Array.isArray(payload.source_doc_ids) ? payload.source_doc_ids as string[] : [],
      })
      return
    }
    if (data.type === 'open_question') {
      report.value.openQuestions.push({
        question: (data.title as string) || '待确认问题',
        reason: (data.content as string) || '',
      })
      return
    }
    if (data.type === 'section') {
      const payload = (data.payload || {}) as Record<string, unknown>
      const newSection: ResearchSectionResult = {
        title: (data.title as string) || '研究章节',
        summary: (payload.summary as string) || '',
        content: (data.content as string) || '',
        sourceDocIds: Array.isArray(payload.source_doc_ids) ? payload.source_doc_ids as string[] : [],
      }
      const existingIdx = report.value.sections.findIndex((s) => s.title === newSection.title)
      if (existingIdx >= 0) {
        report.value.sections[existingIdx] = newSection
      } else {
        report.value.sections.push(newSection)
      }
      return
    }
    if (data.type === 'report') {
      report.value.onePageSummary = (data.content as string) || ''
      return
    }
    if (data.type === 'follow_up') {
      const payload = (data.payload || {}) as Record<string, unknown>
      if (payload.kind === 'section_rerun_notes') {
        const notes = Array.isArray(payload.items)
          ? (payload.items as unknown[]).map((item: unknown) => String(item).trim()).filter(Boolean)
          : String((data.content as string) || '')
            .split('\n')
            .map((item) => item.trim())
            .filter(Boolean)
        if (notes.length) {
          progress.value.push({
            stage: 'analysis',
            content: `章节补充重点：${notes.join('；')}`,
            status: 'completed',
            timestamp: Date.now(),
          })
        }
        return
      }
      report.value.recommendedNextSteps = Array.isArray(payload.items)
        ? payload.items as string[]
        : String((data.content as string) || '')
          .split('\n')
          .map((item) => item.trim())
          .filter(Boolean)
      return
    }
    if (data.type === 'final_document') {
      report.value.finalDocumentMd = (data.content as string) || ''
      return
    }
    if (data.type === 'error') {
      message.error((data.content as string) || '研究执行失败')
    }
  }

  // ------------------------------------------------------------------
  // Stream state management (C18)
  // ------------------------------------------------------------------

  /**
   * Reset SSE accumulated state before re-subscribing.
   * @param clearReport true for full-run re-subscribe, false for section_rerun
   */
  function resetStreamState(clearReport = true) {
    progress.value = []
    references.value = []
    if (clearReport) {
      report.value = createEmptyResearchReport()
      citationMap.value = []
    }
  }

  /** Full reset */
  function reset() {
    recordId.value = null
    record.value = null
    isCreating.value = false
    isPlanning.value = false
    isRunning.value = false
    progress.value = []
    report.value = createEmptyResearchReport()
    references.value = []
    citationMap.value = []
  }

  return {
    // State
    recordId,
    record,
    isCreating,
    isPlanning,
    isRunning,
    progress,
    report,
    references,
    citationMap,
    // Actions
    loadRecord,
    loadReport,
    createNewRecord,
    generatePlan,
    handleSSEEvent,
    resetStreamState,
    reset,
  }
})
