<script setup>
import { ref, reactive, computed, onMounted, onBeforeUnmount, nextTick, markRaw } from 'vue'
import { NPopover, NIcon } from 'naive-ui'
import {
  SmilingFace,
  Pic,
  FolderUpload
} from '@icon-park/vue-next'
import { bus } from '@/utils/event-bus'
import { EditorConst } from '@/constant/event-bus'
import { emitCall } from '@/utils/common'
import { deltaToMessage, deltaToString, isEmptyDelta } from './util'
import { useDialogueStore, useEditorDraftStore } from '@/store'
import { uploadImg } from '@/api/upload'
import { defAvatar } from '@/constant/default'
import { getImageInfo } from '@/utils/functions'
import MeEditorEmoticon from './MeEditorEmoticon.vue'

const props = defineProps({
  vote: {
    type: Boolean,
    default: false
  },
  members: {
    type: Array,
    default: () => []
  }
})

const emit = defineEmits(['editor-event'])

// 响应式数据
const editorRef = ref(null)
const content = ref('')
const isFocused = ref(false)
const showMention = ref(false)
const mentionQuery = ref('')
const mentionPosition = ref({ top: 0, left: 0 })
const selectedMentionIndex = ref(0)
const quoteData = ref(null)
const editingMessage = ref(null)
const isShowEmoticon = ref(false)

const fileImageRef = ref(null)
const uploadFileRef = ref(null)
const emoticonRef = ref(null)

// 获取状态管理
const dialogueStore = useDialogueStore()
const editorDraftStore = useEditorDraftStore()

// 工具栏配置
const navs = reactive([
  {
    title: '图片',
    icon: markRaw(Pic),
    show: true,
    click: () => {
      fileImageRef.value.click()
    }
  },
  {
    title: '文件',
    icon: markRaw(FolderUpload),
    show: true,
    click: () => {
      uploadFileRef.value.click()
    }
  }
])

const mentionList = ref([])
const currentMentionQuery = ref('')

// 编辑器内容
const editorContent = ref('')
const editorHtml = ref('')

// 工具栏配置
const toolbarConfig = computed(() => {
  const config = [
    { type: 'emoticon', icon: 'icon-biaoqing', title: '表情' },
    { type: 'image', icon: 'icon-image', title: '图片' },
    { type: 'file', icon: 'icon-folder-plus', title: '文件' }
  ]
  
  return config
})

// 处理输入事件
const handleInput = (event) => {
  const target = event.target
  editorContent.value = target.textContent || ''
  editorHtml.value = target.innerHTML || ''
  
  // 检查@mention
  checkMention(target)
  
  // 发送输入事件
  emit('editor-event', {
    event: 'input_event',
    data: editorContent.value
  })
}

// 检查@mention
const checkMention = (target) => {
  const selection = window.getSelection()
  if (!selection.rangeCount) return
  
  const range = selection.getRangeAt(0)
  const textBeforeCursor = range.startContainer.textContent?.substring(0, range.startOffset) || ''
  const mentionMatch = textBeforeCursor.match(/@([^@\s]*)$/)
  
  if (mentionMatch) {
    currentMentionQuery.value = mentionMatch[1]
    showMentionList()
    updateMentionPosition(range)
  } else {
    hideMentionList()
  }
}

// 显示mention列表
const showMentionList = () => {
  const query = currentMentionQuery.value.toLowerCase()
  mentionList.value = props.members.filter(member => 
    member.nickname.toLowerCase().includes(query)
  ).slice(0, 10)
  
  showMention.value = mentionList.value.length > 0
  selectedMentionIndex.value = 0
}

// 隐藏mention列表
const hideMentionList = () => {
  showMention.value = false
  mentionList.value = []
  currentMentionQuery.value = ''
}

// 更新mention位置
const updateMentionPosition = (range) => {
  const rect = range.getBoundingClientRect()
  const editorRect = editorRef.value.getBoundingClientRect()
  
  mentionPosition.value = {
    top: rect.bottom - editorRect.top + 5,
    left: rect.left - editorRect.left
  }
}

