<template>
  <div class="article-editor-panel">
    <!-- 左侧：原文区 -->
    <aside class="panel-left">
      <header class="panel-header">
        <h2 class="panel-title">
          <IconLibrary name="document" :size="18" />
          <span>原文</span>
        </h2>
        <div class="header-actions">
          <!-- 选择粒度切换 -->
          <div class="mode-switch">
            <button 
              :class="['mode-btn', { active: selectionMode === 'sentence' }]"
              @click="selectionMode = 'sentence'"
            >句子</button>
            <button 
              :class="['mode-btn', { active: selectionMode === 'paragraph' }]"
              @click="selectionMode = 'paragraph'"
            >段落</button>
          </div>
          <button class="btn-secondary btn-sm" @click="showDocSelector = true">
            <IconLibrary name="folder" :size="14" />
            <span>导入</span>
          </button>
          <button 
            v-if="sourceDocId"
            class="btn-primary btn-sm"
            :disabled="isSavingOriginal || !articleContent"
            @click="saveOriginalContent"
          >
            <IconLibrary v-if="isSavingOriginal" name="loading" :size="14" class="spin" />
            <IconLibrary v-else name="save" :size="14" />
            <span>{{ isSavingOriginal ? '保存中...' : '保存' }}</span>
          </button>
        </div>
      </header>

      <!-- 来源信息 -->
      <div v-if="sourceDocTitle" class="source-info">
        <IconLibrary name="document" :size="12" />
        <span>{{ sourceDocTitle }}</span>
      </div>

      <!-- 选择统计 -->
      <div class="selection-stats">
        <span class="text-muted">{{ contentUnits.length }} {{ selectionMode === 'sentence' ? '句' : '段' }}</span>
        <span v-if="selectedIdxs.length > 0" class="text-highlight">
          已选 {{ selectedIdxs.length }} {{ selectionMode === 'sentence' ? '句' : '段' }}
          <span class="word-count">(约 {{ selectedWordCount }} 字)</span>
        </span>
        <div class="stats-actions">
          <button @click="selectAll" class="btn-link">全选</button>
          <button @click="invertSelection" class="btn-link">反选</button>
        </div>
      </div>

      <!-- 内容展示区 -->
      <div class="content-display">
        <div v-if="contentUnits.length === 0" class="empty-state">
          <IconLibrary name="document" :size="48" class="empty-icon" />
          <p>粘贴文章或从文稿库导入</p>
        </div>
        <div v-else class="content-units">
          <span
            v-for="(unit, idx) in contentUnits"
            :key="'unit-' + idx"
            @click="toggleSelect(idx)"
            :class="[
              'content-unit',
              selectionMode,
              { selected: selectedIdxs.includes(idx) }
            ]"
          >{{ unit.text }}</span>
        </div>
      </div>

      <!-- 输入框 -->
      <div class="input-area">
        <textarea 
          v-model="articleContent"
          class="article-input"
          placeholder="粘贴或输入文章内容..."
          @input="parseContent"
        ></textarea>
      </div>
    </aside>

    <!-- 中间：操作区 -->
    <section class="panel-center">
      <header class="panel-header">
        <h2 class="panel-title">
          <IconLibrary name="settings" :size="18" />
          <span>修改设置</span>
        </h2>
      </header>

      <div class="operation-content">
        <!-- 素材选择 -->
        <div class="section">
          <label class="section-label">
            <span>关联素材</span>
            <button class="btn-link" @click="showMaterialSelector = true">
              <IconLibrary name="add" :size="14" />
              添加
            </button>
          </label>
          <div v-if="linkedMaterials.length > 0" class="materials-list">
            <div 
              v-for="mat in linkedMaterials" 
              :key="mat.id"
              class="material-item"
            >
              <span class="material-name">{{ mat.title }}</span>
              <button @click="removeMaterial(mat.id)" class="btn-icon-danger">
                <IconLibrary name="close" :size="12" />
              </button>
            </div>
          </div>
          <p v-else class="text-muted text-sm">点击"添加"选择参考素材</p>
        </div>

        <!-- 修改提示词 -->
        <div class="section">
          <label class="section-label">修改提示词</label>
          <textarea
            v-model="modifyPrompt"
            class="prompt-input"
            placeholder="描述你希望如何修改选中的内容，例如：
