<template>
  <div class="rich-editor-root">
    <!-- 工具栏 -->
    <div class="toolbar">
      <button class="tool-btn" type="button" @click="execCommand('bold')"><b>B</b></button>
      <button class="tool-btn" type="button" @click="execCommand('italic')"><i>I</i></button>
      <button class="tool-btn" type="button" @click="openImagePicker">{{ $t('common.insertImage') || '插入图片' }}</button>
      <button class="tool-btn" type="button" @click="clear">清空</button>
    </div>

    <!-- 隐藏的文件输入 -->
    <input
      ref="fileInputRef"
      class="hidden-input"
      type="file"
      accept="image/*"
      multiple
      @change="handleSelectFiles"
    />

    <!-- 编辑器区域 -->
    <div
      ref="editorRef"
      class="user-input rich-editor"
      contenteditable="true"
      :data-placeholder="placeholder || '请输入文本...'"
      @input="handleInput"
      @keyup="handleKeyup"
      @click="handleEditorClick"
      @keydown="handleKeydown"
      @paste="handlePaste"
    ></div>

    <!-- @ 图片选择面板 -->
    <div v-if="mentionVisible" class="mention-panel">
      <div
        v-for="(item, idx) in mentionImageList"
        :key="item.url"
        class="mention-item"
        @mousedown.prevent="insertMentionImage(item)"
      >
        <img :src="item.url" class="mention-thumb" />
        <span class="mention-label">@图{{ idx + 1 }}</span>
      </div>
      <div v-if="mentionImageList.length === 0" class="mention-empty">
        {{ $t('common.noImageToMention') || '暂无可引用图片' }}
      </div>
    </div>
  </div>
</template>

<script>
import { nextTick, onMounted, ref, watch } from 'vue'
import { uploadFile, extractUploadUrlFromResponse, PORTAL_TENCENT_COS_UPLOAD_URL } from '@/utils/file'