// 插入mention
const insertMention = (member) => {
  const selection = window.getSelection()
  if (!selection.rangeCount) return
  
  const range = selection.getRangeAt(0)
  const textNode = range.startContainer
  const offset = range.startOffset
  
  // 找到@符号的位置
  const textContent = textNode.textContent || ''
  const atIndex = textContent.lastIndexOf('@', offset - 1)
  
  if (atIndex !== -1) {
    // 创建mention元素
    const mentionSpan = document.createElement('span')
    mentionSpan.className = 'mention'
    mentionSpan.setAttribute('data-user-id', member.user_id)
    mentionSpan.textContent = `@${member.nickname}`
    mentionSpan.contentEditable = 'false'
    
    // 替换文本
    const beforeText = textContent.substring(0, atIndex)
    const afterText = textContent.substring(offset)
    
    // 创建新的文本节点
    const beforeNode = document.createTextNode(beforeText)
    const afterNode = document.createTextNode(' ' + afterText)
    
    // 替换内容
    const parent = textNode.parentNode
    parent.insertBefore(beforeNode, textNode)
    parent.insertBefore(mentionSpan, textNode)
    parent.insertBefore(afterNode, textNode)
    parent.removeChild(textNode)
    
    // 设置光标位置
    const newRange = document.createRange()
    newRange.setStartAfter(mentionSpan)
    newRange.collapse(true)
    selection.removeAllRanges()
    selection.addRange(newRange)
  }
  
  hideMentionList()
  editorRef.value.focus()
}

// 处理粘贴事件
const handlePaste = (event) => {
  event.preventDefault()
  
  // 获取粘贴的纯文本内容
  const text = event.clipboardData?.getData('text/plain') || ''
  
  if (text) {
    // 插入纯文本，移除所有样式
    const selection = window.getSelection()
    if (selection && selection.rangeCount > 0) {
      const range = selection.getRangeAt(0)
      range.deleteContents()
      range.insertNode(document.createTextNode(text))
      range.collapse(false)
      selection.removeAllRanges()
      selection.addRange(range)
      
      // 触发输入事件
      handleInput({ target: editorRef.value })
    }
  }
}

// 处理键盘事件
const handleKeydown = (event) => {
  // 处理@提及列表的键盘导航
  if (showMention.value) {
    switch (event.key) {
      case 'ArrowUp':
        event.preventDefault()
        selectedMentionIndex.value = Math.max(0, selectedMentionIndex.value - 1)
        break
      case 'ArrowDown':
        event.preventDefault()
        selectedMentionIndex.value = Math.min(mentionList.value.length - 1, selectedMentionIndex.value + 1)
        break
      case 'Enter':
      case 'Tab':
        event.preventDefault()
        if (mentionList.value[selectedMentionIndex.value]) {
          insertMention(mentionList.value[selectedMentionIndex.value])
        }
        break
      case 'Escape':
        hideMentionList()
        break
    }
    return
  }
  
  // 处理Enter键发送消息
  if (event.key === 'Enter' && !event.shiftKey) {
    event.preventDefault()
    // 确保编辑器内容不为空
    if (editorContent.value.trim() || editorHtml.value.includes('<img') || editorHtml.value.includes('editor-file')) {
      sendMessage()
    }
  }
}

// 发送消息
const sendMessage = () => {
  // 检查编辑器是否有内容：文本、图片
  if (!editorContent.value.trim() && !editorHtml.value.includes('<img') && !editorHtml.value.includes('editor-file')) {
    return
  }
  
  const messageData = parseEditorContent()
  
  if (editingMessage.value) {
    // 编辑消息
    emit('editor-event', {
      event: 'edit_message',
      data: {
        ...messageData,
        msg_id: editingMessage.value.msg_id
      },
      callBack: (success) => {
        if (success) {
          clearEditor()
          editingMessage.value = null
        }
      }
    })
  } else {
    // 发送新消息
    const eventType = messageData.items.length > 1 ? 'mixed_event' : 
                     messageData.items[0].type === 'text' ? 'text_event' : 
                     messageData.items[0].type + '_event'
    
    emit('editor-event', {
      event: eventType,
      data: messageData,
      callBack: (success) => {
        if (success) {
          clearEditor()
        }
      }
    })
  }
}