• 让语言更加正式
• 增加数据支撑
• 精简表达"
            rows="6"
          ></textarea>
        </div>

        <!-- 快捷提示词 -->
        <div class="section">
          <label class="section-label">快捷操作</label>
          <div class="quick-prompts">
            <button 
              v-for="prompt in quickPrompts" 
              :key="prompt.label"
              @click="modifyPrompt = prompt.value"
              class="quick-prompt-btn"
            >{{ prompt.label }}</button>
          </div>
        </div>
      </div>

      <!-- 操作按钮 -->
      <footer class="panel-footer">
        <button 
          @click="runModify"
          :disabled="!canModify || isModifying"
          class="btn-primary btn-block"
        >
          <IconLibrary v-if="isModifying" name="loading" :size="16" class="spin" />
          <IconLibrary v-else name="sparkles" :size="16" />
          <span>{{ isModifying ? '修改中...' : 'AI 修改' }}</span>
        </button>
      </footer>
    </section>

    <!-- 右侧：对照区 -->
    <aside class="panel-right">
      <header class="panel-header">
        <h2 class="panel-title">
          <IconLibrary name="compare" :size="18" />
          <span>修改结果</span>
        </h2>
        <div class="header-actions">
          <button 
            v-if="modifiedContent"
            @click="applyModification"
            class="btn-secondary btn-sm"
          >
            <IconLibrary name="check" :size="14" />
            <span>应用</span>
          </button>
          <button 
            v-if="modifiedContent && sourceDocId"
            @click="saveToDocument"
            :disabled="isSaving"
            class="btn-primary btn-sm"
          >
            <IconLibrary v-if="isSaving" name="loading" :size="14" class="spin" />
            <IconLibrary v-else name="save" :size="14" />
            <span>{{ isSaving ? '保存中...' : '保存' }}</span>
          </button>
        </div>
      </header>

      <!-- 统计信息 -->
      <div class="right-stats">
        <span class="text-muted">{{ rightWordCount }} 字</span>
        <template v-if="diffStats">
          <span class="stat modified">{{ diffStats.modified }} 处修改</span>
          <span class="stat added">{{ diffStats.added }} 处新增</span>
          <span class="stat removed">{{ diffStats.removed }} 处删除</span>
        </template>
      </div>

      <!-- 对照内容 -->
      <div class="compare-content">
        <!-- 空状态 -->
        <div v-if="contentUnits.length === 0" class="empty-state">
          <IconLibrary name="sparkles" :size="48" class="empty-icon" />
          <p>左侧输入原文后这里同步显示</p>
        </div>
        <!-- 镜像显示（支持流式覆盖） -->
        <div v-else class="mirror-display">
          <template v-for="(unit, idx) in displayUnits" :key="'display-' + idx">
            <!-- 流式覆盖中 -->
            <span 
              v-if="unit.status === 'streaming'"
              :class="['display-unit', selectionMode, 'streaming']"
            ><IconLibrary name="loading" :size="12" class="spin inline-icon" />{{ unit.text }}</span>
            <!-- 未修改的内容 -->
            <span 
              v-else-if="unit.status === 'unchanged'"
              :class="['display-unit', selectionMode]"
            >{{ unit.text }}</span>
            <!-- 左侧已选中对应 -->
            <span 
              v-else-if="unit.status === 'selected'"
              :class="['display-unit', selectionMode, 'is-selected']"
            >{{ unit.text }}</span>
            <!-- 被修改的内容 -->
            <span 
              v-else-if="unit.status === 'modified'"
              :class="['display-unit', selectionMode, 'modified']"
              :title="'原文: ' + unit.originalText"
            >{{ unit.text }}</span>
            <!-- 被删除的内容 -->
            <del 
              v-else-if="unit.status === 'removed'"
              :class="['display-unit', selectionMode, 'removed']"
            >{{ unit.text }}</del>
            <!-- 新增的内容 -->
            <span 
              v-else-if="unit.status === 'added'"
              :class="['display-unit', selectionMode, 'added']"
            >{{ unit.text }}</span>
          </template>
        </div>
      </div>
    </aside>

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

    <!-- 素材选择弹窗 -->
    <MaterialSelectorModal
      :visible="showMaterialSelector"
      @close="showMaterialSelector = false"
      @select="handleMaterialSelect"
    />
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted } from 'vue'
import { useAppStore } from '../stores/app'
import { useDatabaseStore } from '../stores/database'
import { 
  splitIntoSentencesWithPosition, 
  computeDiff, 
  getDiffStats 
} from '../utils/textDiff'
import { saveDocumentVersion, updateDocument } from '../db/index.js'
import DocumentSelectorModal from './DocumentSelectorModal.vue'
import MaterialSelectorModal from './MaterialSelectorModal.vue'
import IconLibrary from './icons/IconLibrary.vue'

