<template>
  <div class="flex-1 flex flex-col bg-slate-900 h-full overflow-hidden">
    <!-- 头部 -->
    <header class="p-3 border-b border-slate-700 bg-slate-800 flex items-center justify-between shrink-0">
      <div class="flex items-center gap-3">
        <h1 class="font-bold text-white flex items-center gap-2">
          <IconLibrary name="sparkles" :size="20" class="text-purple-400" />
          <span>范式润色</span>
        </h1>
        <span class="text-xs text-slate-500">基于范式规则检查并重写文章句子</span>
      </div>
    </header>

    <!-- 范式选择条 -->
    <div class="px-4 py-2 bg-indigo-900/30 border-b border-indigo-700/50 flex items-center justify-between shrink-0">
      <div class="flex items-center gap-3">
        <IconLibrary name="folder" :size="16" class="text-indigo-400" />
        <span class="text-indigo-400 text-sm">当前范式：</span>
        <span v-if="selectedParadigm" class="text-white text-sm font-medium flex items-center gap-1">
          {{ selectedParadigm.icon }} {{ selectedParadigm.name }}
        </span>
        <span v-else class="text-slate-400 text-sm">未选择</span>
      </div>
      <button 
        @click="showParadigmSelector = true"
        class="text-xs px-3 py-1 rounded bg-indigo-600 text-white hover:bg-indigo-500 transition"
      >
        {{ selectedParadigm ? '切换范式' : '选择范式' }}
      </button>
    </div>

    <!-- 主体内容区：三栏布局 -->
    <div class="flex-1 flex overflow-hidden">
      <!-- 左侧：原文区 -->
      <div class="w-[35%] flex flex-col border-r border-slate-700 min-w-0">
        <div class="p-3 bg-slate-800 border-b border-slate-700 flex items-center justify-between">
          <h2 class="text-sm font-medium text-amber-400 flex items-center gap-2">
            <IconLibrary name="document" :size="16" />
            <span>原文区</span>
          </h2>
          <div class="flex items-center gap-2">
            <span class="text-xs text-slate-500">{{ sentences.length }} 句</span>
            <span v-if="selectedSentenceIdxs.length > 0" class="text-xs text-amber-400">
              已选 {{ selectedSentenceIdxs.length }} 句
            </span>
            <!-- 全选/反选按钮 -->
            <div v-if="sentences.length > 0" class="flex gap-1 ml-2">
              <button
                @click="selectAllOriginal"
                class="text-xs px-2 py-0.5 rounded bg-amber-700/50 text-amber-200 hover:bg-amber-600/50 transition"
              >全选</button>
              <button
                @click="invertOriginalSelection"
                class="text-xs px-2 py-0.5 rounded bg-slate-700 text-slate-300 hover:bg-slate-600 transition"
              >反选</button>
            </div>
            <!-- 保存按钮 -->
            <button
              v-if="articleSourceType === 'document' && sourceDocId && hasContentChanged"
              @click="saveToDocument"
              :disabled="isSaving"
              class="text-xs px-2 py-0.5 rounded bg-green-600 text-white hover:bg-green-500 transition flex items-center gap-1 disabled:opacity-50"
            >
              <IconLibrary v-if="isSaving" name="loading" :size="12" class="animate-spin" />
              <IconLibrary v-else name="save" :size="12" />
              <span>{{ isSaving ? '保存中...' : '保存' }}</span>
            </button>
          </div>
        </div>
        <!-- 来源选择器 -->
        <div class="px-3 py-2 bg-slate-800/50 border-b border-slate-700 flex items-center gap-2">
          <span class="text-xs text-slate-500">来源：</span>
          <div class="flex bg-slate-900 rounded p-0.5 border border-slate-700">
            <button
              @click="articleSourceType = 'paste'"
              :class="['text-xs px-2 py-0.5 rounded transition',
                articleSourceType === 'paste' ? 'bg-amber-600 text-white' : 'text-slate-400 hover:text-white']"
            >粘贴</button>
            <button
              @click="showDocSelector = true"
              :class="['text-xs px-2 py-0.5 rounded transition',
                articleSourceType === 'document' ? 'bg-amber-600 text-white' : 'text-slate-400 hover:text-white']"
            >文稿库</button>
          </div>
          <span v-if="articleSourceType === 'document' && sourceDocTitle" class="text-xs text-amber-400 ml-2 flex items-center gap-1">
            <IconLibrary name="document" :size="12" />
            <span>{{ sourceDocTitle }}</span>
          </span>
        </div>
        <!-- 连续文本流 -->
        <div class="flex-1 overflow-y-auto p-4 min-h-0">
          <div v-if="sentences.length === 0" class="h-full flex items-center justify-center">
            <div class="text-center">
              <div class="w-16 h-16 flex items-center justify-center rounded-xl bg-slate-800/50 border border-slate-700 mx-auto mb-2 opacity-40">
                <IconLibrary name="edit" :size="32" />
              </div>
              <p class="text-slate-600 text-sm">请在下方输入或粘贴文章内容</p>
            </div>
          </div>
          <!-- 连续文本展示，句子用 inline span -->
          <div v-else class="bg-slate-800/30 rounded-lg p-4 border border-slate-700 leading-relaxed">
            <template v-for="(sentence, idx) in sentences" :key="'s-' + idx">
              <span
                @click="toggleSentence(idx)"
                :class="[
                  'cursor-pointer transition-all rounded px-0.5 py-0.5 hover:bg-amber-900/30',
                  selectedSentenceIdxs.includes(idx) 
                    ? 'bg-amber-500/40 text-amber-100 ring-1 ring-amber-400' 
                    : 'text-slate-300 hover:text-amber-200'
                ]"
              >{{ sentence.text }}</span>
            </template>
          </div>
          <!-- 提示文字 -->
          <p v-if="sentences.length > 0" class="text-xs text-slate-500 mt-3 text-center flex items-center justify-center gap-1">
            <IconLibrary name="info" :size="12" />
            <span>点击句子可选中/取消，选中的句子将被检查</span>
          </p>
        </div>
        <!-- 输入框 -->
        <div class="p-3 border-t border-slate-700 bg-slate-800">
          <textarea 
            v-model="articleContent"
            class="w-full h-24 bg-slate-900 border border-slate-700 rounded-lg p-3 text-sm focus:ring-2 focus:ring-amber-500 focus:border-transparent outline-none resize-none"
            placeholder="粘贴或输入文章内容..."
            @input="splitToSentences"
          ></textarea>
        </div>
      </div>

      <!-- 中间：检查结果 -->
      <div class="w-[30%] flex flex-col border-r border-slate-700 min-w-0">
        <div class="p-3 bg-slate-800 border-b border-slate-700">
          <h2 class="text-sm font-medium text-blue-400 flex items-center gap-2">
            <IconLibrary name="search" :size="16" />
            <span>检查结果</span>
          </h2>
        </div>
        <div class="flex-1 overflow-y-auto p-4 space-y-3 min-h-0">
          <div v-if="!isChecking && checkResults.length === 0" class="h-full flex items-center justify-center">
            <div class="text-center">
              <div class="w-16 h-16 flex items-center justify-center rounded-xl bg-slate-800/50 border border-slate-700 mx-auto mb-2 opacity-40">
                <IconLibrary name="clipboard" :size="32" />
              </div>
              <p class="text-slate-600 text-sm">选中句子后点击「范式检查」</p>
            </div>
          </div>
          <!-- 检查中状态 -->
          <div v-if="isChecking" class="flex flex-col gap-2 text-blue-300">
            <div class="flex items-center gap-2">
              <IconLibrary name="loading" :size="14" class="animate-spin" />
              <span class="text-sm">AI 正在检查中...</span>
            </div>
            <div v-if="checkProgress" class="text-xs text-slate-400 pl-6">
              {{ checkProgress }}
            </div>
          </div>
          <!-- 检查结果列表 -->
          <div 
            v-for="(result, idx) in checkResults" 
            :key="'check-' + idx"
            :class="[
              'p-3 rounded-lg border',
              result.status === 'pass' ? 'bg-green-900/20 border-green-700/50' :
              result.status === 'warning' ? 'bg-yellow-900/20 border-yellow-700/50' :
              'bg-red-900/20 border-red-700/50'
            ]"
          >
            <div class="flex items-start gap-2">
              <span class="text-lg">
                <IconLibrary v-if="result.status === 'pass'" name="check" :size="16" class="text-green-400" />
                <IconLibrary v-else-if="result.status === 'warning'" name="warning" :size="16" class="text-yellow-400" />
                <IconLibrary v-else name="error" :size="16" class="text-red-400" />
              </span>
              <div class="flex-1 min-w-0">
                <p class="text-xs text-slate-400 mb-1">句子 {{ result.sentenceIdx + 1 }}</p>
                <p class="text-sm text-slate-200">{{ result.message }}</p>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 右侧：重写预览 -->
      <div class="flex-1 flex flex-col min-w-0">
        <div class="p-3 bg-slate-800 border-b border-slate-700 flex items-center justify-between">
          <h2 class="text-sm font-medium text-emerald-400 flex items-center gap-2">
            <IconLibrary name="sparkles" :size="16" />
            <span>重写预览</span>
          </h2>
          <div class="flex items-center gap-2">
            <span class="text-xs text-slate-500">{{ rewrittenSentences.length }} 句</span>
            <span v-if="selectedRewriteIdxs.length > 0" class="text-xs text-emerald-400">
              已选 {{ selectedRewriteIdxs.length }} 句
            </span>
            <!-- 全选/反选按钮 -->
            <div v-if="rewrittenSentences.length > 0" class="flex gap-1 ml-2">
              <button
                @click="selectAllRewrite"
                class="text-xs px-2 py-0.5 rounded bg-emerald-700/50 text-emerald-200 hover:bg-emerald-600/50 transition"
              >全选</button>
              <button
                @click="invertRewriteSelection"
                class="text-xs px-2 py-0.5 rounded bg-slate-700 text-slate-300 hover:bg-slate-600 transition"
              >反选</button>
              <!-- 复检按钮：对重写内容再次检查 -->
              <button
                @click="recheckRewrittenContent"
                :disabled="selectedRewriteIdxs.length === 0 || isChecking"
                class="text-xs px-2 py-0.5 rounded bg-purple-600 text-white hover:bg-purple-500 transition disabled:opacity-50 flex items-center gap-1"
                title="对选中的重写内容再次进行范式检查"
              >
                <IconLibrary name="refresh" :size="12" />
                <span>复检</span>
              </button>
            </div>
          </div>
        </div>
        <div class="flex-1 overflow-y-auto p-4 min-h-0">
          <div v-if="!isRewriting && rewrittenSentences.length === 0" class="h-full flex items-center justify-center">
            <div class="text-center">
              <div class="w-16 h-16 flex items-center justify-center rounded-xl bg-slate-800/50 border border-slate-700 mx-auto mb-2 opacity-40">
                <IconLibrary name="sparkles" :size="32" />
              </div>
              <p class="text-slate-600 text-sm">检查完成后点击「AI 重写」</p>
            </div>
          </div>
          <!-- 重写中状态 -->
          <div v-if="isRewriting" class="flex flex-col gap-2">
            <div class="flex items-center gap-2 text-emerald-300">
              <IconLibrary name="loading" :size="14" class="animate-spin" />
              <span class="text-sm">AI 正在重写中...</span>
            </div>
            <div v-if="rewriteProgress" class="text-xs text-slate-400 pl-6">
              {{ rewriteProgress }}
            </div>
            <div v-if="rewriteStreamContent" class="bg-slate-800/50 rounded-lg p-3 border border-slate-700">
              <p class="text-sm text-slate-200 whitespace-pre-wrap">{{ rewriteStreamContent }}</p>
            </div>
          </div>
          <!-- 连续文本展示，句子用 inline span -->
          <div v-else-if="rewrittenSentences.length > 0" class="bg-slate-800/30 rounded-lg p-4 border border-slate-700 leading-relaxed">
            <template v-for="(sentence, idx) in rewrittenSentences" :key="'rw-' + idx">
              <span
                @click="toggleRewriteSentence(idx)"
                :class="[
                  'cursor-pointer transition-all rounded px-0.5 py-0.5 hover:bg-emerald-900/30',
                  selectedRewriteIdxs.includes(idx) 
                    ? 'bg-emerald-500/40 text-emerald-100 ring-1 ring-emerald-400' 
                    : 'text-slate-200 hover:text-emerald-200'
                ]"
              >{{ sentence.text }}</span>
            </template>
          </div>
          <!-- 提示文字 -->
          <p v-if="rewrittenSentences.length > 0" class="text-xs text-slate-500 mt-3 text-center flex items-center justify-center gap-1">
            <IconLibrary name="info" :size="12" />
            <span>点击句子可选中/取消，选中的句子将替换原文</span>
          </p>
        </div>
      </div>
    </div>

    <!-- 底部操作区 -->
    <footer class="p-4 bg-slate-800 border-t border-slate-700 shrink-0">
      <div class="flex items-center justify-between gap-4">
        <!-- 左侧：状态提示 -->
        <div class="flex-1 text-sm text-slate-500">
          <span v-if="selectedSentenceIdxs.length === 0">请先在左侧选择要检查的句子</span>
          <span v-else-if="!selectedParadigm">请选择一个写作范式</span>
          <span v-else-if="checkResults.length === 0">准备就绪，点击「范式检查」开始</span>
          <span v-else-if="rewrittenSentences.length === 0">检查完成，可点击「AI 重写」</span>
          <span v-else>选择满意的重写句子，点击「应用替换」</span>
        </div>

        <!-- 右侧：操作按钮 -->
        <div class="flex gap-2 shrink-0">
          <button
            @click="clearSelection"
            class="px-4 py-2 rounded-lg text-sm bg-slate-700 text-slate-300 hover:bg-slate-600 transition"
          >
            清空选择
          </button>
          <button
            @click="runParadigmCheck"
            :disabled="!canCheck || isChecking"
            class="px-4 py-2 rounded-lg text-sm font-medium text-white transition disabled:opacity-50 disabled:cursor-not-allowed bg-blue-600 hover:bg-blue-500"
          >
            <span v-if="isChecking" class="flex items-center gap-2">
              <IconLibrary name="loading" :size="14" class="animate-spin" />
              <span>检查中...</span>
            </span>
            <span v-else class="flex items-center gap-2">
              <IconLibrary name="search" :size="16" />
              <span>范式检查</span>
            </span>
          </button>
          <button
            @click="runAIRewrite"
            :disabled="!canRewrite || isRewriting"
            class="px-4 py-2 rounded-lg text-sm font-medium text-white transition disabled:opacity-50 disabled:cursor-not-allowed bg-purple-600 hover:bg-purple-500"
          >
            <span v-if="isRewriting" class="flex items-center gap-2">
              <IconLibrary name="loading" :size="14" class="animate-spin" />
              <span>重写中...</span>
            </span>
            <span v-else class="flex items-center gap-2">
              <IconLibrary name="sparkles" :size="16" />
              <span>AI 重写</span>
            </span>
          </button>
          <button
            @click="applySelectedRewrites"
            :disabled="!canApply"
            class="px-4 py-2 rounded-lg text-sm font-medium text-white transition disabled:opacity-50 disabled:cursor-not-allowed bg-gradient-to-r from-amber-600 to-emerald-600 hover:from-amber-500 hover:to-emerald-500"
          >
            <IconLibrary name="refresh" :size="16" />
            <span>应用替换</span>
          </button>
        </div>
      </div>
    </footer>

    <!-- 范式选择弹窗 -->
    <ParadigmSelectorModal
      :visible="showParadigmSelector"
      @close="showParadigmSelector = false"
      @select="handleParadigmSelect"
      @create-custom="handleCreateCustomParadigm"
    />

    <!-- 文稿选择弹窗 -->
    <DocumentSelectorModal
      :visible="showDocSelector"
      @close="showDocSelector = false"
      @select="handleDocSelect"
    />

    <!-- 需求解析面板 -->
    <RequirementParserPanel
      v-if="showRequirementParser"
      @close="showRequirementParser = false"
      @paradigm-created="handleParadigmCreated"
    />
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { useAppStore } from '../stores/app'
import { useParadigmStore } from '../stores/paradigm'
import { splitIntoSentencesWithPosition, computeDiff } from '../utils/textDiff'
import { updateDocument, saveDocumentVersion } from '../db/index.js'
import ParadigmSelectorModal from './ParadigmSelectorModal.vue'
import DocumentSelectorModal from './DocumentSelectorModal.vue'
import RequirementParserPanel from './RequirementParserPanel.vue'
import IconLibrary from './icons/IconLibrary.vue'