// 解析编辑器内容
const parseEditorContent = () => {
  const items = []
  const mentionUids = []
  
  // 解析HTML内容
  const tempDiv = document.createElement('div')
  tempDiv.innerHTML = editorHtml.value
  
  let textContent = ''
  const nodes = Array.from(tempDiv.childNodes)
  
  nodes.forEach(node => {
    if (node.nodeType === Node.TEXT_NODE) {
      textContent += node.textContent
    } else if (node.nodeType === Node.ELEMENT_NODE) {
      if (node.classList.contains('mention')) {
        const userId = node.getAttribute('data-user-id')
        if (userId) {
          mentionUids.push(parseInt(userId))
        }
        textContent += node.textContent
      } else if (node.tagName === 'IMG') {
        // 处理图片
        const src = node.getAttribute('src')
        const width = node.getAttribute('width') || ''
        const height = node.getAttribute('height') || ''
        
        if (textContent.trim()) {
          items.push({
            type: 'text',
            content: textContent.trim()
          })
          textContent = ''
        }
        
        items.push({
          type: 'image',
          content: src + (width && height ? `?width=${width}&height=${height}` : '')
        })
      } else if (node.classList.contains('emoji')) {
        textContent += node.getAttribute('alt') || node.textContent
      } else if (node.classList.contains('editor-file')) {
        // 处理文件
        const fileUrl = node.getAttribute('data-url')
        const fileName = node.getAttribute('data-name')
        const fileSize = node.getAttribute('data-size')
        
        if (textContent.trim()) {
          items.push({
            type: 'text',
            content: textContent.trim()
          })
          textContent = ''
        }
        
        if (fileUrl && fileName) {
          items.push({
            type: 'file',
            content: fileUrl,
            name: fileName,
            size: node.getAttribute('data-size-raw') || fileSize || 0
          })
        }
      } else {
        textContent += node.textContent
      }
    }
  })
  
  if (textContent.trim()) {
    items.push({
      type: 'text',
      content: textContent.trim()
    })
  }
  
  return {
    items: items.length > 0 ? items : [{ type: 'text', content: '' }],
    mentionUids,
    quoteId: quoteData.value?.msg_id || 0
  }
}

// 清空编辑器
const clearEditor = () => {
  editorContent.value = ''
  editorHtml.value = ''
  if (editorRef.value) {
    editorRef.value.innerHTML = ''
  }
  quoteData.value = null
  hideMentionList()
}



// 插入图片
const insertImage = (url, width, height) => {
  const selection = window.getSelection()
  if (!selection.rangeCount) return
  
  const range = selection.getRangeAt(0)
  const img = document.createElement('img')
  img.src = url
  img.style.maxWidth = '200px'
  img.style.maxHeight = '200px'
  if (width) img.setAttribute('width', width)
  if (height) img.setAttribute('height', height)
  
  range.deleteContents()
  range.insertNode(img)
  range.setStartAfter(img)
  range.collapse(true)
  selection.removeAllRanges()
  selection.addRange(range)
  
  editorRef.value.focus()
  handleInput({ target: editorRef.value })
}

// 插入文件
const insertFile = (url, fileName, fileSize) => {
  const selection = window.getSelection()
  if (!selection.rangeCount) return
  
  const range = selection.getRangeAt(0)
  
  // 创建文件链接元素
  const fileLink = document.createElement('a')
  fileLink.href = url
  fileLink.target = '_blank'
  fileLink.className = 'editor-file'
  fileLink.textContent = fileName
  fileLink.setAttribute('data-size', formatFileSize(fileSize))
  fileLink.setAttribute('data-url', url) // 添加URL属性用于解析
  fileLink.setAttribute('data-name', fileName) // 添加文件名属性用于解析
  fileLink.setAttribute('data-size-raw', fileSize) // 添加原始文件大小属性用于解析
  
  range.deleteContents()
  range.insertNode(fileLink)
  range.setStartAfter(fileLink)
  range.collapse(true)
  selection.removeAllRanges()
  selection.addRange(range)
  
  editorRef.value.focus()
  handleInput({ target: editorRef.value })
}

// 格式化文件大小
const formatFileSize = (size) => {
  if (size < 1024) {
    return size + ' B'
  } else if (size < 1024 * 1024) {
    return (size / 1024).toFixed(2) + ' KB'
  } else if (size < 1024 * 1024 * 1024) {
    return (size / (1024 * 1024)).toFixed(2) + ' MB'
  } else {
    return (size / (1024 * 1024 * 1024)).toFixed(2) + ' GB'
  }
}