const appStore = useAppStore()
const dbStore = useDatabaseStore()

// 状态初始化
onMounted(async () => {
  await dbStore.initialize()
  await dbStore.refreshReferences()
})

// ========== 状态 ==========
// 原文相关
const articleContent = ref('')
const sourceDocId = ref(null)
const sourceDocTitle = ref('')
const selectionMode = ref('sentence') // 'sentence' | 'paragraph'
const selectedIdxs = ref([])

// 操作相关
const linkedMaterials = ref([])
const modifyPrompt = ref('')
const isModifying = ref(false)
const isSaving = ref(false)
const isSavingOriginal = ref(false)

// 结果相关
const modifiedContent = ref('')
const diffSegments = ref([])
const streamingContent = ref('') // 流式输出中的原始内容
const streamingOverlay = ref('') // 流式覆盖内容（用于精确位置覆盖）

// 弹窗
const showDocSelector = ref(false)
const showMaterialSelector = ref(false)

// 快捷提示词
const quickPrompts = [
  { label: '更正式', value: '请让语言更加正式、书面化' },
  { label: '更简洁', value: '请精简表达，去除冗余' },
  { label: '更生动', value: '请让表达更加生动形象' },
  { label: '补充论据', value: '请适当补充数据或论据支撑' }
]

// ========== 计算属性 ==========

// 内容单元（句子或段落）
const contentUnits = computed(() => {
  if (!articleContent.value) return []
  
  if (selectionMode.value === 'sentence') {
    return splitIntoSentencesWithPosition(articleContent.value)
  } else {
    // 按段落拆分
    return splitIntoParagraphs(articleContent.value)
  }
})

// 是否可以执行修改
const canModify = computed(() => {
  return selectedIdxs.value.length > 0 && modifyPrompt.value.trim()
})

// 差异统计
const diffStats = computed(() => {
  if (diffSegments.value.length === 0) return null
  return getDiffStats(diffSegments.value)
})

// 选中内容字数统计
const selectedWordCount = computed(() => {
  if (selectedIdxs.value.length === 0) return 0
  const selectedUnits = selectedIdxs.value.map(idx => contentUnits.value[idx])
  const totalText = selectedUnits.map(u => u?.text || '').join('')
  return totalText.length
})

// 右侧显示单元（原文镜像 + 精确位置差异高亮 + 流式覆盖）
const displayUnits = computed(() => {
  if (contentUnits.value.length === 0) return []
  
  const result = []
  const selectedSet = new Set(selectedIdxs.value)
  
  // 遍历每个原文单元
  for (let i = 0; i < contentUnits.value.length; i++) {
    const original = contentUnits.value[i]
    const isSelected = selectedSet.has(i)
    
    // 如果正在修改且是选中的单元，显示流式内容
    if (isModifying.value && isSelected && streamingOverlay.value) {
      // 找到当前单元在选中列表中的位置
      const selectedIdx = [...selectedIdxs.value].sort((a, b) => a - b).indexOf(i)
      // 分割流式内容（按换行或句子）
      const streamParts = streamingOverlay.value.split('\n').filter(p => p.trim())
      const overlayText = streamParts[selectedIdx] || '...'
      
      result.push({
        text: overlayText,
        status: 'streaming',
        originalText: original.text,
        originalIdx: i
      })
    } else if (modifiedContent.value) {
      // 有修改结果时，计算差异
      const modifiedUnits = selectionMode.value === 'sentence'
        ? splitIntoSentencesWithPosition(modifiedContent.value)
        : splitIntoParagraphs(modifiedContent.value)
      
      const modified = modifiedUnits[i]
      if (modified) {
        const isModified = isSelected && original.text !== modified.text
        result.push({
          text: modified.text,
          status: isModified ? 'modified' : 'unchanged',
          originalText: original.text,
          originalIdx: i
        })
      } else {
        result.push({
          text: original.text,
          status: 'unchanged',
          originalText: original.text,
          originalIdx: i
        })
      }
    } else {
      // 无修改时，显示原文
      result.push({
        text: original.text,
        status: isSelected ? 'selected' : 'unchanged',
        originalText: original.text,
        originalIdx: i
      })
    }
  }
  
  return result
})

