<script setup>
import { ref, reactive, computed, onMounted, onBeforeUnmount, nextTick, markRaw, watch } 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'
import {IosSend} from '@vicons/ionicons4'
const props = defineProps({
  vote: {
    type: Boolean,
    default: false
  },
  members: {
    type: Array,
    default: () => []
  },
  placeholder: {
    type: String,
    default: 'Enter-发送消息  [Ctrl+Enter/Shift+Enter]-换行'
  }
})

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 indexName = computed(() => dialogueStore.index_name)

// 工具栏配置
const navs = ref([
  {
    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
  
  // 获取编辑器内容，但不包括引用元素的内容
  const editorClone = target.cloneNode(true)
  const quoteElements = editorClone.querySelectorAll('.editor-quote')
  quoteElements.forEach(quote => quote.remove())
  
  // 处理表情图片，将其 alt 属性（表情文本）添加到文本内容中
  const emojiImages = editorClone.querySelectorAll('img.editor-emoji')
  let textContent = editorClone.textContent || ''
  
  // 将表情图片的 alt 属性添加到文本内容中
  if (emojiImages.length > 0) {
    emojiImages.forEach(emoji => {
      const altText = emoji.getAttribute('alt')
      if (altText) {
        textContent += altText
      }
    })
  }
  
  // 更新逻辑文本内容
  editorContent.value = textContent

  // 检查是否需要清空编辑器以显示placeholder
  const isEmpty = textContent.trim() === '' && 
                 !target.querySelector('img, .editor-file, .mention')
  
  if (isEmpty && target.innerHTML !== '') {
    target.innerHTML = ''
  }

  // 更新HTML内容
  editorHtml.value = target.innerHTML || ''

  // 后续操作
  checkMention(target)
  saveDraft()

  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 => {
    return member.value.toLowerCase().startsWith(query)
  })
  
  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)
  
  // 创建mention元素
  const mentionSpan = document.createElement('span')
  mentionSpan.className = 'mention'
  mentionSpan.setAttribute('data-user-id', member.id || member.user_id)
  mentionSpan.textContent = `@${member.value || member.nickname}`
  mentionSpan.contentEditable = 'false'
  
  if (atIndex !== -1) {
    // 如果找到@符号，替换文本
    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)
  } else {
    // 如果没有找到@符号，直接在光标位置插入
    range.deleteContents()
    
    // 插入@提及元素
    range.insertNode(mentionSpan)
    
    // 在@提及元素后添加空格
    const spaceNode = document.createTextNode(' ')
    range.setStartAfter(mentionSpan)
    range.insertNode(spaceNode)
    
    // 将光标移动到空格后
    range.setStartAfter(spaceNode)
    range.collapse(true)
    selection.removeAllRanges()
    selection.addRange(range)
  }
  
  // 触发输入事件以更新编辑器内容
  handleInput({ target: editorRef.value })
  
  // 隐藏mention列表
  hideMentionList()
}