// 文件上传处理
const onUploadFile = async (event) => {
  const file = event.target.files[0]
  if (!file) return

  try {
    const formData = new FormData()
    formData.append('file', file)
    formData.append('source', 'fonchain-chat')

    if (file.type.startsWith('image/')) {
      // 图片上传
      const image = new Image()
      image.src = URL.createObjectURL(file)
      image.onload = async () => {
        formData.append('urlParam', `width=${image.width}&height=${image.height}`)
        const { code, data } = await uploadImg(formData)
        if (code === 0) {
          insertImage(data.ori_url, image.width, image.height)
        }
      }
    } else {
      // 文件上传
      const { code, data } = await uploadImg(formData)
      if (code === 0) {
        // 直接发送文件消息，而不是插入到编辑器中
        emit('editor-event', {
          event: 'file_event',
          data: {
            items: [{
              type: 'file',
              content: data.ori_url,
              name: file.name,
              size: file.size
            }],
            mentionUids: [],
            quoteId: quoteData.value?.msg_id || 0
          },
          callBack: (success) => {
            if (success) {
              // 如果需要，可以在这里清空编辑器
              // clearEditor()
            }
          }
        })
      }
    }
  } catch (error) {
    console.error('文件上传失败:', error)
  }

  // 清空文件输入
  event.target.value = ''
}

// 表情选择事件
const onEmoticonEvent = (emoji) => {
  // 关闭表情面板
  emoticonRef.value?.setShow(false)
  
  // 处理不同类型的表情
  if (emoji.type === 'text') {
    // 文本表情
    insertTextEmoji(emoji.value)
  } else if (emoji.type === 'image') {
    // 图片表情
    insertImageEmoji(emoji.img, emoji.value)
  } else if (emoji.type === 'emoji') {
    // 系统表情
    insertTextEmoji(emoji.value)
  } else if (emoji.type === 1) {
    // 兼容旧版表情格式
    if (emoji.img) {
      insertImageEmoji(emoji.img, emoji.value)
    } else {
      insertTextEmoji(emoji.value)
    }
  } else {
    // 发送整个表情包
    emit('editor-event', {
      event: 'emoticon_event',
      data: emoji.value || emoji.id,
      callBack: () => {}
    })
  }
}

// 插入文本表情
const insertTextEmoji = (emojiText) => {
  const editor = editorRef.value
  if (!editor) return

  editor.focus()
  const selection = window.getSelection()
  if (!selection.rangeCount) return

  const range = selection.getRangeAt(0)
  range.deleteContents()

  const textNode = document.createTextNode(emojiText)
  range.insertNode(textNode)

  // 移动光标到插入文本之后
  range.setStartAfter(textNode)
  range.collapse(true)
  selection.removeAllRanges()
  selection.addRange(range)

  // 触发输入事件以更新编辑器内容
  handleInput({ target: editor })
}

// 插入图片表情
const insertImageEmoji = (imgSrc, altText) => {
  const editor = editorRef.value
  if (!editor) return

  editor.focus()
  const selection = window.getSelection()
  if (!selection.rangeCount) return

  const range = selection.getRangeAt(0)
  range.deleteContents()

  const img = document.createElement('img')
  img.src = imgSrc
  img.alt = altText
  img.className = 'editor-emoji' // 使用已有的样式
  // img.style.width = '24px' // 样式已在 .editor-emoji 中定义
  // img.style.height = '24px'
  // img.style.verticalAlign = 'middle'

  range.insertNode(img)

  // 移动光标到插入图片之后
  range.setStartAfter(img)
  range.collapse(true)
  selection.removeAllRanges()
  selection.addRange(range)

  // 触发输入事件以更新编辑器内容
  handleInput({ target: editor })
}



// 图片上传
const onImageUpload = async (event) => {
  const files = event.target.files
  if (!files || files.length === 0) return
  
  const file = files[0]
  if (!file.type.startsWith('image/')) {
    window['$message'].warning('请选择图片文件')
    return
  }
  
  try {
    const formData = new FormData()
    formData.append('file', file)
    
    const response = await ServeUploadImage(formData)
    if (response.code === 200) {
      // 获取图片尺寸
      const img = new Image()
      img.onload = () => {
        insertImage(response.data.url, img.width, img.height)
      }
      img.src = response.data.url
    }
  } catch (error) {
    window['$message'].error('图片上传失败')
  }
  
  event.target.value = ''
}

// 文件上传
const onFileUpload = (event) => {
  const files = event.target.files
  if (!files || files.length === 0) return
  
  const file = files[0]
  emit('editor-event', {
    event: 'file_event',
    data: file
  })
  
  event.target.value = ''
}

// 事件监听
const onSubscribeMention = (data) => {
  insertMention(data)
}

const onSubscribeQuote = (data) => {
  quoteData.value = data
}