// 右侧内容字数统计
const rightWordCount = computed(() => {
  const text = displayUnits.value.map(u => u.text).join('')
  return text.length
})

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

// 按段落拆分
const splitIntoParagraphs = (text) => {
  if (!text) return []
  
  const paragraphs = []
  const lines = text.split(/\n+/)
  let currentStart = 0
  
  for (const line of lines) {
    const trimmed = line.trim()
    if (trimmed) {
      const start = text.indexOf(line, currentStart)
      paragraphs.push({
        text: trimmed,
        start: start,
        end: start + line.length
      })
      currentStart = start + line.length
    }
  }
  
  return paragraphs
}

// 解析内容
const parseContent = () => {
  selectedIdxs.value = []
  modifiedContent.value = ''
  diffSegments.value = []
}

// 切换选择
const toggleSelect = (idx) => {
  const index = selectedIdxs.value.indexOf(idx)
  if (index === -1) {
    selectedIdxs.value.push(idx)
  } else {
    selectedIdxs.value.splice(index, 1)
  }
}

// 全选
const selectAll = () => {
  selectedIdxs.value = contentUnits.value.map((_, idx) => idx)
}

// 反选
const invertSelection = () => {
  const allIdxs = contentUnits.value.map((_, idx) => idx)
  selectedIdxs.value = allIdxs.filter(idx => !selectedIdxs.value.includes(idx))
}

// 处理文稿选择
const handleDocSelect = (doc) => {
  if (doc?.content) {
    articleContent.value = doc.content
    sourceDocId.value = doc.id
    sourceDocTitle.value = doc.title
    parseContent()
  }
  showDocSelector.value = false
}

// 处理素材选择
const handleMaterialSelect = (material) => {
  if (material && !linkedMaterials.value.find(m => m.id === material.id)) {
    linkedMaterials.value.push(material)
  }
}

// 移除素材
const removeMaterial = (id) => {
  linkedMaterials.value = linkedMaterials.value.filter(m => m.id !== id)
}

