<script setup lang="ts">
/**
 * MindMapEditor - 思维导图编辑器（新版四层架构）
 * 
 * 基于：
 * - Graph Model（数据模型）
 * - Layout Engine（布局引擎）
 * - Canvas Renderer（渲染层）
 * - Interaction System（交互系统）
 */

import { ref, onMounted, onUnmounted, computed, watch, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useMessage, NButton, NSpace, NDropdown, NModal, NInput, NFormItem, NColorPicker, NDivider, NPopover, NIcon } from 'naive-ui'
import { Icon } from '@iconify/vue'
import { useMindMap } from './useMindMap'
import { getRecord, updateRecord } from '@/shared/api/common'
import { slugToPageType } from '@/shared/utils/slug'
import type { LayoutType, SerializedGraph } from './core/types'
import type { ThemeConfig, ColorSchemeType, LevelColorConfig } from './theme'
import { t } from '@/shared/i18n'
import { layoutRegistry } from './layout'
import { useRealtime, type PgUpdateData } from '@/shared/composables/useRealtime'
import { GraphModel } from './core/GraphModel'
import { 
  SYSTEM_THEMES, 
  getThemeById, 
  createCustomTheme, 
  saveThemeConfig,
  loadThemeConfig,
  saveToFavoriteThemes,
  removeFromFavoriteThemes,
  loadFavoriteThemes,
  isThemeInFavorites,
  generateLevelColors,
  hexToRgb,
  rgbToHex
} from './theme'

// ---- 路由 & 消息 ----
const route = useRoute()
const router = useRouter()
const message = useMessage()

const recordName = ref<string>((route.query.id as string) || '')

// ---- Canvas 引用 ----
const canvasRef = ref<HTMLCanvasElement>()

// ---- 思维导图逻辑 ----
const {
  graph,
  layoutType,
  renderer,
  initCanvas,
  applyLayout,
  addNode,
  addParent,
  removeNode,
  removeNodes,
  updateNodeLabel,
  updateNodeData,
  toggleCollapse,
  setThemeConfig,
  exportData,
  importData,
  fitView,
  zoomIn,
  zoomOut,
  resetZoom,
  interaction,
  setSelectedNodeId,
  setSelectedNodeIds,
  getSelectedNodeIds,
  resize,
  // 历史管理
  canUndo,
  canRedo,
  undo,
  redo,
  saveHistory,
  clearHistory
} = useMindMap()

// ---- 选中节点 ----
const selectedNodeId = ref<string | null>(null)
const selectedNodeIds = ref<string[]>([])  // 支持多选

// ---- 右键菜单 ----
const contextMenu = ref({
  show: false,
  x: 0,
  y: 0,
  nodeId: ''
})

// 当前右键菜单选中的节点是否有子节点
const contextNodeHasChildren = computed(() => {
  if (!contextMenu.value.nodeId) return false
  const children = graph.value.getChildren(contextMenu.value.nodeId)
  return children.length > 0
})

// 当前右键菜单选中的节点是否已折叠
const contextNodeCollapsed = computed(() => {
  if (!contextMenu.value.nodeId) return false
  const node = graph.value.getNode(contextMenu.value.nodeId)
  return node?.collapsed || false
})

// 当前右键菜单选中的节点是否可以添加父节点（非根节点）
const contextCanAddParent = computed(() => {
  if (!contextMenu.value.nodeId) return false
  const node = graph.value.getNode(contextMenu.value.nodeId)
  return node && !node.isRoot
})

function showContextMenu(x: number, y: number, nodeId: string) {
  contextMenu.value = { show: true, x, y, nodeId }
}

function closeContextMenu() {
  contextMenu.value.show = false
}

function contextAddChild() {
  if (contextMenu.value.nodeId) {
    addNode(contextMenu.value.nodeId, '新节点')
    saveHistory('add-child')
  }
  closeContextMenu()
}

function contextAddSibling() {
  const parentId = graph.value.getParent(contextMenu.value.nodeId)?.id
  if (parentId) {
    addNode(parentId, '新节点')
    saveHistory('add-sibling')
  }
  closeContextMenu()
}

function contextAddParent() {
  if (contextMenu.value.nodeId) {
    addParent(contextMenu.value.nodeId, '新节点')
    saveHistory('add-parent')
  }
  closeContextMenu()
}

function contextEditNode() {
  if (contextMenu.value.nodeId) {
    startEditNode(contextMenu.value.nodeId)
  }
  closeContextMenu()
}

function contextDelete() {
  if (contextMenu.value.nodeId) {
    removeNode(contextMenu.value.nodeId)
    saveHistory('delete-node')
    selectedNodeId.value = null
  }
  closeContextMenu()
}

function contextToggleCollapse() {
  if (contextMenu.value.nodeId) {
    toggleCollapse(contextMenu.value.nodeId)
    saveHistory('toggle-collapse')
  }
  closeContextMenu()
}

// ---- 编辑节点 ----
const editingNodeId = ref<string | null>(null)
const editingLabel = ref('')
const editingDescription = ref('')
const showEditModal = ref(false)

function startEditNode(nodeId: string): void {
  const node = graph.value.getNode(nodeId)
  if (!node) return
  
  editingNodeId.value = nodeId
  editingLabel.value = node.label
  editingDescription.value = node.description || ''
  showEditModal.value = true
}

function finishEditNode(): void {
  if (editingNodeId.value) {
    const label = editingLabel.value.trim() || 'Node'
    const description = editingDescription.value.trim()
    updateNodeData(editingNodeId.value, {
      label,
      description: description || undefined
    })
    // 保存修改后的状态（撤销可回到修改前，重做可回到修改后）
    saveHistory('edit-node')
  }
  closeEditModal()
}

function closeEditModal(): void {
  showEditModal.value = false
  editingNodeId.value = null
  editingLabel.value = ''
  editingDescription.value = ''
}

// ---- 状态 ----
const loading = ref(false)
const saving = ref(false)
const pageTitle = ref('Mind Map')

// ---- 远程同步（Socket.IO） ----
const isSaving = ref(false)
const realtime = useRealtime()