const appStore = useAppStore()
const paradigmStore = useParadigmStore()

// ========== 数据状态 ==========
// 原文相关
const articleContent = ref('')
const articleSourceType = ref('paste')  // 'paste' | 'document'
const sourceDocId = ref(null)
const sourceDocTitle = ref('')
const sentences = ref([])  // 拆分后的句子 {text, start, end}
const selectedSentenceIdxs = ref([])

// 范式相关
const selectedParadigm = ref(null)
const showParadigmSelector = ref(false)
const showRequirementParser = ref(false)  // 需求解析面板

// 文稿选择
const showDocSelector = ref(false)

// 检查相关
const isChecking = ref(false)
const checkProgress = ref('')  // 批次进度信息
const checkResults = ref([])  // {sentenceIdx, status, message}

// 重写相关
const isRewriting = ref(false)
const rewriteProgress = ref('')  // 批次进度信息
const rewriteStreamContent = ref('')
const rewrittenSentences = ref([])  // {text, start, end}
const selectedRewriteIdxs = ref([])

// 保存相关
const isSaving = ref(false)
const originalContent = ref('')  // 初始内容，用于判断是否有更改

// ========== 计算属性 ==========
const canCheck = computed(() => {
  return selectedSentenceIdxs.value.length > 0 && selectedParadigm.value !== null
})