// 执行 AI 修改
const runModify = async () => {
  if (!canModify.value) return
  
  isModifying.value = true
  modifiedContent.value = ''
  diffSegments.value = []
  streamingContent.value = ''
  streamingOverlay.value = '' // 清空流式覆盖
  
  try {
    // 获取选中的内容
    const sortedIdxs = [...selectedIdxs.value].sort((a, b) => a - b)
    const selectedUnits = sortedIdxs.map(idx => contentUnits.value[idx])
    const selectedText = selectedUnits.map(u => u.text).join('\n')
    
    // 构建素材文本
    let materialsText = ''
    if (linkedMaterials.value.length > 0) {
      materialsText = linkedMaterials.value.map(m => {
        const content = m.excerpts?.map(e => e.content).join('\n') || ''
        return `【${m.title}】\n${content}`
      }).join('\n\n')
    }
    
    // 构建 Prompt
    const prompt = `你是一个专业的写作修改专家。请根据用户的修改要求和参考素材，对指定内容进行修改。

# 修改要求
${modifyPrompt.value}

${materialsText ? `# 参考素材\n${materialsText}\n` : ''}# 待修改内容
${selectedText}

# 原文上下文（供参考，不需要全部输出）
${articleContent.value.substring(0, 2000)}${articleContent.value.length > 2000 ? '...' : ''}

# 输出要求
请直接输出修改后的内容，保持与原文相同的格式和数量。每个修改项单独一行。只输出修改后的部分，不要输出其他说明。`

    let fullResponse = ''
    
    // 流式接收并实时更新预览
    await appStore.callApi(prompt, (chunk) => {
      fullResponse += chunk
      
      // 实时更新流式预览内容
      let currentResult = fullResponse
      const draftMatch = fullResponse.match(/<draft>([\s\S]*?)(?:<\/draft>|$)/)
      if (draftMatch) {
        currentResult = draftMatch[1].trim()
      }
      
      // 更新流式覆盖内容（用于精确位置覆盖）
      streamingOverlay.value = currentResult
      streamingContent.value = currentResult
    }, { temperature: 0.7 })
    
    // 最终处理 - 构建最终版本
    streamingOverlay.value = ''
    
    let resultContent = fullResponse.trim()
    const draftMatch = fullResponse.match(/<draft>([\s\S]*?)<\/draft>/)
    if (draftMatch) {
      resultContent = draftMatch[1].trim()
    }
    
    // 构建最终内容
    let newContent = articleContent.value
    
    // 将选中的索引按连续块分组
    if (sortedIdxs.length > 0) {
      // 找出所有连续的块
      const blocks = []
      let currentBlock = [sortedIdxs[0]]
      
      for (let i = 1; i < sortedIdxs.length; i++) {
        if (sortedIdxs[i] === sortedIdxs[i - 1] + 1) {
          currentBlock.push(sortedIdxs[i])
        } else {
          blocks.push(currentBlock)
          currentBlock = [sortedIdxs[i]]
        }
      }
      blocks.push(currentBlock)
      
      // 按从后往前的顺序进行替换，避免位置偏移
      const reversedBlocks = [...blocks].reverse()
      const aiLines = resultContent.split('\n').filter(l => l.trim())
      
      if (blocks.length === 1) {
        // 最常见情况：选中的是一个连续区域
        // 将整个 AI 响应替换掉这个区域
        const block = blocks[0]
        const startUnit = contentUnits.value[block[0]]
        const endUnit = contentUnits.value[block[block.length - 1]]
        
        newContent = newContent.slice(0, startUnit.start) + resultContent + newContent.slice(endUnit.end)
      } else {
        // 非连续区域：尝试按比例或按行分配（比较复杂，目前先按 1:1 分配，余下的放最后）
        // 这部分在 Prompt 中已经要求 AI 按项输出了
        const reversedUnits = sortedIdxs.map(idx => contentUnits.value[idx]).reverse()
        
        for (let i = 0; i < reversedUnits.length; i++) {
          const unit = reversedUnits[i]
          // 如果是一对一则替换，否则如果到最后了就把剩下的都给它（虽然逻辑上不太严谨，但保证了内容不丢）
          let replacement = ''
          const lineIdx = aiLines.length - 1 - i
          
          if (i === 0 && aiLines.length > reversedUnits.length) {
            // 最后一个选中的单元接纳所有多出来的 AI 行
            replacement = aiLines.slice(0, aiLines.length - reversedUnits.length + 1).join('\n')
          } else {
            replacement = aiLines[lineIdx] || unit.text
          }
          
          newContent = newContent.slice(0, unit.start) + replacement + newContent.slice(unit.end)
        }
      }
    }
    
    modifiedContent.value = newContent
    diffSegments.value = computeDiff(articleContent.value, newContent)
    
  } catch (error) {
    console.error('AI 修改失败:', error)
    alert('修改失败: ' + error.message)
  } finally {
    isModifying.value = false
    streamingOverlay.value = '' // 确保清空
  }
}

// 应用修改
const applyModification = () => {
  if (!modifiedContent.value) return
  
  articleContent.value = modifiedContent.value
  parseContent()
  modifiedContent.value = ''
  diffSegments.value = []
}

// 保存到文稿库
const saveToDocument = async () => {
  if (!sourceDocId.value || !modifiedContent.value) return
  
  isSaving.value = true
  try {
    const changedCount = diffStats.value?.modified + diffStats.value?.added || 0
    const changeNote = `文章修改：修改了 ${changedCount} 处`
    
    // 保存版本
    await saveDocumentVersion(sourceDocId.value, modifiedContent.value, changeNote)
    
    // 更新文稿
    await updateDocument(sourceDocId.value, {
      content: modifiedContent.value
    })
    
    // 应用修改
    applyModification()
    
    alert(`保存成功！${changeNote}，已创建新版本。`)
  } catch (error) {
    console.error('保存失败:', error)
    alert('保存失败: ' + error.message)
  } finally {
    isSaving.value = false
  }
}

// 保存原文到文稿库
const saveOriginalContent = async () => {
  if (!sourceDocId.value || !articleContent.value) return
  
  isSavingOriginal.value = true
  try {
    const changeNote = '手动修改原文'
    
    // 保存版本
    await saveDocumentVersion(sourceDocId.value, articleContent.value, changeNote)
    
    // 更新文稿
    await updateDocument(sourceDocId.value, {
      content: articleContent.value
    })
    
    alert('原文保存成功！已创建新版本。')
  } catch (error) {
    console.error('保存原文失败:', error)
    alert('保存原文失败: ' + error.message)
  } finally {
    isSavingOriginal.value = false
  }
}

// 监听选择模式变化
watch(selectionMode, () => {
  selectedIdxs.value = []
})
</script>

<style scoped>
.article-editor-panel {
  display: flex;
  width: 100%;
  height: 100vh;
  background: var(--bg-primary);
  overflow: hidden;
}

/* 通用面板样式 */
.panel-left,
.panel-center,
.panel-right {
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--border-default);
  overflow: hidden;
}

.panel-left {
  flex: 1;
  min-width: 300px;
}

.panel-center {
  width: 260px;
  min-width: 220px;
  flex-shrink: 0;
  background: var(--bg-secondary);
}

.panel-right {
  flex: 1;
  min-width: 300px;
  border-right: none;
}

/* 面板头部 */
.panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-default);
  background: var(--bg-elevated);
  flex-shrink: 0;
  min-height: 52px;
  box-sizing: border-box;
}

.panel-title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-base);
  font-weight: var(--font-semibold);
  color: var(--text-primary);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* 模式切换 */
.mode-switch {
  display: flex;
  background: var(--bg-primary);
  border-radius: var(--radius-md);
  padding: 2px;
}

.mode-btn {
  padding: 4px 12px;
  font-size: var(--text-xs);
  border: none;
  background: transparent;
  color: var(--text-muted);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: all 0.15s;
}

.mode-btn.active {
  background: var(--accent-primary);
  color: white;
}

/* 来源信息 */
.source-info {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  background: var(--bg-elevated);
  border-bottom: 1px solid var(--border-default);
  font-size: var(--text-xs);
  color: var(--text-secondary);
}

/* 选择统计 */
.selection-stats {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-4);
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border-default);
  font-size: var(--text-xs);
}

.text-muted {
  color: var(--text-muted);
}

.text-highlight {
  color: var(--accent-primary);
  font-weight: var(--font-medium);
}

.word-count {
  color: var(--text-muted);
  font-weight: normal;
  font-size: var(--text-xs);
  margin-left: var(--space-1);
}

/* 统计信息 (右侧) */
.right-stats {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-2) var(--space-4);
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border-default);
  font-size: var(--text-xs);
  min-height: 40px;
}

.stat {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

.stat.modified { color: #fbbf24; }
.stat.added { color: #34d399; }
.stat.removed { color: #f87171; }

.stats-actions {
  margin-left: auto;
  display: flex;
  gap: var(--space-2);
}

/* 内容展示区 */
.content-display {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-4);
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: var(--text-muted);
  gap: var(--space-3);
}

.empty-icon {
  opacity: 0.3;
}

.content-units {
  line-height: 1.8;
}

.content-unit {
  cursor: pointer;
  transition: all 0.15s;
  border-radius: var(--radius-sm);
  padding: 1px 2px;
}

.content-unit:hover {
  background: rgba(96, 165, 250, 0.1);
}

.content-unit.selected {
  background: rgba(96, 165, 250, 0.3);
  color: var(--text-primary);
}

.content-unit.paragraph {
  display: block;
  margin-bottom: var(--space-3);
  padding: var(--space-2);
}

/* 输入区 */
.input-area {
  padding: var(--space-3);
  border-top: 1px solid var(--border-default);
  background: var(--bg-elevated);
  flex-shrink: 0;
}

.article-input {
  width: 100%;
  height: 80px;
  padding: var(--space-3);
  background: var(--bg-primary);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  font-size: var(--text-sm);
  resize: none;
}

.article-input:focus {
  outline: none;
  border-color: var(--accent-primary);
}

/* 操作区内容 */
.operation-content {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-4);
}

.section {
  margin-bottom: var(--space-5);
}

.section-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
  color: var(--text-secondary);
  margin-bottom: var(--space-2);
}

.materials-list {
  background: var(--bg-primary);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.material-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border-default);
}

.material-item:last-child {
  border-bottom: none;
}

.material-name {
  font-size: var(--text-sm);
  color: var(--text-primary);
}

.prompt-input {
  width: 100%;
  padding: var(--space-3);
  background: var(--bg-primary);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  font-size: var(--text-sm);
  resize: vertical;
}

.prompt-input:focus {
  outline: none;
  border-color: var(--accent-primary);
}

.quick-prompts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.quick-prompt-btn {
  padding: 4px 10px;
  font-size: var(--text-xs);
  background: var(--bg-primary);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-full);
  color: var(--text-secondary);
  cursor: pointer;
  transition: all 0.15s;
}

.quick-prompt-btn:hover {
  border-color: var(--accent-primary);
  color: var(--accent-primary);
}

/* 面板底部 */
.panel-footer {
  padding: var(--space-4);
  border-top: 1px solid var(--border-default);
  background: var(--bg-secondary);
  flex-shrink: 0;
}

/* 差异统计 */
.diff-stats {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-4);
  background: var(--bg-elevated);
  border-bottom: 1px solid var(--border-default);
  font-size: var(--text-xs);
}

.stat.modified {
  color: #fbbf24;
}

.stat.added {
  color: #34d399;
}

.stat.removed {
  color: #f87171;
}

/* 对照内容 */
.compare-content {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-4);
}

/* 流式预览 */
.streaming-preview {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.streaming-header {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) 0;
  color: var(--accent-primary);
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
  border-bottom: 1px solid var(--border-default);
  margin-bottom: var(--space-3);
}

.streaming-content {
  flex: 1;
  line-height: 1.8;
  white-space: pre-wrap;
  color: var(--text-primary);
  font-size: var(--text-sm);
}

/* 镜像显示区域 */
.mirror-display {
  line-height: 1.8;
}

.display-unit {
  transition: background 0.2s ease;
}

.display-unit.sentence {
  /* 句子模式 - 连续显示 */
}

.display-unit.paragraph {
  display: block;
  margin-bottom: var(--space-3);
}

/* 差异高亮 */
.display-unit.is-selected {
  background: rgba(59, 130, 246, 0.1);
}

.display-unit.modified {
  background: rgba(251, 191, 36, 0.25);
  border-bottom: 2px solid #fbbf24;
}

.display-unit.added {
  background: rgba(52, 211, 153, 0.25);
  border-bottom: 2px solid #34d399;
}

.display-unit.removed {
  background: rgba(248, 113, 113, 0.2);
  color: #f87171;
  text-decoration: line-through;
}

.display-unit.streaming {
  background: rgba(59, 130, 246, 0.15);
  border-bottom: 2px solid #3b82f6;
  color: var(--accent-primary);
}

.inline-icon {
  display: inline;
  vertical-align: middle;
  margin-right: var(--space-1);
}

.diff-display {
  line-height: 1.8;
}

.diff-unchanged {
  color: var(--text-primary);
}

.diff-modified {
  background: rgba(251, 191, 36, 0.2);
  border-bottom: 2px solid #fbbf24;
  cursor: help;
}

.diff-added {
  background: rgba(52, 211, 153, 0.2);
  border-bottom: 2px solid #34d399;
}

.diff-removed {
  background: rgba(248, 113, 113, 0.2);
  color: #f87171;
  text-decoration: line-through;
}

/* 按钮 */
.btn-primary {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-3);
  background: linear-gradient(135deg, var(--accent-primary), #6366f1);
  color: white;
  border: none;
  border-radius: var(--radius-lg);
  font-weight: var(--font-semibold);
  cursor: pointer;
  transition: all 0.2s;
}

.btn-primary:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
}

.btn-primary:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn-secondary {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding: 4px 10px;
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  color: var(--text-secondary);
  font-size: var(--text-xs);
  cursor: pointer;
  transition: all 0.15s;
}

.btn-secondary:hover {
  background: var(--bg-primary);
  border-color: var(--accent-primary);
}

.btn-sm {
  padding: 4px 10px;
  font-size: var(--text-xs);
}

.btn-link {
  background: none;
  border: none;
  color: var(--accent-primary);
  font-size: var(--text-xs);
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

.btn-link:hover {
  text-decoration: underline;
}

.btn-icon-danger {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 2px;
}

.btn-icon-danger:hover {
  color: #f87171;
}

.btn-block {
  width: 100%;
}

.text-sm {
  font-size: var(--text-xs);
}

.spin {
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
</style>