function handlePgUpdate(data: PgUpdateData): void {
  if (isSaving.value) return
  const pagetypeSlug = route.query.pagetype as string
  const pagetype = pagetypeSlug ? slugToPageType(pagetypeSlug) : 'Mind Map'
  if (data.pagetype !== pagetype || data.name !== recordName.value) return
  if (data.modified && data.modified === graph.value.modified) return
  const localData = JSON.stringify(graph.value.serialize())
  const vp = (renderer.value as any)?.getViewport?.()
  getRecord(pagetype, recordName.value).then((result) => {
    if (!result.success || !result.data) return
    const rec = result.data as any
    if (!rec.mindmap_data) return
    const remoteRaw = rec.mindmap_data
    const remoteData = typeof remoteRaw === 'string' ? JSON.parse(remoteRaw) : remoteRaw
    if (JSON.stringify(remoteData) !== localData) {
      const newGraph = GraphModel.deserialize(remoteData)
      newGraph.modified = data.modified || ''
      graph.value = newGraph
      interaction.value?.setGraph(graph.value)
      if (vp) renderer.value?.setViewport?.(vp)
      message.info(t('Content updated by another user.'))
    }
  }).catch(() => {})
}

// ---- 主题配置 ----
const currentThemeId = ref<string>('simple')
const showThemePanel = ref(false)
const customBaseColor = ref('#2a6a4a')
const customThemeName = ref('')
const customSchemeType = ref<ColorSchemeType>('monochromatic')
const customLevelOverrides = ref<Record<number, LevelColorConfig>>({})
const editingLevelIndex = ref<number | null>(null)
const favoriteThemes = ref<ThemeConfig[]>([])
const editingFavoriteThemeId = ref<string | null>(null)

// 打开编辑收藏主题弹窗
function openEditFavoriteTheme(theme: ThemeConfig): void {
  customBaseColor.value = theme.baseColor || '#2a6a4a'
  customThemeName.value = theme.name || ''
  customSchemeType.value = theme.schemeType || 'monochromatic'
  editingFavoriteThemeId.value = theme.id || null
  // 恢复已保存的层级覆盖
  customLevelOverrides.value = {}
  editingLevelIndex.value = null
  showThemePanel.value = true
}

// 删除收藏主题
function deleteFavoriteTheme(themeId: string): void {
  removeFromFavoriteThemes(themeId)
  message.success(t('Theme removed from favorites'))
  favoriteThemes.value = loadFavoriteThemes()
}

function handleThemeSelect(key: string): void {
  const theme = getThemeById(key)
  if (theme) {
    currentThemeId.value = key
    setThemeConfig(theme)
    saveThemeConfig(theme)
    
    // 使用主题配置中的 isDark 属性，如果没有则根据 ID 判断
    const isDark = theme.isDark ?? key.startsWith('dark-')
    currentTheme.value = isDark ? 'dark' : 'light'
  }
}

// 配色理论选项
const schemeOptions = computed(() => [
  { label: t('Monochromatic'), key: 'monochromatic' },
  { label: t('Analogous'), key: 'analogous' },
  { label: t('Complementary'), key: 'complementary' },
  { label: t('Triadic'), key: 'triadic' },
  { label: t('Split-Complementary'), key: 'split-complementary' },
  { label: t('Tetradic'), key: 'tetradic' }
])

function applyCustomTheme(): void {
  const overrides = Object.keys(customLevelOverrides.value).length > 0 ? customLevelOverrides.value : undefined
  const theme = createCustomTheme(customBaseColor.value, customSchemeType.value, overrides)
  currentThemeId.value = theme.id
  setThemeConfig(theme)
  saveThemeConfig(theme)
  
  // 更新亮/暗模式
  currentTheme.value = theme.isDark ? 'dark' : 'light'
  
  // 关闭弹窗
  showThemePanel.value = false
}

// 检查当前自定义主题是否在收藏中
const isCurrentThemeFavorite = computed(() => {
  const theme = renderer.value?.getThemeConfig()
  if (!theme || theme.preset) return false
  return isThemeInFavorites(theme)
})

// 保存当前主题到收藏
function saveCurrentThemeToFavorite(): void {
  // 直接使用面板中的配置创建主题并保存
  const overrides = Object.keys(customLevelOverrides.value).length > 0 ? customLevelOverrides.value : undefined
  const theme = createCustomTheme(customBaseColor.value, customSchemeType.value, overrides)
  const themeName = customThemeName.value.trim() || `Custom (${theme.baseColor})`
  
  const themeWithName = {
    ...theme,
    name: themeName,
    favorite: true
  }
  saveToFavoriteThemes(themeWithName)
  
  // 显示成功提示
  message.success(t('Theme saved to favorites'))
  
  // 清空名称输入
  customThemeName.value = ''
  
  // 刷新收藏列表
  favoriteThemes.value = loadFavoriteThemes()
  
  // 关闭弹窗
  showThemePanel.value = false
}

// 从收藏移除当前主题
function removeCurrentThemeFromFavorite(): void {
  const theme = renderer.value?.getThemeConfig()
  if (!theme) return
  
  removeFromFavoriteThemes(theme.id)
  
  // 刷新收藏列表
  favoriteThemes.value = loadFavoriteThemes()
}

// 设置层级颜色覆盖
function setLevelOverride(index: number, field: keyof LevelColorConfig, value: string): void {
  const current = customLevelOverrides.value[index] || previewColors.value[index]
  customLevelOverrides.value = {
    ...customLevelOverrides.value,
    [index]: { ...current, [field]: value }
  }
}

// 重置层级颜色为自动生成
function resetLevelOverride(index: number): void {
  const newOverrides = { ...customLevelOverrides.value }
  delete newOverrides[index]
  customLevelOverrides.value = newOverrides
}

// 预览自定义主题的颜色（合并层级覆盖）
const previewColors = computed(() => {
  const generated = generateLevelColors(customBaseColor.value, customSchemeType.value)
  return generated.map((c, i) => customLevelOverrides.value[i] || c)
})

// ---- Tooltip ----
const tooltip = ref({
  show: false,
  x: 0,
  y: 0,
  content: ''
})