export default {
  name: 'RichTextEditor',
  props: {
    modelValue: {
      type: String,
      default: ''
    },
    placeholder: {
      type: String,
      default: '请输入文本生成视频...'
    },
    uploadedImages: {
      type: Array,
      default: () => []
    }
  },
  emits: ['update:modelValue', 'text-change', 'image-upload'],
  setup(props, { emit }) {
    const editorRef = ref(null)
    const fileInputRef = ref(null)
    const savedSelectionRange = ref(null)
    const mentionVisible = ref(false)
    const mentionImageList = ref([])
    const MAX_IMAGE_COUNT = 4

    // 执行编辑器命令
    const execCommand = (command) => {
      if (!editorRef.value) return
      editorRef.value.focus()
      document.execCommand(command, false, null)
      handleInput()
    }

    // 打开图片选择器
    const openImagePicker = () => {
      if (fileInputRef.value) {
        fileInputRef.value.click()
      }
    }

    // 处理文件选择 - 上传到服务器
    const handleSelectFiles = async (event) => {
      const files = event.target.files
      if (!files.length) return

      for (let file of files) {
        if (file.type.startsWith('image/')) {
          try {
            // 显示上传中提示
            const loading = window.$message ? window.$message.loading('上传中...') : null
            
            // 上传到后端
            const res = await uploadFile({
              url: PORTAL_TENCENT_COS_UPLOAD_URL,
              file: file,
              name: 'file'
            })
            
            const imageUrl = extractUploadUrlFromResponse(res)
            if (res && (Number(res.code) === 200 || res.code === 200) && imageUrl) {
              insertImage(imageUrl, file.name)
              
              // 通知父组件有新图片上传成功（用于@功能）
              emit('image-upload', { url: imageUrl, name: file.name })
            } else {
              console.error('上传失败:', res)
              alert('图片上传失败')
            }
          } catch (error) {
            console.error('上传图片出错:', error)
            alert('图片上传失败: ' + (error.message || '未知错误'))
          }
        }
      }

      // 清空input
      event.target.value = ''
    }

    // 插入图片
    const insertImage = (url, name = 'image') => {
      if (!editorRef.value) return

      editorRef.value.focus()
      const selection = window.getSelection()
      if (!selection) return

      const img = document.createElement('img')
      img.src = url
      img.alt = name
      img.style.maxWidth = '100%'
      img.style.height = 'auto'
      img.style.margin = '4px 0'
      img.setAttribute('data-image-name', name)

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

      // 添加空格
      const space = document.createTextNode(' ')
      range.setStartAfter(img)
      range.setEndAfter(img)
      range.insertNode(space)

      handleInput()
    }

    // 处理输入
    const handleInput = () => {
      if (!editorRef.value) return
      const content = editorRef.value.innerHTML
      emit('update:modelValue', content)
      emit('text-change', content)
    }

    // 处理按键
    const handleKeyup = (e) => {
      if (e.key === '@') {
        showMentionPanel()
      } else if (e.key === 'Escape' && mentionVisible.value) {
        mentionVisible.value = false
      }
    }

    const handleKeydown = (e) => {
      if (e.key === '@') {
        // 保存当前选择位置
        const selection = window.getSelection()
        if (selection && selection.rangeCount > 0) {
          savedSelectionRange.value = selection.getRangeAt(0).cloneRange()
        }
      }
    }

    const insertPlainTextAtCursor = (text) => {
      if (!editorRef.value || text == null) return
      const normalized = String(text).replace(/\r\n/g, '\n').replace(/\r/g, '\n')
      editorRef.value.focus()
      const selection = window.getSelection()
      if (!selection || selection.rangeCount === 0) return
      let range = selection.getRangeAt(0)
      if (!editorRef.value.contains(range.commonAncestorContainer)) {
        const r = document.createRange()
        r.selectNodeContents(editorRef.value)
        r.collapse(false)
        selection.removeAllRanges()
        selection.addRange(r)
        range = selection.getRangeAt(0)
      }
      range.deleteContents()
      const lines = normalized.split('\n')
      const fragment = document.createDocumentFragment()
      lines.forEach((line, index) => {
        if (line) fragment.appendChild(document.createTextNode(line))
        if (index < lines.length - 1) fragment.appendChild(document.createElement('br'))
      })
      range.insertNode(fragment)
      range.collapse(false)
      selection.removeAllRanges()
      selection.addRange(range)
    }

    const handlePaste = (e) => {
      if (!editorRef.value) return
      const cd = e.clipboardData
      if (!cd) return
      const items = cd.items
      if (items) {
        for (let i = 0; i < items.length; i++) {
          if (items[i].type.indexOf('image') !== -1) {
            const blob = items[i].getAsFile()
            const reader = new FileReader()
            reader.onload = (event) => {
              insertImage(event.target.result, 'pasted-image')
            }
            reader.readAsDataURL(blob)
            e.preventDefault()
            return
          }
        }
      }
      let text = cd.getData('text/plain') || ''
      if (!text && cd.getData('text/html')) {
        const tmp = document.createElement('div')
        tmp.innerHTML = cd.getData('text/html')
        text = tmp.innerText || ''
      }
      e.preventDefault()
      insertPlainTextAtCursor(text)
      handleInput()
    }

    // 显示 @ 面板
    const showMentionPanel = () => {
      if (props.uploadedImages && props.uploadedImages.length > 0) {
        mentionImageList.value = props.uploadedImages.slice(0, MAX_IMAGE_COUNT)
        mentionVisible.value = true
      }
    }

    // 插入 @ 图片
    const insertMentionImage = (imageItem) => {
      if (!editorRef.value || !savedSelectionRange.value) {
        mentionVisible.value = false
        return
      }

      editorRef.value.focus()

      const selection = window.getSelection()
      if (selection) {
        selection.removeAllRanges()
        selection.addRange(savedSelectionRange.value)
      }

      const img = document.createElement('img')
      img.src = imageItem.url
      img.alt = '@图片'
      img.style.maxWidth = '60px'
      img.style.height = 'auto'
      img.style.verticalAlign = 'middle'
      img.setAttribute('data-mention', 'true')

      const range = savedSelectionRange.value
      range.deleteContents()
      range.insertNode(img)

      // 添加空格
      const space = document.createTextNode(' ')
      range.setStartAfter(img)
      range.setEndAfter(img)
      range.insertNode(space)

      mentionVisible.value = false
      handleInput()
    }

    // 清空编辑器
    const clear = () => {
      if (!editorRef.value) return
      editorRef.value.innerHTML = ''
      handleInput()
    }

    // 处理编辑器点击
    const handleEditorClick = () => {
      if (mentionVisible.value) {
        mentionVisible.value = false
      }
    }

    // 监听 props 变化
    watch(() => props.modelValue, (newValue) => {
      if (editorRef.value && editorRef.value.innerHTML !== newValue) {
        editorRef.value.innerHTML = newValue || ''
      }
    })

    // 监听上传的图片列表更新
    watch(() => props.uploadedImages, (newImages) => {
      mentionImageList.value = newImages || []
    }, { immediate: true })

    onMounted(() => {
      if (editorRef.value) {
        editorRef.value.innerHTML = props.modelValue || ''
      }
    })

    return {
      editorRef,
      fileInputRef,
      mentionVisible,
      mentionImageList,
      execCommand,
      openImagePicker,
      handleSelectFiles,
      handleInput,
      handleKeyup,
      handleKeydown,
      handlePaste,
      handleEditorClick,
      insertMentionImage,
      clear
    }
  }
}
</script>