// 处理粘贴事件
const handlePaste = (event) => {
  event.preventDefault()
  
  // 检查是否有图片
  const items = event.clipboardData?.items
  if (items) {
    for (let i = 0; i < items.length; i++) {
      if (items[i].type.indexOf('image') !== -1) {
        // 获取粘贴的图片文件
        const file = items[i].getAsFile()
        if (file) {
          const tempUrl = URL.createObjectURL(file);
    const image = new Image();
    image.src = tempUrl;
    image.onload = () => {
      const form = new FormData();
      form.append('file', file);
      form.append("source", "fonchain-chat");  
      form.append("urlParam", `width=${image.width}&height=${image.height}`);
      insertImage(tempUrl, image.width, image.height);
      uploadImg(form).then(({ code, data, message }) => {
        if (code == 0) {
          const editorImages = editorRef.value.querySelectorAll('img.editor-image');
          const lastImage = editorImages[editorImages.length - 1];
          if (lastImage && lastImage.src === tempUrl) {
            lastImage.src = data.ori_url;
            handleInput({ target: editorRef.value });
          }
        } else {
          window['$message'].error(message);
        }
      });
    };
    
          return
        }
      }
    }
  }
  
  // 获取粘贴的纯文本内容
  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)
        // 确保选中项可见 - 向上滚动
        nextTick(() => {
          const mentionList = document.querySelector('.mention-list ul')
          const selectedItem = mentionList?.children[selectedMentionIndex.value]
          if (mentionList && selectedItem && selectedItem.offsetTop < mentionList.scrollTop) {
            mentionList.scrollTop = selectedItem.offsetTop
          }
        })
        break
      case 'ArrowDown':
        event.preventDefault()
        selectedMentionIndex.value = Math.min(mentionList.value.length - 1, selectedMentionIndex.value + 1)
        // 确保选中项可见 - 向下滚动
        nextTick(() => {
          const mentionList = document.querySelector('.mention-list ul')
          const selectedItem = mentionList?.children[selectedMentionIndex.value]
          if (mentionList && selectedItem) {
            const itemBottom = selectedItem.offsetTop + selectedItem.offsetHeight
            const listBottom = mentionList.scrollTop + mentionList.clientHeight
            if (itemBottom > listBottom) {
              mentionList.scrollTop = itemBottom - mentionList.clientHeight
            }
          }
        })
        break
      case 'Enter':
      case 'Tab':
        event.preventDefault()
        const selectedMember = mentionList.value[selectedMentionIndex.value]
        if (selectedMember) {
          insertMention(selectedMember)
        }
        break
      case 'Escape':
        hideMentionList()
        break
    }
    return
  }
  
  // 处理删除键（Backspace和Delete）删除mention元素
  if (event.key === 'Backspace' || event.key === 'Delete') {
    const selection = window.getSelection()
    if (!selection.rangeCount) return
    
    const range = selection.getRangeAt(0)
    const editor = editorRef.value
    
    // 只处理光标位置的删除，不处理选中内容的删除
    if (range.collapsed) {
      let targetMention = null
      
      // 获取光标位置信息
      const container = range.startContainer
      const offset = range.startOffset
      
      if (event.key === 'Backspace') {
        // Backspace：查找光标前面的mention元素
        if (container.nodeType === Node.TEXT_NODE) {
          // 如果光标在文本节点的开头，检查前一个兄弟节点
          if (offset === 0) {
            let prevSibling = container.previousSibling
            while (prevSibling) {
              if (prevSibling.nodeType === Node.ELEMENT_NODE && 
                  prevSibling.classList && 
                  prevSibling.classList.contains('mention')) {
                targetMention = prevSibling
                break
              }
              // 如果是文本节点且不为空，停止查找
              if (prevSibling.nodeType === Node.TEXT_NODE && prevSibling.textContent.trim()) {
                break
              }
              prevSibling = prevSibling.previousSibling
            }
          }
        } else if (container.nodeType === Node.ELEMENT_NODE) {
          // 如果光标在元素节点中，检查前一个子节点
          if (offset > 0) {
            let prevChild = container.childNodes[offset - 1]
            // 如果前一个子节点是mention元素
            if (prevChild && prevChild.nodeType === Node.ELEMENT_NODE && 
                prevChild.classList && prevChild.classList.contains('mention')) {
              targetMention = prevChild
            }
            // 如果前一个子节点是文本节点，检查它前面的兄弟节点
            else if (prevChild && prevChild.nodeType === Node.TEXT_NODE && !prevChild.textContent.trim()) {
              let prevSibling = prevChild.previousSibling
              while (prevSibling) {
                if (prevSibling.nodeType === Node.ELEMENT_NODE && 
                    prevSibling.classList && 
                    prevSibling.classList.contains('mention')) {
                  targetMention = prevSibling
                  break
                }
                if (prevSibling.nodeType === Node.TEXT_NODE && prevSibling.textContent.trim()) {
                  break
                }
                prevSibling = prevSibling.previousSibling
              }
            }
          } else if (offset === 0 && container === editor) {
            // 特殊情况：光标在编辑器开头，检查第一个子节点是否是mention
            const firstChild = container.firstChild
            if (firstChild && firstChild.nodeType === Node.ELEMENT_NODE && 
                firstChild.classList && firstChild.classList.contains('mention')) {
              targetMention = firstChild
            }
          }
        }
      } else if (event.key === 'Delete') {
        // Delete：查找光标后面的mention元素
        if (container.nodeType === Node.TEXT_NODE) {
          // 如果光标在文本节点的末尾，检查后一个兄弟节点
          if (offset === container.textContent.length) {
            let nextSibling = container.nextSibling
            while (nextSibling) {
              if (nextSibling.nodeType === Node.ELEMENT_NODE && 
                  nextSibling.classList && 
                  nextSibling.classList.contains('mention')) {
                targetMention = nextSibling
                break
              }
              // 如果是文本节点且不为空，停止查找
              if (nextSibling.nodeType === Node.TEXT_NODE && nextSibling.textContent.trim()) {
                break
              }
              nextSibling = nextSibling.nextSibling
            }
          }
        } else if (container.nodeType === Node.ELEMENT_NODE) {
          // 如果光标在元素节点中，检查后一个子节点
          if (offset < container.childNodes.length) {
            const nextChild = container.childNodes[offset]
            if (nextChild && nextChild.nodeType === Node.ELEMENT_NODE && 
                nextChild.classList && nextChild.classList.contains('mention')) {
              targetMention = nextChild
            }
          }
        }
      }
      
      // 如果找到了要删除的mention元素
      if (targetMention) {
        event.preventDefault()
        
        // 删除mention元素
        targetMention.remove()
        
        // 触发输入事件更新编辑器内容
        handleInput({ target: editor })
        return
      }
    }
  }
  
  // 处理Ctrl+Enter或Shift+Enter换行
  if (event.key === 'Enter' && (event.ctrlKey || event.metaKey || event.shiftKey)) {
    // 手动插入换行符
    const selection = window.getSelection()
    if (selection && selection.rangeCount > 0) {
      const range = selection.getRangeAt(0)
      const br = document.createElement('br')
      range.deleteContents()
      range.insertNode(br)
      
      // 在换行符后添加一个空文本节点，并将光标移动到这个节点
      const textNode = document.createTextNode('')
      range.setStartAfter(br)
      range.insertNode(textNode)
      range.setStartAfter(textNode)
      range.collapse(true)
      selection.removeAllRanges()
      selection.addRange(range)
      
      // 触发输入事件更新编辑器内容
      handleInput({ target: editorRef.value })
    }
    
    // 阻止默认行为，防止触发表单提交
    event.preventDefault()
    return
  }
  
  // 处理Enter键发送消息（只有在没有按Ctrl/Cmd/Shift时才发送）
  if (event.key === 'Enter' && !event.ctrlKey && !event.metaKey && !event.shiftKey) {
    event.preventDefault()
    
    // 检查引用元素是否存在，如果不存在但 quoteData 有值，则清除 quoteData
    const editor = editorRef.value
    const quoteElement = editor?.querySelector('.editor-quote')
    if (!quoteElement && quoteData.value) {
      quoteData.value = null
    }
    
    // 解析编辑器内容并发送消息
    sendMessage()
  }
}