// ---- 全屏 ----
const isFullscreen = ref(false)
const editorRoot = ref<HTMLElement | null>(null)

// 动态 Teleport 目标：全屏时传送到 fullscreen 元素，非全屏时传送到 body
const modalTeleportTarget = computed(() => {
  if (isFullscreen.value && editorRoot.value) {
    return editorRoot.value  // 返回 DOM 元素引用
  }
  return 'body'
})

function toggleFullscreen(): void {
  const el = editorRoot.value
  if (!el) return
  if (!isFullscreen.value) {
    el.requestFullscreen?.() || el.webkitRequestFullscreen?.()
  } else {
    document.exitFullscreen?.() || document.webkitExitFullscreen?.()
  }
}

function handleFullscreenChange(): void {
  isFullscreen.value = !!(document.fullscreenElement || document.webkitFullscreenElement)
  // 全屏切换后重新计算 Canvas 尺寸
  nextTick(() => {
    resize()
  })
}

// ---- 主题 ----
const currentTheme = ref<'light' | 'dark'>(
  (localStorage.getItem('mindmap-theme') as 'light' | 'dark') || 'light'
)

function setTheme(theme: 'light' | 'dark') {
  currentTheme.value = theme
  localStorage.setItem('mindmap-theme', theme)
}

// ---- 布局选项 ----
const layoutOptions = computed(() => {
  const types = layoutRegistry.getTypes()
  // 布局类型名称映射 - 使用多语言
  const labels: Record<LayoutType, string> = {
    'radial-mindmap': t('Radial Mindmap'),       // 放射思维导图
    'logic-tree': t('Logic Tree'),               // 逻辑树
    'fishbone': t('Fishbone Diagram'),           // 鱼骨图
    'tree': t('Tree Diagram'),                   // 树形图
    'org-chart': t('Organization Chart'),        // 组织结构图
    'timeline-horizontal': t('Horizontal Timeline'), // 横向时间轴
    'timeline-vertical': t('Vertical Timeline'),     // 纵向时间轴
    'force-directed': t('Force-Directed Graph')      // 力导向图
  }
  return types.map(type => ({
    label: labels[type] || type,
    key: type
  }))
})

function handleLayoutChange(key: string): void {
  applyLayout(key as LayoutType)
}

// ---- 键盘快捷键 ----
function handleKeydown(e: KeyboardEvent): void {
  const target = e.target as HTMLElement
  if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') return

  // 选中节点时的快捷键
  if (selectedNodeId.value) {
    switch (e.key) {
      case 'Tab':
        e.preventDefault()
        addNode(selectedNodeId.value, '新节点')
        saveHistory('add-child')
        break
      case 'Enter':
        if (e.shiftKey) {
          // Shift+Enter: 添加父节点
          e.preventDefault()
          const node = graph.value.getNode(selectedNodeId.value)
          if (node && !node.isRoot) {
            addParent(selectedNodeId.value, '新节点')
            saveHistory('add-parent')
          }
        } else {
          // Enter: 添加兄弟节点
          e.preventDefault()
          const parentId = graph.value.getParent(selectedNodeId.value)?.id
          if (parentId) {
            addNode(parentId, '新节点')
            saveHistory('add-sibling')
          }
        }
        break
      case 'Delete':
      case 'Backspace':
        e.preventDefault()
        // 批量删除选中的节点（排除根节点）
        if (selectedNodeIds.value.length > 1) {
          // 多选删除
          const idsToDelete = selectedNodeIds.value.filter(id => 
            !graph.value.getNode(id)?.isRoot
          )
          if (idsToDelete.length > 0) {
            removeNodes(idsToDelete)
            saveHistory('delete-nodes')
            selectedNodeId.value = null
            selectedNodeIds.value = []
          }
        } else if (selectedNodeId.value) {
          // 单选删除
          if (!graph.value.getNode(selectedNodeId.value)?.isRoot) {
            removeNode(selectedNodeId.value)
            saveHistory('delete-node')
            selectedNodeId.value = null
            selectedNodeIds.value = []
          }
        }
        break
      case 'F2':
        // F2: 编辑节点
        e.preventDefault()
        startEditNode(selectedNodeId.value)
        break
    }
  }

  // Ctrl+Z 撤销
  if ((e.ctrlKey || e.metaKey) && e.key === 'z' && !e.shiftKey) {
    e.preventDefault()
    undo()
  }

  // Ctrl+Shift+Z 或 Ctrl+Y 重做
  if ((e.ctrlKey || e.metaKey) && (e.key === 'y' || (e.key === 'z' && e.shiftKey))) {
    e.preventDefault()
    redo()
  }
}