const onSubscribeEdit = (data) => {
  editingMessage.value = data
  clearEditor()
  
  // 插入编辑内容
  if (data.content) {
    editorRef.value.innerHTML = data.content
    editorContent.value = data.content
    editorHtml.value = data.content
  }
}

// 组件挂载
onMounted(() => {
  bus.subscribe('mention', onSubscribeMention)
  bus.subscribe('quote', onSubscribeQuote)
  bus.subscribe('edit', onSubscribeEdit)
  
  // 点击外部隐藏mention
  document.addEventListener('click', (event) => {
    if (!editorRef.value?.contains(event.target)) {
      hideMentionList()
    }
  })
})

// 组件卸载
onBeforeUnmount(() => {
  bus.unsubscribe('mention', onSubscribeMention)
  bus.unsubscribe('quote', onSubscribeQuote)
  bus.unsubscribe('edit', onSubscribeEdit)
})

// 表情选择
const onEmoticonSelect = (emoji) => {
  // 直接调用onEmoticonEvent处理表情
  onEmoticonEvent(emoji)
  isShowEmoticon.value = false
}

// 代码块
const onCodeSubmit = (data) => {
  emit('editor-event', {
    event: 'code_event',
    data,
    callBack: () => {}
  })
  isShowCode.value = false
}

// 投票
const onVoteSubmit = (data) => {
  emit('editor-event', {
    event: 'vote_event',
    data,
    callBack: () => {}
  })
  isShowVote.value = false
}

// 录音
const onRecorderFinish = (data) => {
  emit('editor-event', {
    event: 'file_event',
    data
  })
  isShowRecorder.value = false
}
</script>

<template>
  <section class="el-container editor">
    <section class="el-container is-vertical">
      <!-- 工具栏区域 -->
      <header class="el-header toolbar bdr-t">
        <div class="tools">
          <!-- 表情选择器弹出框 -->
          <n-popover
            placement="top-start"
            trigger="click"
            raw
            :show-arrow="false"
            :width="300"
            ref="emoticonRef"
            style="width: 500px; height: 250px; border-radius: 10px; overflow: hidden"
          >
            <template #trigger>
              <div class="item pointer">
                <n-icon size="18" class="icon" :component="SmilingFace" />
                <p class="tip-title">表情符号</p>
              </div>
            </template>

            <MeEditorEmoticon @on-select="onEmoticonEvent" />
          </n-popover>

          <!-- 工具栏其他功能按钮 -->
          <div
            class="item pointer"
            v-for="nav in navs"
            :key="nav.title"
            v-show="nav.show"
            @click="nav.click"
          >
            <n-icon size="18" class="icon" :component="nav.icon" />
            <p class="tip-title">{{ nav.title }}</p>
          </div>
        </div>
      </header>

      <!-- 编辑器主体区域 -->
      <main class="el-main height100">
        <div
          ref="editorRef"
          class="custom-editor"
          contenteditable="true"
          :placeholder="placeholder"
          @input="handleInput"
          @keydown="handleKeydown"
          @paste="handlePaste"
          @focus="handleFocus"
          @blur="handleBlur"
        ></div>

        <!-- @提及列表 -->
        <div
          v-if="showMention"
          class="mention-list"
          :style="{ top: mentionPosition.top + 'px', left: mentionPosition.left + 'px' }"
        >
          <ul>
            <li
              v-for="(member, index) in mentionList"
              :key="member.user_id"
              :class="{ selected: index === selectedMentionIndex }"
              @mousedown.prevent="insertMention(member)"
            >
              {{ member.nickname }}
            </li>
          </ul>
        </div>
      </main>
    </section>
  </section>

  <!-- 隐藏的文件上传表单 -->
  <form enctype="multipart/form-data" style="display: none">
    <input type="file" ref="fileImageRef" accept="image/*" @change="onUploadFile" />
    <input type="file" ref="uploadFileRef" @change="onUploadFile" />
  </form>


</template>