const canRewrite = computed(() => {
  return checkResults.value.length > 0 && selectedParadigm.value !== null
})

const canApply = computed(() => {
  return selectedRewriteIdxs.value.length > 0 && selectedSentenceIdxs.value.length > 0
})

// 判断内容是否有更改
const hasContentChanged = computed(() => {
  return articleContent.value !== originalContent.value && originalContent.value !== ''
})

// ========== 方法 ==========

// 返回上一页
const goBack = () => {
  appStore.setCurrentPage('writer')
}

// 拆分文章为句子
const splitToSentences = () => {
  sentences.value = splitIntoSentencesWithPosition(articleContent.value)
  // 清空之前的选择和结果
  selectedSentenceIdxs.value = []
  checkResults.value = []
  rewrittenSentences.value = []
  selectedRewriteIdxs.value = []
}

// 切换句子选中状态
const toggleSentence = (idx) => {
  const index = selectedSentenceIdxs.value.indexOf(idx)
  if (index === -1) {
    selectedSentenceIdxs.value.push(idx)
  } else {
    selectedSentenceIdxs.value.splice(index, 1)
  }
}

// 切换重写句子选中状态
const toggleRewriteSentence = (idx) => {
  const index = selectedRewriteIdxs.value.indexOf(idx)
  if (index === -1) {
    selectedRewriteIdxs.value.push(idx)
  } else {
    selectedRewriteIdxs.value.splice(index, 1)
  }
}