// ---- 生命周期 ----
onMounted(async () => {
  // 加载收藏主题列表
  favoriteThemes.value = loadFavoriteThemes()
  
  // 加载主题配置
  const savedTheme = loadThemeConfig()
  if (savedTheme) {
    currentThemeId.value = savedTheme.id
    setThemeConfig(savedTheme)
    // 使用主题配置中的 isDark 属性，如果没有则根据 ID 判断
    const isDark = savedTheme.isDark ?? savedTheme.id.startsWith('dark-')
    currentTheme.value = isDark ? 'dark' : 'light'
    
    // 如果是自定义主题，恢复基础颜色和配色方案配置
    if (savedTheme.baseColor) {
      customBaseColor.value = savedTheme.baseColor
    }
    if (savedTheme.schemeType) {
      customSchemeType.value = savedTheme.schemeType
    }
  }
  
  await loadData()
  
  // 订阅远程更新
  if (recordName.value) {
    const pagetypeSlug = route.query.pagetype as string
    const pagetype = pagetypeSlug ? slugToPageType(pagetypeSlug) : 'Mind Map'
    realtime.watchDocument(pagetype, recordName.value, { onUpdate: handlePgUpdate })
  }
  
  document.addEventListener('keydown', handleKeydown)
  document.addEventListener('fullscreenchange', handleFullscreenChange)
  document.addEventListener('webkitfullscreenchange', handleFullscreenChange)
  
  // 绑定交互事件
  nextTick(() => {
    if (interaction.value) {
      // 监听节点点击
      interaction.value.on('node:click', (e) => {
        selectedNodeId.value = e.nodeId || null
        // 更新多选状态
        if (e.selectedIds) {
          selectedNodeIds.value = e.selectedIds
          setSelectedNodeIds(e.selectedIds)
        } else {
          selectedNodeIds.value = e.nodeId ? [e.nodeId] : []
          setSelectedNodeId(e.nodeId || null)
        }
        closeContextMenu()
      })
      
      // 监听画布点击
      interaction.value.on('canvas:click', () => {
        selectedNodeId.value = null
        selectedNodeIds.value = []
        setSelectedNodeId(null)
        closeContextMenu()
      })
      
      // 监听框选结束
      interaction.value.on('selection:end', (e) => {
        if (e.selectedIds) {
          selectedNodeIds.value = e.selectedIds
          setSelectedNodeIds(e.selectedIds)
          // 设置主选中节点
          if (e.selectedIds.length > 0) {
            selectedNodeId.value = e.selectedIds[0]
          }
        }
      })
      
      // 监听右键菜单
      interaction.value.on('node:contextmenu', (e) => {
        if (e.nodeId && e.originalEvent) {
          showContextMenu(
            e.originalEvent.clientX,
            e.originalEvent.clientY,
            e.nodeId
          )
        }
      })
      
      // 监听折叠图标点击
      interaction.value.on('node:toggle-collapse', (e) => {
        if (e.nodeId) {
          toggleCollapse(e.nodeId)
        }
      })
      
      // 监听添加子节点按钮点击
      interaction.value.on('node:add-child', (e) => {
        if (e.nodeId) {
          addNode(e.nodeId, '新节点')
          saveHistory('add-child')
        }
      })
      
      // 监听双击编辑
      interaction.value.on('node:dblclick', (e) => {
        if (e.nodeId) {
          startEditNode(e.nodeId)
        }
      })
      
      // 监听节点拖动结束
      interaction.value.on('node:drag:end', (e) => {
        saveHistory('drag-node')
      })
      
      // 监听描述图标悬浮
      interaction.value.on('description:hover', (e) => {
        if (e.description && e.originalEvent) {
          tooltip.value = {
            show: true,
            x: e.originalEvent.clientX,
            y: e.originalEvent.clientY,
            content: e.description
          }
        } else {
          tooltip.value.show = false
        }
      })
    }
  })
})

onUnmounted(() => {
  document.removeEventListener('keydown', handleKeydown)
  document.removeEventListener('fullscreenchange', handleFullscreenChange)
  document.removeEventListener('webkitfullscreenchange', handleFullscreenChange)
})

// ---- 加载数据 ----
async function loadData(): Promise<void> {
  // 等待 DOM 渲染完成
  await nextTick()
  
  if (!recordName.value) {
    // 没有记录 ID，创建默认图
    if (canvasRef.value) {
      initCanvas(canvasRef.value, null)
      // 初始化历史记录
      saveHistory('initial-load')
      // 延迟居中显示
      setTimeout(() => fitView(), 150)
    }
    return
  }

  loading.value = true
  try {
    const pagetypeSlug = route.query.pagetype as string
    const pagetype = pagetypeSlug ? slugToPageType(pagetypeSlug) : 'Mind Map'
    const result = await getRecord(pagetype, recordName.value)
    if (result.success && result.data) {
      const rec = result.data
      pageTitle.value = rec.name || rec.title || 'Mind Map'
      
      // 解析数据
      let mindmapData: SerializedGraph | null = null
      if (rec.mindmap_data) {
        try {
          mindmapData = typeof rec.mindmap_data === 'string' 
            ? JSON.parse(rec.mindmap_data) 
            : rec.mindmap_data
        } catch (e) {
          console.error('Failed to parse mindmap data:', e)
        }
      }
      
      // 初始化 Canvas
      if (canvasRef.value) {
        const needsFitView = initCanvas(canvasRef.value, mindmapData)
        graph.value.modified = (rec as any).modified || ''
        // 初始化历史记录（加载后保存初始状态）
        saveHistory('initial-load')
        // 只有在需要时才调用适应画布
        if (needsFitView) {
          requestAnimationFrame(() => {
            requestAnimationFrame(() => {
              fitView()
            })
          })
        }
      }
    } else {
      message.error(result.message || t('Failed to load mind map'))
    }
  } catch (e: any) {
    message.error(t('Failed to load') + ': ' + (e.message || t('Unknown error')))
  } finally {
    loading.value = false
  }
}

// ---- 保存数据 ----
async function saveData(): Promise<void> {
  if (!recordName.value) {
    message.warning(t('Cannot save: record name not specified'))
    return
  }
  saving.value = true
  isSaving.value = true
  try {
    const flowData = exportData()
    const pagetypeSlug = route.query.pagetype as string
    const pagetype = pagetypeSlug ? slugToPageType(pagetypeSlug) : 'Mind Map'
    // 直接传递对象，不要 JSON.stringify，因为后端 JSON 字段会自动处理
    const result = await updateRecord(pagetype, recordName.value, {
      mindmap_data: flowData
    })
    if (result.success) {
      if (result.data?.modified) {
        graph.value.modified = result.data.modified
      }
      message.success(t('Saved successfully'))
    } else {
      message.error(result.message || t('Failed to save'))
    }
  } catch (e: any) {
    message.error(t('Failed to save') + ': ' + (e.message || t('Unknown error')))
  } finally {
    saving.value = false
    isSaving.value = false
  }
}

// ---- 返回 ----
function goBack(): void {
  router.back()
}

// ---- 适应视图 ----
function handleFitView(): void {
  fitView()
}

// ---- 自动布局 ----
function handleAutoLayout(): void {
  applyLayout()
  saveHistory('auto-layout')
}
</script>