<style lang="less" scoped>
.editor {
  --tip-bg-color: rgb(241 241 241 / 90%);
  height: 100%;

  .toolbar {
    height: 38px;
    display: flex;

    .tools {
      height: 100%;
      flex: auto;
      display: flex;

      .item {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 35px;
        margin: 0 2px;
        position: relative;
        user-select: none;

        .tip-title {
          display: none;
          position: absolute;
          top: 40px;
          left: 0px;
          line-height: 26px;
          background-color: var(--tip-bg-color);
          color: var(--im-text-color);
          min-width: 20px;
          font-size: 12px;
          padding: 0 5px;
          border-radius: 2px;
          white-space: pre;
          user-select: none;
          z-index: 999999999999;
        }

        &:hover {
          .tip-title {
            display: block;
          }
        }
      }
    }
  }
  
  // 文件链接样式
  :deep(.editor-file) {
    display: inline-block;
    padding: 5px 10px;
    margin: 5px 0;
    background-color: #f5f5f5;
    border: 1px solid #e0e0e0;
    border-radius: 4px;
    color: #2196f3;
    text-decoration: none;
    position: relative;
    padding-right: 60px;
    max-width: 100%;
    box-sizing: border-box;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    
    &::after {
      content: attr(data-size);
      position: absolute;
      right: 10px;
      color: #757575;
      font-size: 12px;
    }
    
    &:hover {
      background-color: #e3f2fd;
    }
  }
  
  // 表情符号样式
  :deep(.editor-emoji) {
    display: inline-block;
    width: 24px;
    height: 24px;
    vertical-align: middle;
    margin: 0 2px;
  }

  .custom-editor {
    width: 100%;
    height: 100%;
    padding: 8px;
    border: none;
    outline: none;
    resize: none;
    font-size: 14px;
    line-height: 1.5;
    color: #333;
    background: transparent;
    overflow-y: auto;

    &::-webkit-scrollbar {
      width: 3px;
      height: 3px;
      background-color: unset;
    }

    &::-webkit-scrollbar-thumb {
      border-radius: 3px;
      background-color: transparent;
    }

    &:hover {
      &::-webkit-scrollbar-thumb {
        background-color: var(--im-scrollbar-thumb);
      }
    }
  }

  .custom-editor:empty::before {
    content: attr(placeholder);
    color: #999;
    pointer-events: none;
    font-family: PingFang SC, Microsoft YaHei, 'Alibaba PuHuiTi 2.0 45' !important;
  }

  .custom-editor:focus {
    outline: none;
  }

  /* Mention 样式 */
  .mention {
    color: #1890ff;
    background-color: #e6f7ff;
    padding: 2px 4px;
    border-radius: 3px;
    text-decoration: none;
    cursor: pointer;
  }

  .mention:hover {
    background-color: #bae7ff;
  }

  /* 图片样式 */
  .editor-image {
    max-width: 100px;
    max-height: 100px;
    border-radius: 3px;
    background-color: #48484d;
    margin: 0px 2px;
    cursor: pointer;
  }

  /* 表情样式 */
  .editor-emoji {
    width: 20px;
    height: 20px;
    vertical-align: middle;
    margin: 0 2px;
  }

  /* @提及列表样式 */
  .mention-list {
    position: absolute;
    background-color: white;
    border: 1px solid #eee;
    border-radius: 4px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    z-index: 1000;
    max-height: 200px;
    overflow-y: auto;

    ul {
      list-style: none;
      padding: 0;
      margin: 0;
    }

    li {
      padding: 8px 12px;
      cursor: pointer;
      font-size: 14px;

      &:hover,
      &.selected {
        background-color: #f5f5f5;
      }
    }
  }

  /* 引用卡片样式 */
  .quote-card {
    background: #f5f5f5;
    border-left: 3px solid #1890ff;
    padding: 8px 12px;
    margin: 8px 0;
    border-radius: 4px;
    position: relative;
  }

  .quote-content {
    font-size: 12px;
  }

  .quote-title {
    font-weight: bold;
    color: #1890ff;
    margin-bottom: 4px;
  }

  .quote-text {
    color: #666;
    line-height: 1.4;
  }

  .quote-close {
    position: absolute;
    top: 4px;
    right: 4px;
    background: none;
    border: none;
    cursor: pointer;
    color: #999;
    font-size: 12px;
  }

  /* 编辑提示样式 */
  .edit-tip {
    background: #fff7e6;
    border: 1px solid #ffd591;
    padding: 6px 12px;
    margin-bottom: 8px;
    border-radius: 4px;
    font-size: 12px;
    color: #d46b08;
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .edit-tip button {
    background: none;
    border: none;
    cursor: pointer;
    color: #d46b08;
    margin-left: auto;
  }
}

/* 暗色模式样式调整 */
html[theme-mode='dark'] {
  .editor {
    --tip-bg-color: #48484d;
  }
}
</style>