// 处理范式选择
const handleParadigmSelect = (paradigm) => {
  // 确保 expertGuidelines 有 scope 字段
  const paradigmWithScope = paradigmStore.ensureGuidelinesHasScope(paradigm)
  selectedParadigm.value = paradigmWithScope
  showParadigmSelector.value = false
  console.log('选择范式后的 expertGuidelines:', paradigmWithScope.expertGuidelines)
}

// 处理文稿选择
const handleDocSelect = (doc) => {
  if (doc && doc.content) {
    articleContent.value = doc.content
    originalContent.value = doc.content  // 记录原始内容用于差异检测
    articleSourceType.value = 'document'
    sourceDocId.value = doc.id
    sourceDocTitle.value = doc.title
    splitToSentences()
  }
  showDocSelector.value = false
}

// 处理创建自定义范式（打开需求解析面板）
const handleCreateCustomParadigm = () => {
  showParadigmSelector.value = false
  showRequirementParser.value = true
}

// 处理范式创建完成
const handleParadigmCreated = (paradigm) => {
  selectedParadigm.value = paradigm
  showRequirementParser.value = false
  // 可选：显示成功提示
  console.log('自定义范式已创建:', paradigm)
}

// 粒度判断函数：根据句子数量确定允许的检查粒度
const getCheckScope = (sentenceCount) => {
  if (sentenceCount <= 5) return ['sentence']         // 1-5 句：仅句子级
  if (sentenceCount <= 20) return ['sentence', 'paragraph']  // 6-20 句：句子级+段落级
  return ['sentence', 'paragraph', 'document']         // 21+ 句：所有级别
}