<template>
  <div 
    class="mindmap-editor" 
    :class="{ 
      fullscreen: isFullscreen, 
      'dark-theme': currentTheme === 'dark' 
    }" 
    ref="editorRoot"
  >
    <!-- 顶部工具栏 -->
    <div class="mindmap-toolbar">
      <div class="mindmap-toolbar__left">
        <n-button
          quaternary
          size="small"
          @click="goBack"
          class="toolbar-btn"
          :title="t('Back')"
        >
          <i class="fa fa-arrow-left"></i>
          <span class="btn-text">{{ t('Back') }}</span>
        </n-button>
        <div class="mindmap-title">
          <i class="fa fa-sitemap" style="color: #6366f1; margin-right: 8px;"></i>
          <span>{{ pageTitle }}</span>
        </div>
      </div>

      <div class="mindmap-toolbar__right">
        <n-space :size="6" align="center">
          <!-- 撤销/重做按钮 -->
          <n-button
            quaternary
            size="small"
            type="default"
            class="toolbar-btn"
            :disabled="!canUndo"
            :title="t('Undo') + ' (Ctrl+Z)'"
            @click="undo"
          >
            <template #icon>
              <n-icon><Icon icon="tabler:arrow-back-up" /></n-icon>
            </template>
          </n-button>
          <n-button
            quaternary
            size="small"
            type="default"
            class="toolbar-btn"
            :disabled="!canRedo"
            :title="t('Redo') + ' (Ctrl+Y)'"
            @click="redo"
          >
            <template #icon>
              <n-icon><Icon icon="tabler:arrow-forward-up" /></n-icon>
            </template>
          </n-button>

          <div class="toolbar-divider"></div>

          <n-button
            quaternary
            size="small"
            type="info"
            class="toolbar-btn"
            :title="t('Organize Layout')"
            @click="handleAutoLayout"
          >
            <i class="fa fa-magic"></i>
            <span class="btn-text">{{ t('Organize Layout') }}</span>
          </n-button>

          <n-button
            quaternary
            size="small"
            type="default"
            class="toolbar-btn"
            :title="t('Fit View')"
            @click="handleFitView"
          >
            <template #icon>
              <n-icon><Icon icon="tabler:arrows-maximize" /></n-icon>
            </template>
            <span class="btn-text">{{ t('Fit View') }}</span>
          </n-button>

          <n-button
            quaternary
            size="small"
            type="default"
            class="toolbar-btn"
            :title="isFullscreen ? t('Exit Fullscreen') : t('Fullscreen')"
            @click="toggleFullscreen"
          >
            <template #icon>
              <n-icon><Icon :icon="isFullscreen ? 'tabler:arrows-minimize' : 'tabler:maximize'" /></n-icon>
            </template>
            <span class="btn-text">{{ isFullscreen ? t('Exit Fullscreen') : t('Fullscreen') }}</span>
          </n-button>

          <div class="toolbar-divider"></div>

          <!-- 布局选择 -->
          <n-dropdown
            trigger="click"
            :options="layoutOptions"
            @select="handleLayoutChange"
          >
            <n-button
              quaternary
              size="small"
              class="toolbar-btn"
              :title="t('Switch Layout')"
            >
              <i class="fa fa-sitemap"></i>
              <span class="btn-text">{{ t('Layout') }}</span>
            </n-button>
          </n-dropdown>

          <!-- 主题选择 -->
          <n-popover
            trigger="click"
            placement="bottom-start"
            :show-arrow="false"
            content-style="padding: 4px 0; min-width: 240px;"
          >
            <template #trigger>
              <n-button
                quaternary
                size="small"
                class="toolbar-btn"
                :title="t('Switch Theme')"
              >
                <i class="fa fa-palette"></i>
                <span class="btn-text">{{ t('Theme') }}</span>
              </n-button>
            </template>
            <div class="theme-menu">
              <!-- 系统主题 -->
              <div class="theme-menu-group">{{ t('System') }}</div>
              <div
                v-for="theme in SYSTEM_THEMES"
                :key="theme.id"
                class="theme-menu-item"
                :class="{ active: currentThemeId === theme.id }"
                @click="handleThemeSelect(theme.id)"
              >
                {{ t(theme.name) }}
              </div>
              
              <!-- 收藏主题 -->
              <template v-if="favoriteThemes.length > 0">
                <div class="theme-menu-divider"></div>
                <div class="theme-menu-group">{{ t('Favorites') }}</div>
                <div
                  v-for="theme in favoriteThemes"
                  :key="theme.id"
                  class="theme-menu-item theme-item-with-actions"
                  :class="{ active: currentThemeId === theme.id }"
                >
                  <span class="theme-item-label" @click="handleThemeSelect(theme.id)">
                    {{ t(theme.name || 'Custom') }}
                  </span>
                  <span class="theme-item-actions">
                    <n-icon
                      class="theme-item-action"
                      size="14"
                      :title="t('Edit')"
                      @click.stop="openEditFavoriteTheme(theme)"
                    >
                      <Icon icon="tabler:edit" />
                    </n-icon>
                    <n-icon
                      class="theme-item-action theme-item-delete"
                      size="14"
                      :title="t('Delete')"
                      @click.stop="deleteFavoriteTheme(theme.id!)"
                    >
                      <Icon icon="tabler:trash" />
                    </n-icon>
                  </span>
                </div>
              </template>
              
              <!-- 自定义主题 -->
              <div class="theme-menu-divider"></div>
              <div class="theme-menu-item" @click="showThemePanel = true">
                {{ t('Custom Theme') }}
              </div>
            </div>
          </n-popover>

          <div class="toolbar-divider"></div>

          <n-button
            size="small"
            class="save-btn-brand"
            :loading="saving"
            :disabled="saving"
            :title="t('Save')"
            @click="saveData"
          >
            <template #icon>
              <n-icon><Icon icon="tabler:check" /></n-icon>
            </template>
            <span class="btn-text">{{ saving ? t('Saving...') : t('Save') }}</span>
          </n-button>
        </n-space>
      </div>
    </div>

    <!-- 加载遮罩 -->
    <div v-if="loading" class="mindmap-loading">
      <i class="fa fa-spinner fa-spin"></i>
      <p>{{ t('Loading mind map...') }}</p>
    </div>

    <!-- Canvas 画布 -->
    <div class="mindmap-canvas">
      <canvas ref="canvasRef" class="mind-map-canvas"></canvas>
    </div>

    <!-- 缩放控制 -->
    <div class="zoom-controls">
      <button class="zoom-btn" @click="zoomIn" title="放大">+</button>
      <button class="zoom-btn" @click="resetZoom" title="重置">⟲</button>
      <button class="zoom-btn" @click="zoomOut" title="缩小">−</button>
    </div>

    <!-- 右键菜单 -->
    <div
      v-if="contextMenu.show"
      class="context-menu"
      :style="{ left: contextMenu.x + 'px', top: contextMenu.y + 'px' }"
      @click.stop
    >
      <div class="context-menu__item" @click="contextEditNode">
        <i class="fa fa-edit"></i>
        <span>{{ t('Edit Node') }}</span>
        <span class="shortcut">F2</span>
      </div>
      <div class="context-menu__divider"></div>
      <div class="context-menu__item" @click="contextAddChild">
        <i class="fa fa-plus"></i>
        <span>{{ t('Add Child Node') }}</span>
        <span class="shortcut">Tab</span>
      </div>
      <div class="context-menu__item" @click="contextAddSibling">
        <i class="fa fa-share"></i>
        <span>{{ t('Add Sibling Node') }}</span>
        <span class="shortcut">Enter</span>
      </div>
      <div v-if="contextCanAddParent" class="context-menu__item" @click="contextAddParent">
        <i class="fa fa-level-up"></i>
        <span>{{ t('Add Parent Node') }}</span>
        <span class="shortcut">Shift+Enter</span>
      </div>
      <div class="context-menu__divider"></div>
      <div v-if="contextNodeHasChildren" class="context-menu__item" @click="contextToggleCollapse">
        <i :class="contextNodeCollapsed ? 'fa fa-expand' : 'fa fa-compress'"></i>
        <span>{{ contextNodeCollapsed ? t('Expand') : t('Collapse') }}</span>
      </div>
      <div v-if="contextNodeHasChildren" class="context-menu__divider"></div>
      <div class="context-menu__item context-menu__item--danger" @click="contextDelete">
        <i class="fa fa-trash"></i>
        <span>{{ t('Delete Node') }}</span>
        <span class="shortcut">Del</span>
      </div>
    </div>
    
    <!-- 编辑节点弹窗 -->
    <Teleport :to="modalTeleportTarget">
      <div v-if="showEditModal" class="custom-modal-overlay" @click.self="closeEditModal">
        <div class="custom-modal-content">
          <div class="custom-modal-header">
            <h3>{{ t('Edit Node') }}</h3>
          </div>
          <div class="custom-modal-body">
            <div class="form-item">
              <label>{{ t('Title') }}</label>
              <n-input
                v-model:value="editingLabel"
                :placeholder="t('Enter title')"
                @keydown.enter.prevent
              />
            </div>
            <div class="form-item">
              <label>{{ t('Description') }}</label>
              <n-input
                v-model:value="editingDescription"
                type="textarea"
                :placeholder="t('Enter description (optional)')"
                :rows="3"
                :autosize="{ minRows: 2, maxRows: 6 }"
              />
            </div>
          </div>
          <div class="custom-modal-footer">
            <n-button @click="closeEditModal">{{ t('Cancel') }}</n-button>
            <n-button type="primary" @click="finishEditNode">{{ t('Save') }}</n-button>
          </div>
        </div>
      </div>
    </Teleport>
    
    <!-- 自定义主题面板 -->
    <Teleport :to="modalTeleportTarget">
      <div v-if="showThemePanel" class="custom-modal-overlay" @click.self="showThemePanel = false">
        <div class="custom-modal-content custom-modal-card">
          <div class="custom-modal-header">
            <h3>{{ t('Custom Theme') }}</h3>
          </div>
          <div class="custom-modal-body">
        <!-- 主题名称 -->
        <div class="theme-row">
          <label class="theme-label">{{ t('Theme Name') }}</label>
          <n-input
            v-model:value="customThemeName"
            placeholder=""
            clearable
            style="width: 200px"
          />
        </div>
        
        <!-- 基础颜色选择 -->
        <div class="theme-row">
          <label class="theme-label">{{ t('Base Color') }}</label>
          <n-color-picker
            v-model:value="customBaseColor"
            :show-alpha="false"
            :modes="['hex']"
            :to="false"
          />
        </div>
        
        <!-- 配色理论选择 -->
        <div class="theme-row">
          <label class="theme-label">{{ t('Color Scheme') }}</label>
          <n-dropdown
            trigger="click"
            :options="schemeOptions"
            @select="(key: string) => customSchemeType = key as ColorSchemeType"
            :to="false"
          >
            <n-button>
              {{ schemeOptions.find(o => o.key === customSchemeType)?.label }}
              <i class="fa fa-chevron-down" style="margin-left: 8px"></i>
            </n-button>
          </n-dropdown>
        </div>
        
        <!-- 层级颜色编辑 -->
        <div class="theme-preview">
          <label class="theme-label">{{ t('Level Colors') }}</label>
          <div class="color-preview">
            <div
              v-for="(color, index) in previewColors"
              :key="index"
              class="color-swatch clickable"
              :class="{ 'is-overridden': customLevelOverrides[index], 'is-editing': editingLevelIndex === index }"
              :style="{
                backgroundColor: color.fill === 'transparent' ? '#fff' : color.fill,
                borderColor: color.stroke,
                color: color.color
              }"
              @click="editingLevelIndex = editingLevelIndex === index ? null : index"
            >
              {{ t('Level') }} {{ index }}
              <span v-if="customLevelOverrides[index]" class="override-dot" />
            </div>
          </div>
          <!-- 展开的层级编辑器 -->
          <div v-if="editingLevelIndex !== null" class="level-editor">
            <div class="level-editor-header">
              <span>{{ t('Level') }} {{ editingLevelIndex }}</span>
              <n-button v-if="customLevelOverrides[editingLevelIndex]" text size="tiny" @click="resetLevelOverride(editingLevelIndex)">
                {{ t('Reset') }}
              </n-button>
            </div>
            <div class="level-editor-row">
              <label>{{ t('Fill') }}</label>
              <n-color-picker
                :value="previewColors[editingLevelIndex]?.fill || '#64748b'"
                :show-alpha="false"
                :modes="['hex']"
                :to="false"
                @update:value="(v: string) => setLevelOverride(editingLevelIndex, 'fill', v)"
              />
            </div>
            <div class="level-editor-row">
              <label>{{ t('Stroke') }}</label>
              <n-color-picker
                :value="previewColors[editingLevelIndex]?.stroke || '#94a3b8'"
                :show-alpha="false"
                :modes="['hex']"
                :to="false"
                @update:value="(v: string) => setLevelOverride(editingLevelIndex, 'stroke', v)"
              />
            </div>
            <div class="level-editor-row">
              <label>{{ t('Text') }}</label>
              <n-color-picker
                :value="previewColors[editingLevelIndex]?.color || '#ffffff'"
                :show-alpha="false"
                :modes="['hex']"
                :to="false"
                @update:value="(v: string) => setLevelOverride(editingLevelIndex, 'color', v)"
              />
            </div>
          </div>
        </div>
        
        <n-divider />
        <n-space vertical>
          <n-button class="save-btn-brand" block @click="applyCustomTheme">
            <template #icon>
              <n-icon><Icon icon="tabler:check" /></n-icon>
            </template>
            {{ t('Apply Theme') }}
          </n-button>
          <n-button 
            quaternary 
            block 
            @click="saveCurrentThemeToFavorite"
          >
            <template #icon>
              <n-icon><Icon icon="tabler:star" /></n-icon>
            </template>
            {{ t('Save to Favorites') }}
          </n-button>
        </n-space>
          </div>
        </div>
      </div>
    </Teleport>
    
    <!-- 描述 Tooltip -->
    <div
      v-if="tooltip.show"
      class="description-tooltip"
      :style="{ left: tooltip.x + 'px', top: tooltip.y + 'px' }"
    >
      {{ tooltip.content }}
    </div>
  </div>
