<template>
  <div class="mention-wrapper" ref="wrapperRef">
    <div ref="inputRef" class="mention-input"
      :style="{ height: typeof height === 'number' ? height + 'px' : height || '120px', ...(typeof width === 'number' ? { width: width + 'px' } : width ? { width } : {}), ...(typeof style === 'object' ? style : {}) }"
      :contenteditable="!see && mode !== 'select'" @input="onInput" @keydown="onKeydown" @click="onInputClick"
      :tabindex="see ? -1 : 0" :placeholder="placeholder || '请输入内容...'"></div>

    <div v-show="showDropdown && dropdownPos" class="mention-cascader-overlay" :style="overlayStyle">
      <a-cascader ref="cascaderRef" v-model:value="selectedValue" :options="cascaderOptions" :disabled="see"
        :fieldNames="{ label: 'label', value: 'value', children: 'children' }" @change="onCascaderChange"
        @keydown="handleCascaderKeydown" @dropdownVisibleChange="onDropdownVisibleChange" size="small"
        :open="showDropdown">
        <span></span>
      </a-cascader>
    </div>
  </div>
</template>

<script>
import { debounce } from 'lodash-es'; // 添加防抖功能

export default {
  name: 'MentionInput',
  computed: {
    see() {
      return this.$store?.forms?.see || false;
    }
  },
  props: {
    modelValue: {
      type: String,
      default: ''
    },
    options: {
      type: Array,
      required: true
    },

    saveSymbol: {
      type: String,
      default: '$'  // 最终保存的符号，默认 '$'
    },
    height: {
      type: [String, Number],
      default: undefined  // 输入框高度
    },
    width: {
      type: [String, Number],
      default: undefined  // 输入框宽度
    },
    placeholder: {
      type: String,
      default: undefined
    },
    mode: {
      type: String,
      default: 'input'  // 添加mode属性，默认为input模式
    },
    multiple: {
      type: Boolean,
      default: true
    },
    style: { type: [String, Object], default: "width: 100%;" }
  },
  emits: ['update:modelValue', 'change'],
  data() {
    return {
      PREFIX: '/',
      SAVE_SYMBOL: this.saveSymbol || '$',
      showDropdown: false,
      dropdownPos: null,
      triggerText: '',
      selectionRange: null,
      cascaderOptions: [],
      selectedValue: [],
      currentPathValues: [],
      currentPathLabels: [],
      optionMap: new Map(),
      pathToNameMap: new Map(),
      wrapperRef: null,
      inputRef: null,
      cascaderRef: null
    }
  },
  computed: {
    overlayStyle() {
      if (!this.dropdownPos) {
        return {};
      }

      // 计算默认位置
      let top = this.dropdownPos.top;
      let left = this.dropdownPos.left;

      // 获取窗口尺寸
      const windowWidth = window.innerWidth;
      const windowHeight = window.innerHeight;

      // 面板基本样式
      const style = {
        position: 'fixed',  // 使用 fixed 定位，相对于视窗
        top: top + 'px',
        left: left + 'px',
        zIndex: 1050,
      };

      return style;
    }
  },
  mounted() {
    // 获取引用
    this.wrapperRef = this.$refs.wrapperRef;
    this.inputRef = this.$refs.inputRef;
    this.cascaderRef = this.$refs.cascaderRef;

    // 构建选项映射
    this.optionMap = this.buildOptionMap(this.options);
    // 构建路径到名称的映射
    this.pathToNameMap = this.buildPathToNameMap(this.options);

    // 添加事件监听器处理标签点击删除
    if (this.inputRef) {
      this.inputRef.addEventListener('click', this.handleInputClick);
    }

    document.addEventListener('click', this.handleClickOutside);

    // 初始化值
    this.initializeValue();

    // 使用防抖处理输入事件
    this.debouncedOnInput = debounce(this._onInput, 100);
  },
  beforeDestroy() {
    // 清理防抖函数
    if (this.debouncedOnInput) {
      this.debouncedOnInput.cancel();
    }

    if (this.inputRef) {
      this.inputRef.removeEventListener('click', this.handleInputClick);
    }

    document.removeEventListener('click', this.handleClickOutside);
  },
  watch: {
    modelValue: {
      handler(newValue) {
        if (document.activeElement !== this.inputRef) {
          // 只有当输入框未获得焦点时才更新，避免覆盖用户的输入
          this.setValue(newValue || '');
        }
      },
      immediate: true
    },
    options: {
      handler(newOptions) {
        if (!newOptions) return;
        this.optionMap = this.buildOptionMap(newOptions);
        this.pathToNameMap = this.buildPathToNameMap(newOptions);

        // 重新初始化值
        if (this.modelValue) {
          this.setValue(this.modelValue);
        }
      },
      deep: true
    }
  },
  methods: {
    // 构建选项映射关系
    buildOptionMap(options, map = new Map()) {
      if (!options) return;
      for (const option of options) {
        // 使用 id 或 value 作为键，使用 name 或 label 作为值
        const key = option.id || option.value || '';
        const value = option.name || option.label || '';
        if (key && value) {
          map.set(key, value);
        }
        if (option.children) {
          this.buildOptionMap(option.children, map);
        }
      }
      return map;
    },

    // 构建路径到名称的映射
    buildPathToNameMap(options, currentPath = [], currentLabelPath = []) {
      if (!options) return;
      const map = new Map();

      for (const option of options) {
        // 更新当前路径，使用 id 或 value 作为路径
        const pathValue = option.id || option.value || '';
        // 使用 name 或 label 作为标签路径
        const labelValue = option.name || option.label || '';

        // 跳过空值
        if (!pathValue) continue;

        const newPath = [...currentPath, pathValue];
        const newLabelPath = [...currentLabelPath, labelValue];

        // 将当前路径映射到标签路径
        const pathStr = newPath.join('.');
        const labelStr = newLabelPath.join('/');

        map.set(pathStr, labelStr);

        // 递归处理子选项
        if (option.children) {
          const childMap = this.buildPathToNameMap(option.children, newPath, newLabelPath);
          for (const [key, value] of childMap) {
            map.set(key, value);
          }
        }
      }

      return map;
    },

    // Cascader 选择改变事件
    onCascaderChange(value, selectedOptions) {
      if (value && selectedOptions) {
        this.currentPathValues = [...value];
        this.currentPathLabels = selectedOptions.map(opt => String(opt.label || ''));
        this.insertMentionTag();
      }
    },

    // 处理 Cascader 内部键盘事件
    handleCascaderKeydown(e) {
      if (e.key === 'Escape') {
        this.showDropdown = false;
      }
    },

    // 监听下拉框可见性变化
    onDropdownVisibleChange(open) {
      // 不自动关闭，让用户选择完成后再关闭
      // showDropdown.value = open;
    },

    // 监听输入
    onInput(e) {
      if (this.mode === 'select') {
        // 在选择模式下，阻止任何输入
        e.preventDefault();
        return;
      }
      this.debouncedOnInput(e);
    },

    // 实际的输入处理方法
    _onInput(e) {
      if (this.mode === 'select') {
        // 在选择模式下，不执行输入处理
        return;
      }

      const div = e.target;

      // 每次输入都触发 change 事件，确保文本输入也被捕获
      const structured = this.parseContent(div);
      this.$emit('change', structured);
      this.$emit('update:modelValue', this.serialize(structured));

      const fullText = div.textContent || '';

      // 查找最后一个前缀（如 $）的位置
      const lastDollarIndex = fullText.lastIndexOf(this.PREFIX);
      if (lastDollarIndex === -1) {
        this.showDropdown = false;
        return;
      }

      // 提取触发文本（触发符号后的文本）
      const textBeforeCursor = this.getCurrentTextBeforeCursor();
      const dollarIndex = textBeforeCursor.lastIndexOf(this.PREFIX);

      if (dollarIndex === -1) {
        this.showDropdown = false;
        return;
      }

      const afterDollar = textBeforeCursor.slice(dollarIndex + this.PREFIX.length);

      // 如果后面有空格或其他分隔符（但不是换行），说明提及已结束
      // 换行不应该关闭提及下拉菜单
      if (afterDollar.includes(' ') || afterDollar.includes('\t')) {
        this.showDropdown = false;
        return;
      }

      this.triggerText = afterDollar;

      // 定位到前缀后的位置
      const range = document.getSelection()?.getRangeAt(0);
      if (range && this.inputRef) {
        const rect = range.getBoundingClientRect();
        // 使用 fixed 定位，所以直接用视口坐标
        this.dropdownPos = {
          top: rect.bottom + window.scrollY,
          left: rect.left + window.scrollX
        };
        this.selectionRange = range.cloneRange();

        // 更新 Cascader 选项
        // 直接使用传入的选项，假设它们已经是 CascaderOption 格式
        this.cascaderOptions = this.options;

        this.showDropdown = true;
      } else {
        this.showDropdown = false;
      }
    },

    // 获取光标前的纯文本内容
    getCurrentTextBeforeCursor() {
      const selection = window.getSelection();
      if (!selection || selection.rangeCount === 0) {
        return '';
      }

      const range = selection.getRangeAt(0).cloneRange();
      const preCaretRange = range.cloneRange();
      preCaretRange.selectNodeContents(this.inputRef);
      preCaretRange.setEnd(range.endContainer, range.endOffset);

      // 将结果中的换行符标准化为 \n
      return preCaretRange.toString().replace(/\r\n|\r/g, '\n');
    },

    // 键盘控制
    onKeydown(e) {
      if (this.mode === 'select') {
        // 在选择模式下，只允许特定按键（如 Tab、方向键、回车用于选择）
        if (e.key !== 'Tab' && e.key !== 'ArrowUp' && e.key !== 'ArrowDown' && e.key !== 'Enter' && e.key !== 'Escape') {
          e.preventDefault();
          // 如果按下的是字母数字等键，则打开下拉菜单
          if (/[a-zA-Z0-9]/.test(e.key) && !e.ctrlKey && !e.metaKey && !e.altKey) {
            this.showSelectDropdown();
          }
          return;
        }
      }

      if (!this.showDropdown) {
        // 如果下拉菜单未显示，处理普通键盘事件
        if (e.key === 'Backspace') {
          this.handleBackspace(e);
        } else if (e.key === 'Enter') {
          // 处理回车键，插入换行
          e.preventDefault();
          const selection = window.getSelection();
          if (selection && selection.rangeCount > 0) {
            const range = selection.getRangeAt(0);
            range.deleteContents();

            // 插入换行符
            const br = document.createElement('br');
            range.insertNode(br);

            // 将光标移动到新行
            const newRange = document.createRange();
            newRange.setStartAfter(br);
            newRange.collapse(true);

            selection.removeAllRanges();
            selection.addRange(newRange);
          }

          // 触发 change 事件
          this.$nextTick(() => {
            const structured = this.parseContent(this.inputRef);
            this.$emit('change', structured);
            this.$emit('update:modelValue', this.serialize(structured));
          });
        }
        return;
      }

      if (e.key === 'Escape') {
        this.showDropdown = false;
      }
    },

    // 插入提及标签
    insertMentionTag() {
      if (!this.inputRef) return;

      // 如果是单选模式，先清空现有内容
      if (!this.multiple) {
        this.inputRef.innerHTML = '';
      }

      // 如果没有选择范围（比如在select模式下），创建一个默认的范围到输入框末尾
      let range;
      if (this.selectionRange) {
        range = this.selectionRange.cloneRange();
      } else {
        // 如果没有selectionRange，说明可能是select模式，创建默认范围
        range = document.createRange();
        range.selectNodeContents(this.inputRef);
        range.collapse(false); // 折叠到末尾
      }

      // 获取当前光标位置的文本节点和偏移量
      let textNode = null;
      let offset = 0;

      if (range.startContainer.nodeType === Node.TEXT_NODE) {
        textNode = range.startContainer;
        offset = range.startOffset;
      } else {
        // 如果光标在元素节点内，尝试找到最近的文本节点
        const walker = document.createTreeWalker(
          this.inputRef,
          NodeFilter.SHOW_TEXT,
          null
        );
        let node = null;
        while (walker.nextNode()) {
          if (walker.currentNode === range.startContainer || walker.currentNode.contains(range.startContainer)) {
            node = walker.currentNode;
          }
        }
        if (node) {
          textNode = node;
          // 计算偏移量
          offset = node.textContent?.length || 0;
        }
      }

      // 创建完整的路径值和标签
      const fullValue = this.SAVE_SYMBOL + this.currentPathValues.join('.');
      const fullLabel = this.currentPathLabels.join('/');

      // 在当前位置插入标签（只在后方添加空格）
      const mentionEl = document.createElement('span');
      mentionEl.className = 'mention-tag';
      mentionEl.contentEditable = 'false';
      mentionEl.dataset.value = fullValue;
      mentionEl.innerHTML = `
              <span class="tag-close">×</span>
              <span class="tag-content">${fullLabel}</span>
          `;

      // 确定插入位置
      let insertPosition = offset;
      if (textNode && textNode.textContent) {
        // 如果是在提及模式下，查找并移除触发符号
        const text = textNode.textContent;
        const textBeforeCursor = text.substring(0, offset);
        const dollarIndex = textBeforeCursor.lastIndexOf(this.PREFIX);

        if (dollarIndex !== -1) {
          // 删除从触发符号开始到当前位置的内容
          const beforeDollar = text.substring(0, dollarIndex);
          const afterCurrent = text.substring(offset);

          // 更新文本节点内容，保留前后内容
          textNode.textContent = beforeDollar + afterCurrent;

          // 重新计算插入位置
          insertPosition = beforeDollar.length;
        }
      }

      // 创建新的范围来插入标签
      const newRange = document.createRange();
      try {
        if (textNode && textNode.textContent) {
          // 确保偏移量不超过文本节点长度
          const safeOffset = Math.min(insertPosition, textNode.length);
          newRange.setStart(textNode, safeOffset);
          newRange.setEnd(textNode, safeOffset);
        } else {
          // 如果没有文本节点，直接添加到容器末尾
          newRange.selectNodeContents(this.inputRef);
          newRange.collapse(false);
        }

        // 插入标签和后方空格
        newRange.insertNode(mentionEl);
        const spaceAfter = document.createTextNode(' ');
        mentionEl.parentNode?.insertBefore(spaceAfter, mentionEl.nextSibling);

        // 在标签后插入零宽字符作为光标位置
        const cursorMarker = document.createTextNode('\u200B');
        mentionEl.parentNode?.insertBefore(cursorMarker, spaceAfter.nextSibling);

        // 设置光标位置
        const finalRange = document.createRange();
        finalRange.setStart(cursorMarker, 0);
        finalRange.setEnd(cursorMarker, 0);

        const selection = window.getSelection();
        if (selection) {
          selection.removeAllRanges();
          selection.addRange(finalRange);
        }
      } catch (e) {
        // 如果出现索引错误，使用替代方案
        console.error("Error inserting mention tag:", e);

        // 创建零宽字符用于光标定位
        const cursorMarker = document.createTextNode('\u200B');

        // 直接在光标位置插入整个HTML片段
        const fragment = document.createDocumentFragment();
        fragment.appendChild(mentionEl);
        fragment.appendChild(cursorMarker);

        range.deleteContents();
        range.insertNode(fragment);

        // 设置光标到零宽字符位置
        const selection = window.getSelection();
        if (selection) {
          const cursorRange = document.createRange();
          cursorRange.setStart(cursorMarker, 0);
          cursorRange.setEnd(cursorRange, 0);
          selection.removeAllRanges();
          selection.addRange(cursorRange);
        }
      }

      // 清理状态
      this.showDropdown = false;
      this.triggerText = '';
      this.selectionRange = null;
      this.cascaderOptions = [];
      this.currentPathValues = [];
      this.currentPathLabels = [];

      // 触发 change
      this.$nextTick(() => {
        const structured = this.parseContent(this.inputRef);
        this.$emit('change', structured);
        this.$emit('update:modelValue', this.serialize(structured));
      });
    },

    // 处理退格键
    handleBackspace(e) {
      const selection = window.getSelection();
      if (!selection || selection.rangeCount === 0) return;

      // 如果是单选模式，清空整个输入框
      if (!this.multiple) {
        this.inputRef.innerHTML = '';
        e.preventDefault();

        // 触发 change 事件
        this.$nextTick(() => {
          const structured = this.parseContent(this.inputRef);
          this.$emit('change', structured);
          this.$emit('update:modelValue', this.serialize(structured));
        });
        return;
      }

      const range = selection.getRangeAt(0);
      const startContainer = range.startContainer;
      const startOffset = range.startOffset;

      // 检查光标位置，看是否在标签前面
      if (startContainer.nodeType === Node.TEXT_NODE) {
        const textNode = startContainer;
        if (startOffset > 0) {
          // 检查光标前的字符
          const text = textNode.textContent || '';
          if (startOffset <= text.length) {
            const prevChar = text[startOffset - 1];
            if (prevChar === '\u200B') { // 零宽字符，通常在标签后
              // 检查前一个节点是否是标签
              const prevNode = textNode.previousSibling;
              if (prevNode && prevNode.classList && prevNode.classList.contains('mention-tag')) {
                // 删除标签和前后空格
                const prevSpace = prevNode.previousSibling;
                const nextSpace = prevNode.nextSibling;

                // 删除标签前的空格节点（如果存在且只包含空格）
                if (prevSpace && prevSpace.nodeType === Node.TEXT_NODE && (prevSpace.textContent || '').trim() === '') {
                  prevSpace.remove();
                }

                prevNode.remove();

                // 删除标签后的空格节点（如果存在且只包含空格）
                if (nextSpace && nextSpace.nodeType === Node.TEXT_NODE && (nextSpace.textContent || '').trim() === '') {
                  nextSpace.remove();
                }

                e.preventDefault();

                // 触发 change 事件
                this.$nextTick(() => {
                  const structured = this.parseContent(this.inputRef);
                  this.$emit('change', structured);
                  this.$emit('update:modelValue', this.serialize(structured));
                });
              }
            }
          }
        }
      } else if (startContainer.nodeType === Node.ELEMENT_NODE) {
        // 光标在元素节点内
        const element = startContainer;
        if (element.classList.contains('mention-input')) {
          // 检查光标前是否有标签
          const childNodes = Array.from(element.childNodes);
          if (startOffset > 0 && startOffset <= childNodes.length) {
            const prevNode = childNodes[startOffset - 1];
            if (prevNode && prevNode.classList && prevNode.classList.contains('mention-tag')) {
              // 删除标签和前后空格
              const prevSpace = prevNode.previousSibling;
              const nextSpace = prevNode.nextSibling;

              // 删除标签前的空格节点（如果存在且只包含空格）
              if (prevSpace && prevSpace.nodeType === Node.TEXT_NODE && (prevSpace.textContent || '').trim() === '') {
                prevSpace.remove();
              }

              prevNode.remove();

              // 删除标签后的空格节点（如果存在且只包含空格）
              if (nextSpace && nextSpace.nodeType === Node.TEXT_NODE && (nextSpace.textContent || '').trim() === '') {
                nextSpace.remove();
              }

              e.preventDefault();

              // 触发 change 事件
              this.$nextTick(() => {
                const structured = this.parseContent(this.inputRef);
                this.$emit('change', structured);
                this.$emit('update:modelValue', this.serialize(structured));
              });
            }
          }
        }
      }
    },

    // 点击输入框时更新光标（用于后续触发）
    onInputClick() {
      // 如果模式为 'select'，则点击时显示下拉选项
      if (this.mode === 'select') {
        this.showSelectDropdown();
      } else {
        // 原有的输入模式行为
        const sel = window.getSelection();
        if (sel && sel.rangeCount > 0) {
          this.selectionRange = sel.getRangeAt(0);
        }
      }
    },

    // 显示选择模式下的下拉选项
    showSelectDropdown() {
      const rect = this.inputRef.getBoundingClientRect();

      // 使用 fixed 定位，所以直接用视口坐标
      this.dropdownPos = {
        top: rect.bottom + window.scrollY,
        left: rect.left + window.scrollX
      };

      // 在选择模式下，也需要设置selectionRange，以便选择后可以插入值
      if (this.mode === 'select') {
        const selection = window.getSelection();
        if (selection && selection.rangeCount > 0) {
          this.selectionRange = selection.getRangeAt(0);
        } else {
          // 如果没有选择区域，创建一个默认的范围到输入框末尾
          const range = document.createRange();
          range.selectNodeContents(this.inputRef);
          range.collapse(false); // 移动到末尾
          this.selectionRange = range;
        }
      }

      // 更新 Cascader 选项
      this.cascaderOptions = this.options;

      this.showDropdown = true;
    },

    // 解析内容
    parseContent(div) {
      const result = [];

      for (const node of div.childNodes) {
        if (node.nodeType === Node.TEXT_NODE) {
          const text = node.textContent || '';
          if (text) { // 保留所有文本内容，包括换行符和空格
            result.push({ type: 'text', value: text });
          }
        } else if (node.classList.contains('mention-tag')) {
          const el = node;
          const value = el.dataset.value || '';
          const label = el.querySelector('.tag-content')?.textContent || '';
          result.push({
            type: 'mention',
            value: value,
            name: label // 使用标签内容作为名称
          });
        } else if (node.nodeType === Node.ELEMENT_NODE) {
          // 处理其他可能的元素
          const element = node;
          if (element.tagName === 'BR') { // 处理换行符
            result.push({ type: 'text', value: '\n' });
          } else {
            // 对于其他元素，递归解析其子节点以保留内部结构
            const childResult = this.parseContent(element);
            result.push(...childResult);
          }
        }
      }

      // 合并相邻的文本节点
      const mergedResult = [];
      for (const item of result) {
        if (item.type === 'text' && mergedResult.length > 0 && mergedResult[mergedResult.length - 1].type === 'text') {
          // 合并相邻的文本节点
          mergedResult[mergedResult.length - 1].value += item.value;
        } else {
          mergedResult.push(item);
        }
      }

      return mergedResult;
    },

    // 序列化（用于 v-model）
    serialize(data) {
      let result = '';
      for (let i = 0; i < data.length; i++) {
        const item = data[i];
        if (item.type === 'mention') {
          // 对于提及项，直接使用原始值，不需要额外添加空格（已在插入时添加）
          result += item.value;
        } else {
          result += item.value;
        }
      }
      return result;
    },

    // 点击外部关闭下拉
    handleClickOutside(e) {
      if (
        this.inputRef?.contains(e.target) ||
        // 检查是否点击了级联选择器内部
        e.target.closest('.ant-cascader-menus')
      ) return;
      this.showDropdown = false;
    },

    // 处理输入框内的点击事件（特别是标签上的关闭按钮）
    handleInputClick(e) {
      const target = e.target;

      // 如果点击的是标签的关闭按钮
      if (target.classList.contains('tag-close')) {
        const tagElement = target.parentElement;
        if (tagElement && tagElement.classList.contains('mention-tag')) {
          // 如果是单选模式，清空整个输入框
          if (!this.multiple) {
            this.inputRef.innerHTML = '';
          } else {
            // 删除标签和前后空格
            const prevSpace = tagElement.previousSibling;
            const nextSpace = tagElement.nextSibling;

            // 删除标签前的空格节点（如果存在且只包含空格）
            if (prevSpace && prevSpace.nodeType === Node.TEXT_NODE && (prevSpace.textContent || '').trim() === '') {
              prevSpace.remove();
            }

            tagElement.remove();

            // 删除标签后的空格节点（如果存在且只包含空格）
            if (nextSpace && nextSpace.nodeType === Node.TEXT_NODE && (nextSpace.textContent || '').trim() === '') {
              nextSpace.remove();
            }
          }

          // 触发 change 事件
          this.$nextTick(() => {
            const structured = this.parseContent(this.inputRef);
            this.$emit('change', structured);
            this.$emit('update:modelValue', this.serialize(structured));
          });
        }
      } else if (target.classList.contains('mention-tag')) {
        // 如果点击标签本身，将光标移到标签后
        const cursorMarker = document.createTextNode('\u200B');
        target.parentNode?.insertBefore(cursorMarker, target.nextSibling);

        const newRange = document.createRange();
        newRange.setStart(cursorMarker, 0);
        newRange.setEnd(cursorMarker, 0);

        const sel = window.getSelection();
        if (sel) {
          sel.removeAllRanges();
          sel.addRange(newRange);
        }
      }
    },

    // 添加方法来设置值（用于外部传入值的反显）
    setValue(value) {
      if (this.inputRef) {
        this.inputRef.innerHTML = '';

        if (!value) return;

        // 解析值并重建内容
        let htmlContent = '';
        let remainingText = value;
        let lastIndex = 0;

        // 匹配 自定义符号后跟着标识符格式
        // 表达式以 $ 开头，以空格或字符串结尾
        // 支持格式：$aaa, $aaa.bbb, $xxx-bbb, $aaa_bb, $user_name.first-name 等
        // 支持任意非空白字符（包括字母、数字、符号、中文、-、_ 等）
        const mentionRegex = new RegExp(`\\${this.SAVE_SYMBOL}[^\\s]+(?=\\s|$)`, 'g');
        let match;

        while ((match = mentionRegex.exec(remainingText)) !== null) {
          // 添加匹配前的文本
          if (match.index > lastIndex) {
            const textBefore = remainingText.substring(lastIndex, match.index);
            htmlContent += this.convertTextToHtml(textBefore);
          }

          // 创建标签
          const fullMatch = match[0];
          const pathWithoutPrefix = fullMatch.substring(this.SAVE_SYMBOL.length); // 移除保存符号

          // 从路径到名称的映射中获取标签名称
          let label = this.pathToNameMap.get(pathWithoutPrefix) || pathWithoutPrefix;

          // 创建标签（不在这里添加空格，空格在插入时处理）
          htmlContent += `<span class="mention-tag" contenteditable="false" data-value="${fullMatch}">
                      <span class="tag-close">×</span>
                      <span class="tag-content">${this.escapeHtml(label)}</span>
                  </span>`;

          lastIndex = match.index + match[0].length;
        }

        // 添加最后剩余的文本
        if (lastIndex < remainingText.length) {
          const remaining = remainingText.substring(lastIndex);
          htmlContent += this.convertTextToHtml(remaining);
        }

        // 在末尾添加零宽字符作为光标位置
        htmlContent += '\u200B';

        // 将换行符转换为 <br> 标签以便在 contenteditable 中正确显示
        this.inputRef.innerHTML = htmlContent.replace(/\n/g, '<br>');
      }
    },

    // 转义HTML特殊字符
    escapeHtml(text) {
      const div = document.createElement('div');
      div.textContent = text;
      return div.innerHTML;
    },

    // 将文本转换为HTML，特别处理换行符
    convertTextToHtml(text) {
      // 将换行符替换为 <br> 标签
      const escaped = this.escapeHtml(text);
      return escaped.replace(/\n/g, '<br>');
    },

    // 初始化值
    initializeValue() {
      if (this.modelValue) {
        this.setValue(this.modelValue);
      }
    }
  }
}
</script>