// 执行范式检查
const runParadigmCheck = async () => {
  if (!canCheck.value) return

  isChecking.value = true
  checkProgress.value = ''
  checkResults.value = []

  try {
    // 获取选中的句子索引（排序）
    const sortedIdxs = [...selectedSentenceIdxs.value].sort((a, b) => a - b)
    const sentenceCount = sortedIdxs.length

    // 自动分批处理：每批最多15个句子
    const BATCH_SIZE = 15
    const totalBatches = Math.ceil(sortedIdxs.length / BATCH_SIZE)

    // 确定当前检查粒度
    const allowedScopes = getCheckScope(sentenceCount)
    console.log(`总共选中 ${sentenceCount} 个句子，将分 ${totalBatches} 批处理，允许粒度:`, allowedScopes)

    // 构建公共的检查参数
    const paradigmPrompt = selectedParadigm.value.specializedPrompt || ''

    // expertGuidelines 可能是字符串数组或对象数组，需要兼容处理并过滤
    const guidelines = selectedParadigm.value.expertGuidelines || []
    const filteredGuidelines = guidelines.filter(g => {
      // 兼容字符串和对象格式
      if (typeof g === 'string') {
        // 字符串格式：默认为 sentence 级别
        return allowedScopes.includes('sentence')
      } else {
        // 对象格式：检查 scope 字段
        const scope = g.scope || 'sentence'  // 默认句子级
        return allowedScopes.includes(scope)
      }
    })

    console.log(`过滤前 expertGuidelines: ${guidelines.length} 条，过滤后: ${filteredGuidelines.length} 条`)

    const guidelinesText = filteredGuidelines
      .map((g, i) => {
        if (typeof g === 'string') {
          return `${i + 1}. ${g}`
        } else {
          return `${i + 1}. 【${g.title || '检查项'}】${g.description || g}`
        }
      })
      .join('\n')

    // 逐批处理
    for (let batchIndex = 0; batchIndex < totalBatches; batchIndex++) {
      const batchStart = batchIndex * BATCH_SIZE
      const batchEnd = Math.min(batchStart + BATCH_SIZE, sortedIdxs.length)
      const batchIdxs = sortedIdxs.slice(batchStart, batchEnd)
      const batchSentences = batchIdxs.map(idx => sentences.value[idx])

      checkProgress.value = `正在检查第 ${batchIndex + 1}/${totalBatches} 批（句子 ${batchStart + 1}-${batchEnd}）...`
      console.log(`检查批次 ${batchIndex + 1}/${totalBatches}（句子 ${batchStart + 1}-${batchEnd}）`)

      const checkPrompt = `你是一个写作质量检查专家。请基于以下范式规则和专家指令，逐条检查给定的句子。

【检查上下文】
本次检查的是 ${batchSentences.length} 个句子的片段（共选中 ${sentenceCount} 句）。
${sentenceCount <= 5 ? '⚠️ 这是句子级检查，请忽略文档结构要求，专注于句子质量（如术语、语气、表达）。' : ''}${sentenceCount <= 20 ? '⚠️ 这是段落级检查，请检查局部逻辑和结构，忽略全文结构要求（如篇幅占比、章节完整性）。' : ''}

# 范式规则
${paradigmPrompt}

# 专家检查项（已根据检查粒度自动过滤）
${guidelinesText || '（无特定检查项）'}

# 待检查的句子
${batchSentences.map((s, i) => `${i + 1}. ${s.text}`).join('\n')}

# 输出要求
请严格按照以下JSON格式输出（只输出JSON，不要markdown代码块标记）：
{
  "results": [
    {"sentenceIdx": 0, "status": "pass", "message": "符合要求"},
    {"sentenceIdx": 1, "status": "warning", "message": "建议改进"},
    {"sentenceIdx": 2, "status": "fail", "message": "不符合要求"}
  ]
}

注意：
1. status只能是 pass/warning/fail 三个值之一
2. message要简洁明了，不超过50字
3. sentenceIdx从0开始，对应上面句子的序号
4. 必须检查所有${batchSentences.length}个句子
5. 确保JSON格式完全正确，不要有多余的逗号或换行`

      let fullResponse = ''
      await appStore.callApi(checkPrompt, (chunk) => {
        fullResponse += chunk
      }, { temperature: 0.3 })

      console.log(`批次 ${batchIndex + 1} - AI完整响应长度:`, fullResponse.length)

      // 解析本批次结果
      try {
        // 1. 尝试提取JSON代码块
        let jsonText = fullResponse
        const jsonBlockMatch = fullResponse.match(/```json\s*([\s\S]*?)\s*```/)
        if (jsonBlockMatch) {
          jsonText = jsonBlockMatch[1]
        }

        // 2. 提取JSON对象
        const jsonMatch = jsonText.match(/\{[\s\S]*\}/)
        if (!jsonMatch) {
          throw new Error('未找到有效的JSON对象')
        }

        const parsed = JSON.parse(jsonMatch[0])

        if (!parsed.results || !Array.isArray(parsed.results)) {
          throw new Error('JSON格式错误：缺少results数组')
        }

        // 映射回原始句子索引并添加到总结果
        const batchResults = parsed.results.map((r, i) => ({
          sentenceIdx: batchIdxs[r.sentenceIdx] ?? batchIdxs[i],
          status: r.status || 'warning',
          message: r.message || '检查完成'
        }))

        checkResults.value.push(...batchResults)
        console.log(`批次 ${batchIndex + 1} 解析成功，本批 ${batchResults.length} 个结果`)
      } catch (e) {
        console.error(`批次 ${batchIndex + 1} 解析失败:`, e)
        console.error('完整响应内容:', fullResponse)

        // 降级：为本批次的每个句子生成通用结果
        const fallbackResults = batchIdxs.map((idx) => ({
          sentenceIdx: idx,
          status: 'warning',
          message: '解析异常，建议人工复核'
        }))
        checkResults.value.push(...fallbackResults)
      }
    }

    console.log(`所有批次检查完成，共 ${checkResults.value.length} 个结果`)
    checkProgress.value = `检查完成！共检查 ${checkResults.value.length} 个句子`
  } catch (error) {
    console.error('范式检查失败:', error)
    alert('检查失败: ' + error.message)
  } finally {
    isChecking.value = false
  }
}