</template>

<style scoped>
.mindmap-editor {
  display: flex;
  flex-direction: column;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: #f8fafc;
  overflow: hidden;
  transition: background-color 0.3s ease;
}

.mindmap-editor.dark-theme {
  background: #1e293b;
}

.mindmap-editor.fullscreen {
  position: fixed !important;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100vw;
  height: 100vh;
  z-index: 99999;
}

/* ---- 自定义 Modal 样式 ---- */
.custom-modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100000;
}

.custom-modal-content {
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
  min-width: 400px;
  max-width: 90vw;
  max-height: 90vh;
  overflow: auto;
}

.custom-modal-card {
  min-width: 500px;
}

.custom-modal-header {
  padding: 16px 20px;
  border-bottom: 1px solid #e2e8f0;
}

.custom-modal-header h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #1e293b;
}

.custom-modal-body {
  padding: 20px;
}

.custom-modal-body .form-item {
  margin-bottom: 16px;
}

.custom-modal-body .form-item:last-child {
  margin-bottom: 0;
}

.custom-modal-body .form-item label {
  display: block;
  margin-bottom: 8px;
  font-size: 14px;
  color: #475569;
}

.custom-modal-footer {
  padding: 16px 20px;
  border-top: 1px solid #e2e8f0;
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

/* ---- 工具栏 ---- */
.mindmap-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 16px;
  background: #ffffff;
  border-bottom: 1px solid #e2e8f0;
  flex-shrink: 0;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
  z-index: 10;
}