<style scoped>
.mention-wrapper {
  position: relative;
  width: 100%;
  max-width: 100%;
  overflow: hidden;
}

/* ================= 输入区域（textarea 行为） ================= */

.mention-input {
  min-height: 32px;
  padding: 4px 6px;
  /* 减小内边距以适应单行模式 */
  width: 100%;
  box-sizing: border-box;

  border: 1px solid #d9d9d9;
  border-radius: 4px;
  background: var(--background-color);

  font-size: 14px;
  line-height: 1.6;
  color: rgba(0, 0, 0, 0.88);

  white-space: pre-wrap;
  word-break: break-word;
  overflow-y: auto;
  /* 启用垂直滚动 */
  overflow-x: hidden;
  /* 防止水平滚动 */
  /* 禁用调整大小功能 */
  resize: none;

  outline: none;
  /* 确保换行符正确显示 */
  display: block;
  overflow-wrap: break-word;
  white-space: pre-wrap;
  word-wrap: break-word;
}

/* 隐藏滚动条样式 */
.mention-input::-webkit-scrollbar {
  width: 0;
  height: 0;
}

.mention-input::-webkit-scrollbar-track {
  background: transparent;
}

.mention-input::-webkit-scrollbar-thumb {
  background: transparent;
  border-radius: 0;
}

.mention-input::-webkit-scrollbar-thumb:hover {
  background: transparent;
}

.mention-input:focus {
  border-color: #40a9ff;
}

.mention-input:empty::before {
  content: attr(placeholder);
  color: #bfbfbf;
}

.mention-input :deep(.mention-tag) {
  display: inline-flex;
  align-items: center;
  background: #e6f7ff;
  border-radius: 4px;
  padding: 0 4px 0 4px;
  margin: 0 2px;
  height: 24px;
  font-size: 12px;
  line-height: 22px;
  color: #1890ff;
  white-space: nowrap;
  vertical-align: center;
}

.mention-input :deep(.mention-tag .tag-content) {
  margin-left: 4px;
}

.mention-input :deep(.mention-tag .tag-close) {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #b4bdb4;
  color: white;
  font-size: 10px;
  cursor: pointer;
}

.mention-input :deep(.mention-tag .tag-close:hover) {
  background: #ff4d4f;
}

/* ================= 下拉面板样式 ================= */

.mention-cascader-overlay {
  position: fixed;
  z-index: 1050;
}
</style>