// 执行 AI 重写
const runAIRewrite = async () => {
  if (!canRewrite.value) return

  isRewriting.value = true
  rewriteProgress.value = ''
  rewriteStreamContent.value = ''
  rewrittenSentences.value = []
  selectedRewriteIdxs.value = []

  try {
    // 获取选中的句子索引（排序）
    const sortedIdxs = [...selectedSentenceIdxs.value].sort((a, b) => a - b)

    // 自动分批处理：每批最多10个句子（重写比检查需要更多tokens，所以批次更小）
    const BATCH_SIZE = 10
    const totalBatches = Math.ceil(sortedIdxs.length / BATCH_SIZE)

    console.log(`总共需要重写 ${sortedIdxs.length} 个句子，将分 ${totalBatches} 批处理`)

    // 构建公共的重写参数
    const paradigmPrompt = selectedParadigm.value.specializedPrompt || ''

    // 逐批处理
    for (let batchIndex = 0; batchIndex < totalBatches; batchIndex++) {
      const batchStart = batchIndex * BATCH_SIZE
      const batchEnd = Math.min(batchStart + BATCH_SIZE, sortedIdxs.length)
      const batchIdxs = sortedIdxs.slice(batchStart, batchEnd)
      const batchSentences = batchIdxs.map(idx => sentences.value[idx])

      rewriteProgress.value = `正在重写第 ${batchIndex + 1}/${totalBatches} 批（句子 ${batchStart + 1}-${batchEnd}）...`
      console.log(`重写批次 ${batchIndex + 1}/${totalBatches}（句子 ${batchStart + 1}-${batchEnd}）`)

      // 获取本批次对应的检查结果
      const batchCheckResults = checkResults.value
        .filter(r => batchIdxs.includes(r.sentenceIdx))
        .map(r => {
          const localIdx = batchIdxs.indexOf(r.sentenceIdx)
          return `句子${localIdx + 1}: ${r.status} - ${r.message}`
        })
        .join('\n')

      const rewritePrompt = `你是一个专业的写作润色专家。请基于以下范式规则和检查结果，重写给定的句子。

# 范式规则
${paradigmPrompt}

# 检查结果
${batchCheckResults || '（无检查结果）'}

# 原句
${batchSentences.map((s, i) => `${i + 1}. ${s.text}`).join('\n')}

# 输出要求
请直接按照顺序输出重写后的句子，每句一行，格式如下（仅输出重写内容，不要其他说明）：
1. 重写后的句子1
2. 重写后的句子2
...`

      let fullResponse = ''
      await appStore.callApi(rewritePrompt, (chunk) => {
        fullResponse += chunk
        // 实时显示时尝试提取 draft 内容
        const draftMatch = fullResponse.match(/<draft>([\s\S]*?)(?:<\/draft>|$)/)
        if (draftMatch) {
          rewriteStreamContent.value = draftMatch[1].trim()
        } else {
          // 如果还没有 draft 标签，显示完整内容（可能在 thinking 阶段）
          rewriteStreamContent.value = fullResponse
        }
      }, { temperature: 0.7 })

      console.log(`批次 ${batchIndex + 1} - AI完整响应长度:`, fullResponse.length)

      // 解析重写结果：提取 <draft> 标签内的内容
      let contentToParse = fullResponse
      const draftMatch = fullResponse.match(/<draft>([\s\S]*?)<\/draft>/)
      if (draftMatch) {
        contentToParse = draftMatch[1].trim()
      }

      // 按行拆分并处理
      const lines = contentToParse.split('\n').filter(line => line.trim())
      const batchRewritten = lines.map((line, i) => {
        // 移除行首的序号
        const text = line.replace(/^\d+\.\s*/, '').trim()
        return { text, start: 0, end: text.length }
      }).filter(s => s.text) // 过滤空行

      rewrittenSentences.value.push(...batchRewritten)
      console.log(`批次 ${batchIndex + 1} 重写完成，本批 ${batchRewritten.length} 个句子`)
    }

    console.log(`所有批次重写完成，共 ${rewrittenSentences.value.length} 个句子`)
    rewriteProgress.value = `重写完成！共重写 ${rewrittenSentences.value.length} 个句子`
  } catch (error) {
    console.error('AI 重写失败:', error)
    alert('重写失败: ' + error.message)
  } finally {
    isRewriting.value = false
    rewriteStreamContent.value = ''
  }
}