.mindmap-toolbar__left {
  display: flex;
  align-items: center;
  gap: 12px;
}

.mindmap-toolbar__right {
  display: flex;
  align-items: center;
}

.mindmap-title {
  font-size: 15px;
  font-weight: 600;
  color: #1e293b;
  display: flex;
  align-items: center;
}

.toolbar-btn {
  border-radius: 6px !important;
  color: #64748b !important;
}

.toolbar-btn i {
  margin-right: 5px;
}

.toolbar-divider {
  width: 1px;
  height: 20px;
  background: #e2e8f0;
  margin: 0 4px;
}

.save-btn {
  background: #22c55e !important;
  border: none !important;
  color: #fff !important;
}

.save-btn:hover {
  background: #16a34a !important;
}

/* ---- 加载 ---- */
.mindmap-loading {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: #ffffff;
  opacity: 0.95;
  z-index: 100;
  gap: 12px;
  color: #64748b;
  font-size: 15px;
}

.dark-theme .mindmap-loading {
  background: #1e293b;
  color: #94a3b8;
}

.mindmap-loading i {
  font-size: 28px;
}

/* ---- 画布 ---- */
.mindmap-canvas {
  flex: 1;
  position: relative;
  overflow: hidden;
}

.mind-map-canvas {
  display: block;
  width: 100%;
  height: 100%;
}

/* ---- 缩放控制 ---- */
.zoom-controls {
  position: absolute;
  bottom: 20px;
  right: 20px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  background: #ffffff;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  padding: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.zoom-btn {
  width: 32px;
  height: 32px;
  border: none;
  background: transparent;
  color: #64748b;
  font-size: 16px;
  cursor: pointer;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.zoom-btn:hover {
  background: #f1f5f9;
  color: #0f766e;
}

/* ---- 响应式 ---- */
@media (max-width: 600px) {
  .btn-text {
    display: none;
  }

  .mindmap-toolbar {
    padding: 8px 10px;
  }
}

/* ---- 右键菜单 ---- */
.context-menu {
  position: fixed;
  background: #ffffff;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  z-index: 9999;
  min-width: 160px;
  overflow: hidden;
}

.dark-theme .context-menu {
  background: #334155;
  border-color: #475569;
}

.context-menu__item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  font-size: 13px;
  color: #1e293b;
  cursor: pointer;
  transition: background 0.15s;
}

.dark-theme .context-menu__item {
  color: #f1f5f9;
}

.context-menu__item:hover {
  background: #f1f5f9;
}