<style lang="less" scoped>
.rich-editor-root {
  position: relative;
  margin-bottom: 16px;
}

.toolbar {
  display: flex;
  gap: 8px;
  margin-bottom: 8px;
  padding: 8px;
  background: #1a1b20;
  border-radius: 6px;
  border: 1px solid rgba(255,255,255,0.1);
  
  .tool-btn {
    padding: 6px 12px;
    background: rgba(255,255,255,0.1);
    border: none;
    border-radius: 4px;
    color: #fff;
    cursor: pointer;
    font-size: 14px;
    
    &:hover {
      background: rgba(255,255,255,0.2);
    }
  }
}

.rich-editor {
  min-height: 120px;
  padding: 12px;
  background: #1a1b20;
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 6px;
  color: #fff;
  line-height: 1.6;
  font-size: 14px;
  outline: none;
  overflow-y: auto;

  /* 覆盖粘贴残留的内联颜色，保证深底上始终可读 */
  :deep(*) {
    color: #fff !important;
  }

  &:empty:before {
    content: attr(data-placeholder);
    color: #666;
    pointer-events: none;
  }
  
  img {
    max-width: 100%;
    height: auto;
    margin: 4px 0;
    border-radius: 4px;
  }
}

.mention-panel {
  position: absolute;
  top: 100%;
  left: 0;
  background: #1f2128;
  border: 1px solid #3a3d47;
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  z-index: 1000;
  max-height: 200px;
  overflow-y: auto;
  width: 280px;
  
  .mention-item {
    display: flex;
    align-items: center;
    padding: 8px 12px;
    cursor: pointer;
    border-bottom: 1px solid rgba(255,255,255,0.1);
    
    &:hover {
      background: #2a2d38;
    }
    
    &:last-child {
      border-bottom: none;
    }
    
    .mention-thumb {
      width: 40px;
      height: 40px;
      object-fit: cover;
      border-radius: 4px;
      margin-right: 12px;
    }
    
    .mention-label {
      color: #a1a4b3;
      font-size: 13px;
    }
  }
  
  .mention-empty {
    padding: 20px;
    text-align: center;
    color: #666;
    font-size: 13px;
  }
}

.hidden-input {
  display: none;
}
</style>