// 应用选中的重写
const applySelectedRewrites = () => {
  if (!canApply.value) return

  // 获取选中的原句索引（排序）
  const sortedOrigIdxs = [...selectedSentenceIdxs.value].sort((a, b) => b - a)
  // 获取选中的重写索引（排序）
  const sortedRewriteIdxs = [...selectedRewriteIdxs.value].sort((a, b) => a - b)

  // 从后往前替换，避免位置偏移
  let newContent = articleContent.value
  const minLen = Math.min(sortedOrigIdxs.length, sortedRewriteIdxs.length)

  for (let i = 0; i < minLen; i++) {
    const origIdx = sortedOrigIdxs[i]
    const rewriteIdx = sortedRewriteIdxs[minLen - 1 - i]

    const origSentence = sentences.value[origIdx]
    const rewriteSentence = rewrittenSentences.value[rewriteIdx]

    if (origSentence && rewriteSentence) {
      newContent = newContent.slice(0, origSentence.start) + 
                   rewriteSentence.text + 
                   newContent.slice(origSentence.end)
    }
  }

  // 更新内容并重新拆分
  articleContent.value = newContent
  splitToSentences()

  // 提示完成
  alert(`已替换 ${minLen} 个句子`)
}

// 清空选择
const clearSelection = () => {
  selectedSentenceIdxs.value = []
  selectedRewriteIdxs.value = []
  checkResults.value = []
  rewrittenSentences.value = []
}

// 监听内容变化自动拆分
watch(articleContent, () => {
  if (articleSourceType.value === 'paste') {
    splitToSentences()
  }
}, { immediate: false })

// ========== 全选/反选方法 ==========

// 原文区全选
const selectAllOriginal = () => {
  selectedSentenceIdxs.value = sentences.value.map((_, idx) => idx)
}

// 原文区反选
const invertOriginalSelection = () => {
  const allIdxs = sentences.value.map((_, idx) => idx)
  selectedSentenceIdxs.value = allIdxs.filter(idx => !selectedSentenceIdxs.value.includes(idx))
}

// 重写预览区全选
const selectAllRewrite = () => {
  selectedRewriteIdxs.value = rewrittenSentences.value.map((_, idx) => idx)
}

// 重写预览区反选
const invertRewriteSelection = () => {
  const allIdxs = rewrittenSentences.value.map((_, idx) => idx)
  selectedRewriteIdxs.value = allIdxs.filter(idx => !selectedRewriteIdxs.value.includes(idx))
}

// ========== 保存方法 ==========

// 保存到文稿库
const saveToDocument = async () => {
  if (!sourceDocId.value || !hasContentChanged.value) return
  
  isSaving.value = true
  try {
    // 计算差异
    const diff = computeDiff(originalContent.value, articleContent.value)
    const changedCount = diff.filter(d => d.type !== 'unchanged').length
    
    // 保存版本历史
    const changeNote = `范式润色：修改了 ${changedCount} 处`
    saveDocumentVersion(sourceDocId.value, articleContent.value, changeNote)
    
    // 更新文稿内容
    updateDocument(sourceDocId.value, {
      content: articleContent.value
    })
    
    // 更新原始内容基准
    originalContent.value = articleContent.value
    
    alert(`保存成功！修改了 ${changedCount} 处，已创建新版本。`)
  } catch (error) {
    console.error('保存失败:', error)
    alert('保存失败: ' + error.message)
  } finally {
    isSaving.value = false
  }
}

// ========== 复检方法 ==========