.dark-theme .context-menu__item:hover {
  background: #475569;
}

.context-menu__item i {
  width: 16px;
  text-align: center;
  color: #0f766e;
}

.context-menu__item span:first-of-type {
  flex: 1;
}

.context-menu__item .shortcut {
  font-size: 11px;
  color: #64748b;
  background: #f1f5f9;
  padding: 2px 6px;
  border-radius: 4px;
}

.dark-theme .context-menu__item .shortcut {
  background: #475569;
  color: #94a3b8;
}

.context-menu__divider {
  height: 1px;
  background: #e2e8f0;
  margin: 4px 0;
}

.dark-theme .context-menu__divider {
  background: #475569;
}

.context-menu__item--danger {
  color: #ef4444;
}

.context-menu__item--danger i {
  color: #ef4444;
}

.context-menu__item--danger:hover {
  background: rgba(239, 68, 68, 0.1);
}

/* ---- 编辑输入框 ---- */
.edit-input {
  position: absolute;
  z-index: 1000;
  padding: 0 12px;
  font-size: 14px;
  border: 2px solid #6366f1;
  border-radius: 8px;
  background: #ffffff;
  color: #1e293b;
  outline: none;
  text-align: center;
  box-shadow: 0 2px 8px rgba(99, 102, 241, 0.3);
}

.dark-theme .edit-input {
  background: #334155;
  color: #f1f5f9;
  border-color: #818cf8;
}

/* ---- 描述 Tooltip ---- */
.description-tooltip {
  position: fixed;
  z-index: 10000;
  max-width: 280px;
  padding: 8px 12px;
  font-size: 13px;
  line-height: 1.5;
  color: #1e293b;
  background: #ffffff;
  border: 1px solid #e2e8f0;
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  transform: translate(16px, 16px);
  pointer-events: none;
}

.dark-theme .description-tooltip {
  color: #f1f5f9;
  background: #334155;
  border-color: #475569;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

/* ---- 主题面板 ---- */
.theme-panel {
  padding: 0 4px;
}

.theme-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
}

.theme-label {
  font-size: 14px;
  font-weight: 500;
  color: #1e293b;
}

.dark-theme .theme-label {
  color: #f1f5f9;
}

.theme-preview {
  margin-top: 20px;
}

.theme-preview .theme-label {
  display: block;
  margin-bottom: 12px;
}

.color-preview {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.color-swatch {
  padding: 8px 12px;
  border-radius: 6px;
  border-width: 2px;
  border-style: solid;
  font-size: 12px;
  font-weight: 500;
  min-width: 60px;
  text-align: center;
  transition: transform 0.2s;
  position: relative;
}

.color-swatch.clickable {
  cursor: pointer;
}

.color-swatch.clickable:hover {
  transform: scale(1.05);
}

.color-swatch.is-editing {
  outline: 2px solid #3b82f6;
  outline-offset: 1px;
}

.color-swatch.is-overridden .override-dot {
  position: absolute;
  top: 3px;
  right: 3px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #3b82f6;
}

.level-editor {
  margin-top: 8px;
  padding: 10px 12px;
  background: #f8fafc;
  border-radius: 8px;
  border: 1px solid #e2e8f0;
}

.level-editor-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  font-size: 13px;
  font-weight: 500;
}

.level-editor-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
}

.level-editor-row:last-child {
  margin-bottom: 0;
}

.level-editor-row label {
  font-size: 12px;
  color: #64748b;
  min-width: 40px;
}

/* ---- 保存按钮品牌风格 ---- */
.save-btn-brand {
  background: #e6f8f0 !important;
  border: 1px solid #1fc76f !important;
  color: #0d684b !important;
}

.save-btn-brand :deep(.n-button__border) {
  border: none !important;
  border-color: transparent !important;
}

.save-btn-brand :deep(.n-button__state-border) {
  border: none !important;
  border-color: transparent !important;
}

.save-btn-brand:hover {
  background: #dcfce7 !important;
  border-color: #1fc76f !important;
  border: 1px solid #1fc76f !important;
  color: #166534 !important;
  box-shadow: 0 2px 8px rgba(31, 199, 111, 0.15) !important;
}

.save-btn-brand:hover :deep(.n-button__border),
.save-btn-brand:hover :deep(.n-button__state-border) {
  border: none !important;
  border-color: transparent !important;
}

.save-btn-brand:active {
  background: #1fc76f !important;
  border-color: #1fc76f !important;
  border: 1px solid #1fc76f !important;
  color: white !important;
  box-shadow: 0 1px 4px rgba(31, 199, 111, 0.2) !important;
}

.save-btn-brand:active :deep(.n-button__border),
.save-btn-brand:active :deep(.n-button__state-border) {
  border: none !important;
  border-color: transparent !important;
}

/* ---- 主题菜单样式 ---- */
.theme-menu {
  min-width: 220px;
}

.theme-menu-group {
  padding: 8px 12px 4px;
  font-size: 11px;
  font-weight: 600;
  color: #94a3b8;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.theme-menu-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px;
  cursor: pointer;
  transition: background 0.15s;
  font-size: 13px;
  color: #334155;
}

.theme-menu-item:hover {
  background: #f1f5f9;
}

.theme-menu-item.active {
  color: #0f766e;
  font-weight: 500;
}

.theme-menu-divider {
  height: 1px;
  background: #e2e8f0;
  margin: 4px 0;
}

/* 收藏主题行 */
.theme-item-with-actions {
  padding-right: 8px;
}

.theme-item-label {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.theme-item-actions {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-left: 8px;
  flex-shrink: 0;
}

.theme-item-action {
  opacity: 0;
  transition: opacity 0.2s, color 0.2s;
  padding: 4px;
  border-radius: 4px;
  color: #94a3b8;
  cursor: pointer;
}

.theme-item-action:hover {
  color: #0f766e;
  background: #e2e8f0;
}

.theme-item-action.theme-item-delete:hover {
  color: #ef4444;
  background: #fee2e2;
}

/* 悬浮时显示操作图标 */
.theme-menu-item:hover .theme-item-action {
  opacity: 1;
}
</style>