// 发送消息 
const sendMessage = () => {
  // 解析编辑器内容
  const messageData = parseEditorContent()
  
  // 检查是否有内容可发送
  if (messageData.items.length === 0 || 
     (messageData.items.length === 1 && 
      messageData.items[0].type === 1 && 
      !messageData.items[0].content.trim())) {
    return // 没有内容，不发送
  }
  
  // 处理不同类型的消息
  messageData.items.forEach(item => {
    // 处理文本内容
    if (item.type === 1 && item.content.trim()) {
      const data = {
        items: [{
          content: item.content,
          type: 1
        }],
        mentionUids: messageData.mentionUids,
        mentions: [],
        quoteId: messageData.quoteId,
      }
      
      emit(
        'editor-event',
        emitCall('text_event', data)
      )
    } else if (item.type === 3) { // 图片消息
      const data = {
        height: 0,
        width: 0,
        size: 10000,
        url: item.content,
      }
      
      emit(
        'editor-event',
        emitCall('image_event', data)
      )
    } else if (item.type === 4) { // 文件消息
      // 文件消息处理逻辑
    }
  })
  
  // 发送后清空编辑器
  clearEditor()
}

// 解析编辑器内容 
const parseEditorContent = () => {
  const items = []
  const mentionUids = []
  
  // 解析HTML内容
  const tempDiv = document.createElement('div')
  tempDiv.innerHTML = editorHtml.value
  
  // 检查是否有引用元素
  const quoteElements = tempDiv.querySelectorAll('.editor-quote')
  const hasQuote = quoteElements.length > 0 && quoteData.value
  const quoteId = hasQuote ? quoteData.value.id || '' : ''
  
  // 移除引用元素，避免重复处理
  quoteElements.forEach(quote => quote.remove())
  
  let textContent = ''
  
  // 处理文本节点和元素节点
  const processNode = (node) => {
    if (node.nodeType === Node.TEXT_NODE) {
      // 文本节点直接添加内容
      textContent += node.textContent
      return
    }
    
    if (node.nodeType !== Node.ELEMENT_NODE) return
    
    // 处理不同类型的元素
    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') {
      // 处理图片
      processImage(node)
    } else if (node.classList.contains('emoji')) {
      // 处理emoji元素
      textContent += node.getAttribute('alt') || node.textContent
    } else if (node.classList.contains('editor-file')) {
      // 处理文件
      processFile(node)
    } else if (node.childNodes.length) {
      // 处理有子节点的元素
      Array.from(node.childNodes).forEach(processNode)
    } else {
      // 其他元素，添加文本内容
      textContent += node.textContent
    }
  }
  
  // 处理图片元素
  const processImage = (node) => {
    const src = node.getAttribute('src')
    const width = node.getAttribute('data-original-width') || node.getAttribute('width') || ''
    const height = node.getAttribute('data-original-height') || node.getAttribute('height') || ''
    const isEmoji = node.classList.contains('editor-emoji')
    
    // 如果有累积的文本内容，先添加到items
    if (textContent.trim()) {
      items.push({
        type: 1,
        content: textContent.trim()
      })
      textContent = ''
    }
    
    if (isEmoji) {
      // 处理表情图片
      const altText = node.getAttribute('alt') || ''
      if (altText) {
        // 如果有alt文本，将表情作为文本处理
        textContent += altText
      } else {
        // 否则作为图片处理
        items.push({
          type: 3,
          content: src + (width && height ? `?width=${width}&height=${height}` : ''),
          isEmoji: true
        })
      }
    } else {
      // 处理普通图片
      items.push({
        type: 3,
        content: src + (width && height ? `?width=${width}&height=${height}` : ''),
        width: width,
        height: height
      })
    }
  }
  
  // 处理文件元素
  const processFile = (node) => {
    const fileUrl = node.getAttribute('data-url')
    const fileName = node.getAttribute('data-name')
    const fileSize = node.getAttribute('data-size')
    
    // 如果有累积的文本内容，先添加到items
    if (textContent.trim()) {
      items.push({
        type: 1,
        content: textContent.trim()
      })
      textContent = ''
    }
    
    if (fileUrl && fileName) {
      items.push({
        type: 4, // 使用数字类型保持一致性
        content: fileUrl,
        name: fileName,
        size: node.getAttribute('data-size-raw') || fileSize || 0
      })
    }
  }
  
  // 处理所有顶级节点
  Array.from(tempDiv.childNodes).forEach(processNode)
  
  // 处理剩余的文本内容
  if (textContent.trim()) {
    items.push({
      type: 1,
      content: textContent.trim()
    })
  }
  
  // 构建完整的消息数据结构
  return {
    items: items.length > 0 ? items : [{ type: 1, content: '' }],
    mentionUids,
    quoteId
  }
}