// 对重写内容再次进行范式检查
const recheckRewrittenContent = async () => {
  if (selectedRewriteIdxs.value.length === 0 || !selectedParadigm.value) {
    alert('请先在重写预览区选中要复检的句子')
    return
  }

  isChecking.value = true
  checkResults.value = []

  try {
    // 获取选中的重写句子索引（排序）
    const sortedIdxs = [...selectedRewriteIdxs.value].sort((a, b) => a - b)
    const sentenceCount = sortedIdxs.length

    // 自动分批处理：每批最多15个句子
    const BATCH_SIZE = 15
    const totalBatches = Math.ceil(sortedIdxs.length / BATCH_SIZE)

    // 确定当前检查粒度
    const allowedScopes = getCheckScope(sentenceCount)
    console.log(`[复检] 总共选中 ${sentenceCount} 个句子，将分 ${totalBatches} 批处理，允许粒度:`, allowedScopes)

    // 构建公共的检查参数
    const paradigmPrompt = selectedParadigm.value.specializedPrompt || ''

    // expertGuidelines 可能是字符串数组或对象数组，需要兼容处理并过滤
    const guidelines = selectedParadigm.value.expertGuidelines || []
    const filteredGuidelines = guidelines.filter(g => {
      // 兼容字符串和对象格式
      if (typeof g === 'string') {
        // 字符串格式：默认为 sentence 级别
        return allowedScopes.includes('sentence')
      } else {
        // 对象格式：检查 scope 字段
        const scope = g.scope || 'sentence'  // 默认句子级
        return allowedScopes.includes(scope)
      }
    })

    console.log(`[复检] 过滤前 expertGuidelines: ${guidelines.length} 条，过滤后: ${filteredGuidelines.length} 条`)

    const guidelinesText = filteredGuidelines
      .map((g, i) => {
        if (typeof g === 'string') {
          return `${i + 1}. ${g}`
        } else {
          return `${i + 1}. 【${g.title || '检查项'}】${g.description || g}`
        }
      })
      .join('\n')

    // 逐批处理
    for (let batchIndex = 0; batchIndex < totalBatches; batchIndex++) {
      const batchStart = batchIndex * BATCH_SIZE
      const batchEnd = Math.min(batchStart + BATCH_SIZE, sortedIdxs.length)
      const batchIdxs = sortedIdxs.slice(batchStart, batchEnd)
      const batchSentences = batchIdxs.map(idx => rewrittenSentences.value[idx])

      console.log(`[复检] 批次 ${batchIndex + 1}/${totalBatches}: 处理句子 ${batchStart + 1}-${batchEnd}`)

      const checkPrompt = `你是一个写作质量检查专家。请基于以下范式规则和专家指令，逐条检查给定的句子。

【检查上下文】
本次检查的是 ${batchSentences.length} 个句子的片段（共选中 ${sentenceCount} 句，这是重写后的内容复检）。
${sentenceCount <= 5 ? '⚠️ 这是句子级检查，请忽略文档结构要求，专注于句子质量（如术语、语气、表达）。' : ''}${sentenceCount <= 20 ? '⚠️ 这是段落级检查，请检查局部逻辑和结构，忽略全文结构要求（如篇幅占比、章节完整性）。' : ''}

# 范式规则
${paradigmPrompt}

# 专家检查项（已根据检查粒度自动过滤）
${guidelinesText || '（无特定检查项）'}

# 待检查的句子（重写后的内容）
${batchSentences.map((s, i) => `${i + 1}. ${s.text}`).join('\n')}

# 输出要求
请严格按照以下 JSON 格式输出检查结果（仅输出 JSON，不要其他内容）：
{
  "results": [
    {"sentenceIdx": 0, "status": "pass|warning|fail", "message": "评价说明"}
  ]
}`

      let fullResponse = ''
      await appStore.callApi(checkPrompt, (chunk) => {
        fullResponse += chunk
      }, { temperature: 0.3 })

      // 解析结果
      try {
        const jsonMatch = fullResponse.match(/\{[\s\S]*\}/)
        if (jsonMatch) {
          const parsed = JSON.parse(jsonMatch[0])
          // 映射回重写句子索引，并标记为「复检」
          const batchResults = (parsed.results || []).map((r, i) => ({
            sentenceIdx: batchIdxs[r.sentenceIdx] ?? batchIdxs[i],
            status: r.status || 'warning',
            message: `[复检] ${r.message || '检查完成'}`,
            isRecheck: true  // 标记为复检结果
          }))
          checkResults.value.push(...batchResults)
        }
      } catch (e) {
        console.warn(`[复检] 批次 ${batchIndex + 1} 结果解析失败:`, e)
        // 为当前批次的句子添加警告结果
        const fallbackResults = batchIdxs.map((idx) => ({
          sentenceIdx: idx,
          status: 'warning',
          message: '[复检] 解析异常，建议人工复核',
          isRecheck: true
        }))
        checkResults.value.push(...fallbackResults)
      }
    }

    console.log(`[复检] 所有批次处理完成，共 ${checkResults.value.length} 条结果`)
  } catch (error) {
    console.error('复检失败:', error)
    alert('复检失败: ' + error.message)
  } finally {
    isChecking.value = false
  }
}
</script>