// 清空编辑器 
const clearEditor = () => {
  // 一次性清空所有编辑器相关状态
  editorContent.value = ''
  editorHtml.value = ''
  quoteData.value = null
  
  // 清空DOM内容
  if (editorRef.value) {
    editorRef.value.innerHTML = ''
    // 立即设置焦点，提高响应速度
    nextTick(() => editorRef.value.focus())
  }
  
  // 隐藏@提及列表
  hideMentionList()
  
  // 清空草稿
  saveDraft()
  
  // 触发输入事件
  emit('editor-event', {
    event: 'input_event',
    data: ''
  })
}



// 插入图片
const insertImage = (src, width, height) => {
  const selection = window.getSelection()
  if (!selection.rangeCount) return
  
  const range = selection.getRangeAt(0)
  
  // 创建图片元素
  const img = document.createElement('img')
  img.src = src
  img.className = 'editor-image'
  img.alt = '图片'
  img.style.maxHeight = '150px'
  img.style.maxWidth = '150px'
  img.style.objectFit = 'contain' // 保持原始比例
  
  // 存储原始尺寸信息，但不直接设置宽高属性
  if (width) img.setAttribute('data-original-width', width)
  if (height) img.setAttribute('data-original-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 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 onUploadSendImg=async (eventFile)=>{
  for (const file of eventFile.target.files) {
    const form = new FormData();
    form.append('file', file);
    form.append("source", "fonchain-chat");

   const res=await uploadImg(form)
   if(res.status===0){
    const data={
          height:0,
          width:0,
          size:10000,
          url:res.data.ori_url,
        }
        emit(
        'editor-event',
        emitCall(
          'image_event',
          data
        )
      )
   }
  }
}
async function onUploadFile(e) {
  const file = e.target.files[0]
  if (!file) return
  
  // 清空input，允许再次选择相同文件
  e.target.value = null
  
  if (file.type.indexOf('image/') === 0) {
    // 处理图片文件 - 立即显示临时消息，然后上传
    emit('editor-event', emitCall('image_event', file))

    return
  }

  if (file.type.indexOf('video/') === 0) {
    // 处理视频文件
    emit('editor-event', emitCall('video_event', file))
  } else {
    // 处理其他类型文件
    emit('editor-event', emitCall('file_event', file))
  }
}

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

// 插入文本表情
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 onSubscribeMention = (data) => {
  // 确保编辑器获得焦点
  editorRef.value?.focus()
  
  // 如果编辑器为空或者光标不在编辑器内，将光标移动到编辑器末尾
  const selection = window.getSelection()
  if (!selection.rangeCount || !editorRef.value.contains(selection.anchorNode)) {
    const range = document.createRange()
    if (editorRef.value.lastChild) {
      range.setStartAfter(editorRef.value.lastChild)
    } else {
      range.setStart(editorRef.value, 0)
    }
    range.collapse(true)
    selection.removeAllRanges()
    selection.addRange(range)
  }
  
  // 插入@提及
  insertMention(data)
}

const onSubscribeQuote = (data) => {
  // 保存引用数据，但不保存到草稿中
  quoteData.value = data
  
  // 在编辑器中显示引用内容
  const editor = editorRef.value
  if (!editor) return
  
  // 先移除已有的引用元素
  const existingQuotes = editor.querySelectorAll('.editor-quote')
  existingQuotes.forEach(quote => quote.remove())
  
  // 保存当前光标位置
  const selection = window.getSelection()
  const savedRange = selection.rangeCount > 0 ? selection.getRangeAt(0).cloneRange() : null
  const hasContent = editor.textContent.trim().length > 0
  
  // 创建引用元素
  const quoteElement = document.createElement('div')
  quoteElement.className = 'editor-quote'
  quoteElement.contentEditable = 'false' // 设置为不可编辑
  
  // 添加引用内容和关闭按钮
  quoteElement.innerHTML = `
    <div class="quote-content-wrapper">
      <div class="quote-title">${data.title}</div>
      ${data.image ? `<div class="quote-image"><img src="${data.image}" alt="引用图片" /></div>` : ''}
      ${data.describe ? `<div class="quote-content">${data.describe}</div>` : ''}
    </div>
    <div class="quote-close">×</div>
  `
  
  // 将引用元素插入到编辑器开头
  if (editor.firstChild) {
    editor.insertBefore(quoteElement, editor.firstChild)
  } else {
    editor.appendChild(quoteElement)
  }
  
  // 使用事件委托处理引用元素的所有点击事件
  quoteElement.addEventListener('click', (e) => {
    // 检查点击的是否是关闭按钮或其内部元素
    const closeButton = e.target.classList?.contains('quote-close') ? e.target : e.target.closest('.quote-close')
    
    // 阻止事件冒泡，避免触发编辑器的其他点击事件
    e.stopPropagation()
    
    if (closeButton) {
      // 移除引用元素并清除引用数据
      quoteElement.remove()
      quoteData.value = null
      
      // 只更新编辑器内容变量，不触发handleInput，避免保存草稿
      editorContent.value = editor.textContent || ''
      editorHtml.value = editor.innerHTML || ''
      
      // 使用nextTick确保DOM更新后再设置焦点
      nextTick(() => editor.focus())
    } else {
      // 如果不是点击关闭按钮，则设置光标到引用卡片后面
      const selection = window.getSelection()
      const range = document.createRange()
      range.setStartAfter(quoteElement)
      range.collapse(true)
      selection.removeAllRanges()
      selection.addRange(range)
      
      // 立即设置焦点
      editor.focus()
    }
  })
  
  // 注意：不调用saveDraft()，确保引用内容不会被保存到草稿中
  
  // 在同一个事件监听器中处理引用卡片的点击
  // 已经在上面的事件处理中添加了关闭按钮的处理逻辑
  // 这里只需要处理非关闭按钮的点击
  // 注意：由于事件委托的方式，不需要额外添加点击事件监听器
  
  // 监听键盘事件，处理引用元素的删除操作
  const handleDeleteQuote = function(e) {
    // 只处理删除键（Backspace 或 Delete）
    if (e.key !== 'Backspace' && e.key !== 'Delete') return;
    
    const selection = window.getSelection();
    if (selection.rangeCount === 0) return;
    
    const range = selection.getRangeAt(0);
    const quoteElement = editor.querySelector('.editor-quote');
    
    if (!quoteElement) {
      // 如果引用元素已经被删除，移除事件监听器
      editor.removeEventListener('keydown', handleDeleteQuote);
      return;
    }
    
    // 获取引用元素在子节点中的索引
    const quoteIndex = Array.from(editor.childNodes).indexOf(quoteElement);
    
    // 检查光标是否在引用卡片前面（Backspace）或后面（Delete）
    const isBeforeQuote = e.key === 'Backspace' && 
                         range.collapsed && 
                         range.startContainer === editor && 
                         quoteIndex === range.startOffset;
    
    const isAfterQuote = e.key === 'Delete' && 
                        range.collapsed && 
                        range.startContainer === editor && 
                        quoteIndex === range.startOffset - 1;
    
    if (isBeforeQuote || isAfterQuote) {
      // 阻止默认删除行为
      e.preventDefault();
      
      // 移除引用元素并清除引用数据
      quoteElement.remove();
      quoteData.value = null;
      
      // 更新编辑器内容
      handleInput({ target: editor });
    }
  };

editor.addEventListener('keydown', handleDeleteQuote);
  
  // 设置光标位置
setTimeout(() => {
  // 确保编辑器中有内容可以放置光标
  if (!editor.childNodes.length || (editor.childNodes.length === 1 && editor.childNodes[0] === quoteElement)) {
    // 如果编辑器中只有引用元素，添加一个空的文本节点
    const textNode = document.createTextNode('\u200B'); // 使用零宽空格
    editor.appendChild(textNode);
  }
  
  // 强制刷新编辑器内容，确保DOM已更新
  const currentHtml = editor.innerHTML;
  editor.innerHTML = currentHtml;
  
  // 重新获取引用元素（因为innerHTML操作会导致之前的引用丢失）
  const newQuoteElement = editor.querySelector('.editor-quote');
  
  editor.focus();
  const newSelection = window.getSelection();
  const newRange = document.createRange();
  
  // 始终将光标设置在引用元素后面
  if (newQuoteElement) {
    // 找到引用元素后的第一个节点
    let nextNode = newQuoteElement.nextSibling;
    if (nextNode && nextNode.nodeType === 3) { // 文本节点
      newRange.setStart(nextNode, 0);
    } else if (nextNode) { // 其他元素节点
      newRange.setStartBefore(nextNode);
    } else { // 没有下一个节点
      newRange.setStartAfter(newQuoteElement);
    }
  } else {
    // 如果找不到引用元素，则设置到编辑器开头
    if (editor.firstChild) {
      newRange.setStartBefore(editor.firstChild);
    } else {
      newRange.setStart(editor, 0);
    }
  }
  
  newRange.collapse(true);
  newSelection.removeAllRanges();
  newSelection.addRange(newRange);
  
  // 确保光标可见
  editor.scrollTop = editor.scrollHeight;
  
  // 更新编辑器内容
  handleInput({ target: editor });
  
  // 再次确保编辑器获得焦点
  setTimeout(() => {
    editor.focus();
    // 再次尝试设置光标位置
    if (newSelection.rangeCount === 0) {
      const finalRange = document.createRange();
      if (newQuoteElement) {
        finalRange.setStartAfter(newQuoteElement);
      } else {
        finalRange.setStart(editor, 0);
      }
      finalRange.collapse(true);
      newSelection.removeAllRanges();
      newSelection.addRange(finalRange);
    }
  }, 50);
}, 200); // 增加延时确保DOM已完全更新
}

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

// 清除编辑器内容的事件处理函数
const onSubscribeClear = () => {
  clearEditor()
}

// 保存草稿
const saveDraft = () => {
  if (!indexName.value || !editorRef.value) return
  
  // 获取编辑器内容，但排除引用元素
  // 使用DocumentFragment进行高效的DOM操作
  const fragment = document.createDocumentFragment()
  const tempDiv = document.createElement('div')
  tempDiv.innerHTML = editorRef.value.innerHTML
  fragment.appendChild(tempDiv)
  
  // 从临时DOM中移除引用元素
  const quoteElements = tempDiv.querySelectorAll('.editor-quote')
  quoteElements.forEach(quote => quote.remove())
  
  // 获取不包含引用的内容
  const contentToSave = tempDiv.textContent || ''
  const htmlToSave = tempDiv.innerHTML || ''
  
  // 检查是否有实际内容（不包括引用）
  const hasContent = contentToSave.trim().length > 0 || 
                    htmlToSave.includes('<img') || 
                    htmlToSave.includes('editor-file')
  
  // 根据内容状态保存或删除草稿
  if (hasContent) {
    // 保存草稿到store，不包括引用数据
    editorDraftStore.items[indexName.value] = JSON.stringify({
      content: contentToSave,
      html: htmlToSave
    })
  } else {
    // 编辑器为空时删除对应草稿
    delete editorDraftStore.items[indexName.value]
  }
}

// 加载草稿 
const loadDraft = () => {
  if (!indexName.value) return
  
  // 使用nextTick确保DOM已渲染，更可预测且性能更好
  nextTick(() => {
    // 保存当前引用数据的临时副本
    const currentQuoteData = quoteData.value
    
    // 清除当前引用数据，避免重复添加
    quoteData.value = null
    
    // 如果编辑器引用不存在，直接返回
    if (!editorRef.value) return
    
    // 先清空编辑器内容
    editorRef.value.innerHTML = ''
    editorContent.value = ''
    editorHtml.value = ''
    
    // 获取草稿数据
    const draft = editorDraftStore.items[indexName.value]
    
    // 如果有草稿，恢复草稿内容
    if (draft) {
      try {
        const draftData = JSON.parse(draft)
        
        // 恢复草稿内容
        editorRef.value.innerHTML = draftData.html || ''
        editorContent.value = draftData.content || ''
        editorHtml.value = draftData.html || ''
      } catch (error) {
        console.warn('加载草稿失败，使用空内容', error)
      }
    }
    
    // 如果有引用数据，重新添加到编辑器（无论是否有草稿）
    if (currentQuoteData) {
      onSubscribeQuote(currentQuoteData)
    }
  })
}

// 监听会话变化，加载对应草稿
watch(indexName, loadDraft, { immediate: true })

// 处理点击文档事件，隐藏@提及列表
const handleDocumentClick = (event) => {
  if (!editorRef.value?.contains(event.target)) {
    hideMentionList()
  }
}

// 组件挂载
onMounted(() => {
  // 订阅所有编辑器相关事件
  const subscriptions = [
    [EditorConst.Mention, onSubscribeMention],
    [EditorConst.Quote, onSubscribeQuote],
    [EditorConst.Edit, onSubscribeEdit],
    [EditorConst.Clear, onSubscribeClear]
  ]
  
  // 批量订阅事件
  subscriptions.forEach(([event, handler]) => {
    bus.subscribe(event, handler)
  })

  // 为编辑器添加点击事件监听器
  editorRef.value?.addEventListener('click', handleEditorClick)
  
  // 点击外部隐藏mention - 使用命名函数便于清理
  document.addEventListener('click', handleDocumentClick)
  
  // 初始加载草稿
  loadDraft()
})

/**
 * 组件生命周期钩子 - 组件卸载前
 * 清理所有事件订阅和监听器，防止内存泄漏
 */
onBeforeUnmount(() => {
  // 取消订阅所有编辑器相关事件
  const subscriptions = [
    [EditorConst.Mention, onSubscribeMention],
    [EditorConst.Quote, onSubscribeQuote],
    [EditorConst.Edit, onSubscribeEdit],
    [EditorConst.Clear, onSubscribeClear]
  ]
  
  // 批量取消订阅
  subscriptions.forEach(([event, handler]) => {
    bus.unsubscribe(event, handler)
  })

  // 移除编辑器点击事件监听器
  editorRef.value?.removeEventListener('click', handleEditorClick)
  
  // 移除文档点击事件监听器
  document.removeEventListener('click', handleDocumentClick)
  const editor = editorRef.value
  if (editor && handleDeleteQuote) {
    editor.removeEventListener('keydown', handleDeleteQuote)
  }
})

/**
 * 表情选择事件处理函数
 * 
 * @param {Object} emoji - 选中的表情对象
 * 
 * 当用户从表情选择器中选择表情时触发
 * 调用onEmoticonEvent插入表情到编辑器
 * 然后关闭表情选择器面板
 */
const onEmoticonSelect = (emoji) => {
  // 直接调用onEmoticonEvent处理表情
  onEmoticonEvent(emoji)
  isShowEmoticon.value = false
}

/**
 * 代码块提交事件处理函数
 * 
 * @param {Object} data - 代码块数据
 * 
 * 当用户提交代码块时触发
 * 通过emit向父组件发送code_event事件
 * 传递代码块数据并关闭代码块面板
 */
const onCodeSubmit = (data) => {
  emit('editor-event', {
    event: 'code_event',
    data,
    callBack: () => {}
  })
  isShowCode.value = false
}

/**
 * 投票提交事件处理函数
 * 
 * @param {Object} data - 投票数据
 * 
 * 当用户提交投票时触发
 * 通过emit向父组件发送vote_event事件
 * 传递投票数据并关闭投票面板
 */
const onVoteSubmit = (data) => {
  emit('editor-event', {
    event: 'vote_event',
    data,
    callBack: () => {}
  })
  isShowVote.value = false
}

// 处理编辑器内部点击事件（用于关闭引用等）
const handleEditorClick = (event) => {
  const closeButton = event.target.closest('.quote-close');

  if (closeButton) {
    const quoteElement = event.target.closest('.editor-quote');
    if (quoteElement) {
      quoteElement.remove();
      quoteData.value = null;

      handleInput({ target: editorRef.value });

      event.preventDefault();
      event.stopPropagation();
    }
  }
};
</script>

<template>
  <!-- 
    编辑器容器组件
    使用el-container布局组件创建垂直布局的编辑器
    包含工具栏和编辑区域两个主要部分
  -->
  <section class="el-container editor">
    <section class="el-container is-vertical">
      <!-- 
        工具栏区域 
        使用el-header组件作为工具栏容器
        包含各种编辑工具按钮
      -->
      <header class="el-header toolbar bdr-t">
        <div class="tools pr-30px">
          <!-- 
            表情选择器弹出框
            使用n-popover组件创建悬浮的表情选择面板
            通过trigger="click"设置点击触发
            raw属性表示内容不会被包装在额外的div中
          -->
          <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>

            <!-- 
              表情选择器组件
              通过on-select事件将选中的表情传递给onEmoticonEvent处理函数
            -->
            <MeEditorEmoticon @on-select="onEmoticonEvent" />
          </n-popover>

          <!-- 
            工具栏其他功能按钮
            通过v-for循环渲染navs数组中定义的工具按钮
            每个按钮包含图标和提示文本
            通过v-show="nav.show"控制按钮的显示/隐藏
            点击时执行nav.click定义的函数
          -->
          <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>
          <n-button class="w-80px h-30px ml-auto" type="primary">
            <template #icon>
        <n-icon>
          <IosSend />
        </n-icon>
      </template>
      发送
    </n-button>
        </div>
      </header>

      <!-- 
        编辑器主体区域
        使用el-main组件作为主要内容区域
      -->
      <main class="el-main height100">
        <!-- 
          可编辑区域
          使用contenteditable="true"使div可编辑，这是HTML5的属性
          ref="editorRef"用于获取DOM引用
          placeholder属性用于显示占位文本
          绑定多个事件处理函数处理用户交互
        -->
        <div
          ref="editorRef"
          class="custom-editor"
          contenteditable="true"
          :placeholder="placeholder"
          @input="handleInput"
          @keydown="handleKeydown"
          @paste="handlePaste"
          @focus="handleFocus"
          @blur="handleBlur"
        ></div>

        <!-- 
          @提及列表
          当用户输入@时显示的用户列表
          通过v-if="showMention"控制显示/隐藏
          使用动态样式定位列表位置
        -->
        <div
          v-if="showMention"
          class="mention-list py-5px"
          :style="{ top: mentionPosition.top + 'px', left: mentionPosition.left + 'px' }"
        >
          <ul class="max-h-140px w-163px overflow-auto hide-scrollbar">
            <li
              v-for="(member, index) in mentionList"
              :key="member.user_id || member.id"
              class="cursor-pointer px-14px h-42px"
              :class="{ 'bg-#EEE9F9': index === selectedMentionIndex }"
              @mousedown.prevent="insertMention(member)"
              @mouseover="selectedMentionIndex = index"
            >
              <div class="flex items-center border-b-1px border-b-solid border-b-#F8F8F8 h-full">
                <img class="w-26px h-26px rounded-50% mr-11px" :src="member.avatar" alt="">
                <span>{{ member.nickname }}</span>
              </div>
            </li>
          </ul>
        </div>
      </main>
    </section>
  </section>

  <!-- 
    隐藏的文件上传表单
    使用display: none隐藏表单
    包含两个文件输入框，分别用于上传图片和其他文件
    通过ref获取DOM引用
  -->
  <form enctype="multipart/form-data" style="display: none">
    <input type="file" ref="fileImageRef" accept="image/*" @change="onUploadSendImg" />
    <input type="file" ref="uploadFileRef" @change="onUploadFile" />
  </form>


</template>

<style lang="less" scoped>
/**
 * 编辑器组件样式
 * 使用CSS变量定义可复用的颜色值
 * --tip-bg-color: 提示背景色
 */
.editor {
  --tip-bg-color: rgb(241 241 241 / 90%);
  height: 100%;

  /**
   * 工具栏样式
   * 固定高度的顶部工具栏
   */
  .toolbar {
    height: 38px;
    display: flex;

    /**
     * 工具按钮容器
     * 使用flex布局排列工具按钮
     */
    .tools {
      height: 40px;
      flex: auto;
      display: flex;
      align-items: center;
      
      /**
       * 单个工具按钮样式
       * 使用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: #462AA0;
    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;
  }
  :deep(.editor-quote) {
    margin-bottom: 8px;
    padding: 8px 12px;
    background-color: var(--im-message-left-bg-color, #f5f5f5);
    border-left: 3px solid var(--im-primary-color, #409eff);
    border-radius: 4px;
    font-size: 13px;
    position: relative;
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); /* 轻微阴影效果 */
    cursor: pointer; /* 添加指针样式 */
    user-select: none; /* 防止文本选择 */
    transition: background-color 0.2s ease; /* 平滑过渡效果 */
    
    /**
     * 引用卡片悬停效果
     * 改变背景色提供视觉反馈
     */
    &:hover {
      background-color: var(--im-message-left-bg-hover-color, #eaeaea);
    }
    
    /**
     * 引用内容容器
     * 使用flex: 1占据剩余空间
     * 处理内容溢出
     */
    .quote-content-wrapper {
      flex: 1;
      overflow: hidden;
    }
    
    /**
     * 引用标题样式
     * 使用主题色显示引用来源
     */
    .quote-title {
      color: var(--im-primary-color, #409eff);
      margin-bottom: 4px;
      font-weight: 500;
    }
    
    /**
     * 引用内容样式
     * 限制显示行数，超出部分显示省略号
     * 使用-webkit-line-clamp实现多行文本截断
     */
    .quote-content {
      color: var(--im-text-color, #333);
      word-break: break-all; /* 在任意字符间断行 */
      white-space: normal; /* 允许正常换行 */
      overflow: hidden;
      text-overflow: ellipsis; /* 文本溢出显示省略号 */
      display: -webkit-box;
      -webkit-line-clamp: 2; /* 限制显示2行 */
      -webkit-box-orient: vertical;
    }
    
    /**
     * 引用图片样式
     * 限制图片大小，添加圆角
     */
    .quote-image img {
      max-width: 100px;
      max-height: 60px;
      border-radius: 3px;
      pointer-events: none; /* 防止图片被拖拽 */
    }
    
    /**
     * 引用关闭按钮样式
     * 圆形按钮，悬停时改变背景色和文字颜色
     */
    .quote-close {
      width: 18px;
      height: 18px;
      line-height: 16px;
      text-align: center;
      border-radius: 50%;
      background-color: rgba(0, 0, 0, 0.1);
      color: #666;
      cursor: pointer;
      font-size: 16px;
      margin-left: 8px;
      user-select: none;
      
      &:hover {
        background-color: rgba(0, 0, 0, 0.2);
        color: #333;
      }
    }
  }

  .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;

    /* 添加placeholder样式 */
    &:empty:before {
      content: attr(placeholder);
      color: #999;
      pointer-events: none;
    }

    /**
     * 自定义滚动条样式 - 轨道
     * 使用::-webkit-scrollbar伪元素自定义滚动条轨道
     * 设置宽度和高度为3px，背景色为透明
     */
    &::-webkit-scrollbar {
      width: 3px;
      height: 3px;
      background-color: unset;
    }

    /**
     * 自定义滚动条样式 - 滑块
     * 使用::-webkit-scrollbar-thumb伪元素自定义滚动条滑块
     * 设置圆角和透明背景色
     */
    &::-webkit-scrollbar-thumb {
      border-radius: 3px;
      background-color: transparent;
    }

    /**
     * 滚动条悬停效果
     * 当鼠标悬停在编辑器上时，显示滚动条滑块
     * 使用CSS变量适配不同主题的滚动条颜色
     */
    &:hover {
      &::-webkit-scrollbar-thumb {
        background-color: var(--im-scrollbar-thumb);
      }
    }
  }

  /**
   * 编辑器占位符样式
   * 使用:empty::before伪元素在编辑器为空时显示占位文本
   * content: attr(placeholder)获取placeholder属性的值作为显示内容
   */
  .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 {
    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: 300px;
  //   max-height: 200px;
  //   border-radius: 3px;
  //   background-color: #48484d;
  //   margin: 0px 2px;
  //   cursor: pointer;
  //   object-fit: contain; /* 保持原始比例 */
  //   display: inline-block; /* 确保图片正确显示 */
  // }

  /**
   * 表情样式
   * 设置表情图片的大小和对齐方式
   */
  .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;

  }

  /* 引用卡片样式 */
  .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;
  }

  /**
   * 编辑提示样式
   * 使用橙色背景和边框创建警示效果
   * 添加内边距、圆角和适当的字体大小
   * 使用flex布局对齐内容
   */
  .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;
  }

  /**
   * 编辑提示按钮样式
   * 移除默认按钮样式，添加鼠标指针
   * 使用margin-left: auto将按钮推到右侧
   */
  .edit-tip button {
    background: none;
    border: none;
    cursor: pointer;
    color: #d46b08;
    margin-left: auto;
  }
}

/**
 * 暗色模式样式调整
 * 使用HTML属性选择器检测暗色主题
 * 重新定义暗色模式下的CSS变量
 */
html[theme-mode='dark'] {
  .editor {
    --tip-bg-color: #48484d;
  }
}

/**
 * 隐藏滚动条样式
 * 保留滚动功能但隐藏滚动条的视觉显示
 */
.hide-scrollbar {
  /* Chrome, Safari, Edge */
  &::-webkit-scrollbar {
    width: 0;
    display: none;
  }
  
  /* Firefox */
  scrollbar-width: none;
  
  /* IE */
  -ms-overflow-style: none;
}
</style>