<template>
  <div class="editor-container">
    <div id="editor" />
    <!-- eslint-disable-next-line -->
    <!-- <div id="content-editor-view" class="view-box" v-html="modelValue"/> -->
    <Loading v-if="loading" />

    <!-- 图片调整模态框 -->
    <div
      v-if="showImageModal" class="image-resize-modal" :style="{
        top: modalPosition.top + 'px',
        left: modalPosition.left + 'px'
      }"
    >
      <div class="modal-content">
        <!-- 一行显示：缩放控制、宽度、高度 -->
        <div class="controls-row">
          <div class="zoom-controls">
            <button :disabled="currentZoom <= minZoom" class="zoom-btn" title="缩小 (10%)" @click="zoomOut">
              <span>-</span>
            </button>
            <span class="zoom-display">{{ currentZoom && Math.round(currentZoom * 100) }}%</span>
            <button :disabled="currentZoom >= maxZoom" class="zoom-btn" title="放大 (10%)" @click="zoomIn">
              <span>+</span>
            </button>
          </div>

          <div class="size-input-group">
            <label>宽度:</label>
            <input v-model="imageSize.width" type="number" @input="updateImageSize" @keydown.enter.prevent />
            <span>px</span>
          </div>

          <div class="size-input-group">
            <label>高度:</label>
            <input v-model="imageSize.height" type="number" @input="updateImageSize" @keydown.enter.prevent />
            <span>px</span>
          </div>
        </div>
        <button class="close-btn" title="关闭" @click="closeImageModal">×</button>
      </div>
    </div>
  </div>
</template>

<script>
import Common from '../common/Common';
import { message } from 'ant-design-vue';
import { ajaxApiFile } from '../common/utils.js';
import { DownloadService, Notify } from 'pc-component-v3';

export default {
  components: {
    DownloadService,
  },
  props: {
    modelValue: {
      type: String,
      default: '',
    },
    className: {
      type: String,
      default: '',
    },
  },
  emits: ['update:modelValue'],

  data: function () {
    return {
      loading: false,
      // 图片调整模态框相关数据
      showImageModal: false,
      currentImage: null,
      originalImageSize: { width: 0, height: 0 },
      imageSize: { width: 0, height: 0 },
      modalPosition: { top: 0, left: 0 },
      currentZoom: 1,
      minZoom: 0.1, // 最小10%
      maxZoom: 5.0, // 最大500%
      contentChangeTimer: null, // 添加防抖定时器
    };
  },

  watch: {
    modelValue(newVal) {
      if ($('#editor').trumbowyg('html') !== newVal) {
        $('#editor').trumbowyg('html', newVal || '');
      }
    },
  },

  mounted() {
    const _self = this;
    // 附件上传
    $.trumbowyg.plugins.attach = {
      init: function (trumbowyg) {
        trumbowyg.addBtnDef('attach', {
          fn: function () {
            // 1. 保存当前选区
            trumbowyg.saveRange();

            const input = document.createElement('input');
            input.type = 'file';
            input.style.display = 'none';
            document.body.appendChild(input);
            input.click();
            input.onchange = function () {
              var file = input.files[0];
              _self.uploadFile(file, function (fileName) {
                // 2. 恢复选区
                trumbowyg.restoreRange();
                trumbowyg.syncCode(); // 保证内容同步
                // 3. 插入HTML
                trumbowyg.execCmd('insertHTML',
                  `<a class="trumbowyg-attachment-link" class-name="${_self.className}" file-name="${fileName}" style="color:#337ab7;" 
                  target="_blank">${file.name}</a><span><br></span><br>`,
                );
                document.body.removeChild(input);
              });
            };
          },
          hasIcon: true,
          ico: 'attach',
          text: '上传附件',
          title: '上传附件',
        });
      },
    };
    $.trumbowyg.plugins.image = {
      init: function (trumbowyg) {
        trumbowyg.addBtnDef('image', {
          title: '图片',
        });
      },
    };
    // 图片上传
    $.trumbowyg.plugins.imageUpload = {
      init: function (trumbowyg) {
        trumbowyg.addBtnDef('imageUpload', {
          hasIcon: true,
          ico: 'upload',
          text: '上传图片',
          title: '上传图片',
          fn: function () {
            trumbowyg.saveRange();
            const input = document.createElement('input');
            input.type = 'file';
            input.accept = 'image/*';
            input.style.display = 'none';
            document.body.appendChild(input);
            input.click();
            input.onchange = function () {
              var file = input.files[0];
              if (file) {
                _self.uploadImg(file, function (imagUrl) {
                  trumbowyg.restoreRange();
                  trumbowyg.syncCode();
                  trumbowyg.execCmd('insertHTML', `<img src="${imagUrl}" alt="图片" />`);
                  document.body.removeChild(input);
                });
              } else {
                document.body.removeChild(input);
              }
            };
          },
        });
      },
    };

    // 初始化编辑器
    $('#editor').trumbowyg({
      // svgPath: '../trumbowyg/icons.svg',
      svgPath: Common.getRootPath() + '/static/trumbowyg/icons/icons.svg',
      btnsDef: {
        image: {
          dropdown: ['insertImage', 'imageUpload'],
          ico: 'insertImage',
        },
      },
      btns: [
        // ['viewHTML'],
        ['formatting'],
        ['strong', 'em', 'del'],
        ['link'],
        'image',
        ['attach'],
        ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'],
        ['unorderedList', 'orderedList'],
        ['horizontalRule'],
        ['undo', 'redo'],

        ['fullscreen'],
      ],
      autogrow: true,
      imageWidthModalEdit: true,
      lang: _self.$i18n.locale == 'zh-CN' ? 'zh_cn' : 'en',
      plugins: {
        attach: true,
        imageUpload: true,
      },
    });

    // 粘贴图片特殊处理(粘贴到光标处)
    $('#editor').on('paste', function (e) {
      const clipboardData = e.originalEvent.clipboardData;
      if (!clipboardData) return;
      let handled = false;

      // 获取 trumbowyg 实例
      const trumbowyg = $('#editor').data('trumbowyg');

      for (let i = 0; i < clipboardData.items.length; i++) {
        const item = clipboardData.items[i];
        if (item.type.indexOf('image') !== -1) {
          const file = item.getAsFile();
          if (file) {
            handled = true;

            // 插入临时文本作为标记
            const tempId = 'img-placeholder-' + Date.now();
            if (trumbowyg) {
              trumbowyg.execCmd('insertText', `[图片上传中${tempId}]`);
            }

            // 上传图片
            _self.uploadImg(file, function (imagUrl) {
              // 上传完成后，替换临时文本为图片
              const html = $('#editor').trumbowyg('html');
              const newHtml = html.replace(`[图片上传中${tempId}]`, `<img src="${imagUrl}" alt="图片" />`);
              $('#editor').trumbowyg('html', newHtml);
              // 将光标定位到图片后面
              _self.setCursorPosition(imagUrl);
            });
          }
        }
      }

      // 如果粘贴的是图片，阻止默认行为
      if (handled) {
        e.preventDefault();
      }
    });

    // 事件委托，监听点击附件链接下载(编辑器里)
    // $('#editor').on('click', '.trumbowyg-attachment-link', function (e) {
    //   e.preventDefault();
    //   const fileName = $(this).attr('file-name');
    //   const className = $(this).attr('class-name');
    //   DownloadService.fileDownload(className, fileName);
    // });

    // 获取编辑器内容
    $('#editor').trumbowyg('html', this.modelValue || '');

    // 监听内容变化
    $('#editor').on('tbwchange', () => {
      const html = $('#editor').trumbowyg('html');
      this.$emit('update:modelValue', html);

      // 检查当前选中的图片是否还存在，如果不存在则关闭模态框
      this.checkImageExistence();
    });

    // 通过 Trumbowyg 事件系统监听编辑器变化
    $('#editor').on('tbwchange tbwinit', () => {
      // 每次内容变化后重新绑定图片点击事件
      setTimeout(() => {
        this.bindImageClickEvents();
      }, 100);
    });

    // 点击其他地方关闭模态框，同时作为图片点击的备用监听器
    $(document).on('click', e => {
      // 如果点击的是编辑器内的图片，显示调整模态框
      if (e.target.tagName === 'IMG' && $(e.target).closest('#editor').length) {
        e.preventDefault();
        e.stopPropagation();
        this.showImageResizeModal(e.target);
        return;
      }

      // 如果点击的不是模态框或图片，关闭模态框
      if (!$(e.target).closest('.image-resize-modal, .trumbowyg-editor img, #editor img').length) {
        this.closeImageModal();
      }
    });

    // Common.downloadByA();
  },
  unmounted() {
    if (this.contentChangeTimer) {
      clearTimeout(this.contentChangeTimer);
    }
    $('#editor').trumbowyg('destroy');
  },
  methods: {
    // 通过html查看
    viewByHtml() {
      var html = $('#editor').trumbowyg('html');
      $('#content-editor-view').html(html);
    },

    // 上传图片
    async uploadImg(file, insertFn) {
      const _self = this;
      const formData = new FormData();
      try {
        formData.append('images', file);
        formData.append('className', _self.className);
        const url = 'file/imageUpload';
        _self.loading = true;
        await ajaxApiFile(url, formData).then(res => {
          if (res.errorCode === 0) {
            const imageName = res.datas[0];
            const imagUrl = Common.getResourceUrl1('image', imageName);
            insertFn(imagUrl);
          } else {
            message.warning(res.errorMessage);
          }
          _self.loading = false;
        });
      } catch (error) {
        _self.loading = false;
        console.error('上传图片失败:', error);
        message.error('图片上传失败，请稍后重试');
      }
    },
    /**
     * 上传文件
     * @param  {File} selectedFile 选择的文件
     */
    uploadFile: function (selectedFile, callback) {
      var _self = this;
      if (selectedFile == undefined) {
        return;
      }
      var formData = new FormData();
      formData.append('files', selectedFile);
      formData.append('className', _self.className);
      _self.loading = true;
      $.ajax({
        url: Common.getApiURL('file/classFileUpload'),
        type: 'post',
        beforeSend: function (request) {
          Common.addTokenToRequest(request);
        },
        data: formData,
        contentType: false,
        processData: false,
        success: function (data) {
          _self.loading = false;
          if (data.errorCode == 0) {
            if (data.datas) {
              var fileName = data.datas[0];
              if (callback) callback(fileName);
            }
          } else {
            message.error(data.errorMessage);
          }
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
          _self.loading = false;
          Common.processException(XMLHttpRequest, textStatus, errorThrown);
        },
      });
    },

    // 获取图片缩放配置
    showImageResizeModal(imgElement) {
      this.currentImage = imgElement;

      // 获取图片设置的样式尺寸（用户实际设置的值，不受容器限制影响）
      const setWidth = parseInt(imgElement.style.width) || imgElement.naturalWidth;
      const setHeight = parseInt(imgElement.style.height) || imgElement.naturalHeight;

      // 如果没有设置样式，使用计算样式作为备用
      const computedStyle = window.getComputedStyle(imgElement);
      const currentWidth = setWidth || parseInt(computedStyle.width) || imgElement.naturalWidth;
      const currentHeight = setHeight || parseInt(computedStyle.height) || imgElement.naturalHeight;

      // 保存原始尺寸（如果是第一次点击）
      if (!imgElement.dataset.originalWidth) {
        imgElement.dataset.originalWidth = imgElement.naturalWidth;
        imgElement.dataset.originalHeight = imgElement.naturalHeight;
      }

      this.originalImageSize = {
        width: parseInt(imgElement.dataset.originalWidth),
        height: parseInt(imgElement.dataset.originalHeight),
      };

      this.imageSize = {
        width: currentWidth,
        height: currentHeight,
      };

      // 计算当前缩放比例
      if (this.originalImageSize.width == 0) {
        this.currentZoom = 1;
      } else {
        this.currentZoom = currentWidth / this.originalImageSize.width;
      }

      // 计算模态框位置
      this.calculateModalPosition(imgElement);

      this.showImageModal = true;
    },

    // 计算模态框位置的独立方法
    calculateModalPosition(imgElement) {
      const imgRect = imgElement.getBoundingClientRect();
      const editorContainer = document.querySelector('.editor-container');
      const containerRect = editorContainer.getBoundingClientRect();

      // 获取Trumbowyg编辑器的box容器（包含工具栏和编辑区域）
      const trumbowygBox = document.querySelector('.trumbowyg-box');
      const trumbowygBoxRect = trumbowygBox ? trumbowygBox.getBoundingClientRect() : null;

      // 模态框宽度
      const modalWidth = 420;

      // 编辑器固定高度
      const editorHeight = 368;

      let top, left;

      // 判断是否需要将模态框显示在编辑器下方
      const shouldShowBelowEditor = this.shouldShowModalBelowEditor(imgRect, trumbowygBoxRect, editorHeight);

      if (shouldShowBelowEditor) {
        // 模态框显示在编辑器容器的正下方
        if (trumbowygBoxRect) {
          top = trumbowygBoxRect.bottom - containerRect.top + 5;
        } else {
          // 备用方案：使用固定位置
          top = editorHeight + 40; // 工具栏高度约40px
        }

        // 水平位置：居中显示在编辑器下方
        const centerX = trumbowygBoxRect ? (trumbowygBoxRect.left + trumbowygBoxRect.right) / 2 : containerRect.left + containerRect.width / 2;
        left = centerX - containerRect.left - modalWidth * 2;

        // 确保不超出容器边界
        left = Math.max(0, Math.min(left, containerRect.width - modalWidth));
      } else {
        // 小图片且在可视区域内：模态框显示在图片正下方
        top = imgRect.bottom - containerRect.top + 5;
        left = imgRect.left - containerRect.left;

        // 确保不超出容器边界
        left = Math.max(0, Math.min(left, containerRect.width - modalWidth));
      }

      this.modalPosition = { top, left };
    },

    // 判断是否应该将模态框显示在编辑器下方
    shouldShowModalBelowEditor(imgRect, trumbowygBoxRect, editorHeight) {
      // 情况1：图片本身高度超过编辑器高度
      if (this.imageSize.height > editorHeight) {
        return true;
      }

      // 情况2：图片底部超出了编辑器的可视区域
      if (trumbowygBoxRect) {
        // 获取编辑器内容区域的底部位置（不包括工具栏）
        const editorContentBottom = trumbowygBoxRect.bottom;

        // 如果图片底部超出了编辑器内容区域，说明图片有部分在滚动区域下方
        if (imgRect.bottom > editorContentBottom) {
          return true;
        }
      }

      // 情况3：图片顶部在编辑器可视区域上方（图片被向上滚动了）
      if (trumbowygBoxRect) {
        // 获取编辑器内容区域的顶部位置（工具栏下方）
        const trumbowyg = $('#editor').data('trumbowyg');
        const toolbarHeight = trumbowyg && trumbowyg.$btnPane ? trumbowyg.$btnPane.height() : 40;
        const editorContentTop = trumbowygBoxRect.top + toolbarHeight;

        // 如果图片顶部在编辑器内容区域上方，说明图片被部分滚动到上方了
        if (imgRect.top < editorContentTop) {
          return true;
        }
      }

      return false;
    },

    // 关闭图片模态框
    closeImageModal() {
      this.showImageModal = false;
      this.currentImage = null;
    },

    // 更新图片尺寸
    updateImageSize() {
      if (!this.currentImage) return;

      const width = parseInt(this.imageSize.width);
      const height = parseInt(this.imageSize.height);

      if (width > 0 && height > 0) {
        this.currentImage.style.width = width + 'px';
        this.currentImage.style.height = height + 'px';

        // 更新缩放比例
        this.currentZoom = width / this.originalImageSize.width;

        // 强制同步编辑器内容
        this.syncEditorContent();
      }
    },

    // 放大
    zoomIn() {
      if (this.currentZoom >= this.maxZoom) return;

      this.currentZoom = Math.min(this.currentZoom + 0.1, this.maxZoom);
      this.applyZoom();
    },

    // 缩小
    zoomOut() {
      if (this.currentZoom <= this.minZoom) return;

      this.currentZoom = Math.max(this.currentZoom - 0.1, this.minZoom);
      this.applyZoom();
    },

    // 触发缩放事件
    applyZoom() {
      if (!this.currentImage) return;

      const newWidth = Math.round(this.originalImageSize.width * this.currentZoom);
      const newHeight = Math.round(this.originalImageSize.height * this.currentZoom);

      // 直接设置模态框显示的尺寸（用户设置的目标尺寸）
      this.imageSize.width = newWidth;
      this.imageSize.height = newHeight;

      // 设置图片的样式尺寸
      this.currentImage.style.width = newWidth + 'px';
      this.currentImage.style.height = newHeight + 'px';

      // 强制同步编辑器内容
      this.syncEditorContent();
    },

    // 更新模态框中显示的尺寸值（获取图片设置的样式尺寸）
    updateDisplayedSize() {
      if (!this.currentImage) return;

      // 获取图片设置的样式尺寸（用户实际设置的值）
      const setWidth = parseInt(this.currentImage.style.width) || this.currentImage.naturalWidth;
      const setHeight = parseInt(this.currentImage.style.height) || this.currentImage.naturalHeight;

      // 更新模态框中显示的尺寸值（显示用户设置的值，不是被限制后的显示值）
      this.imageSize = {
        width: setWidth,
        height: setHeight,
      };

      // 更新缩放比例（基于用户设置的尺寸）
      if (this.originalImageSize.width > 0) {
        this.currentZoom = setWidth / this.originalImageSize.width;
      }
    },
    // 同步编辑器内容
    syncEditorContent() {
      const trumbowyg = $('#editor').data('trumbowyg');
      if (trumbowyg) {
        // 强制同步DOM到HTML
        trumbowyg.syncCode();

        // 延迟触发内容变化事件
        this.debouncedTriggerContentChange();
      }
    },
    // 防抖的内容变化触发器
    debouncedTriggerContentChange() {
      if (this.contentChangeTimer) {
        clearTimeout(this.contentChangeTimer);
      }
      this.contentChangeTimer = setTimeout(() => {
        this.triggerContentChange();
      }, 300); // 300ms 防抖
    },
    // 触发编辑器内容变化事件
    triggerContentChange() {
      const html = $('#editor').trumbowyg('html');
      this.$emit('update:modelValue', html);
    },


    // 给所有图片绑定点击事件
    bindImageClickEvents() {
      const _self = this;
      const trumbowyg = $('#editor').data('trumbowyg');

      if (!trumbowyg || !trumbowyg.$ed) {
        console.log('bindImageClickEvents: Trumbowyg 编辑器未初始化');
        return;
      }

      // 查找所有图片
      const images = trumbowyg.$ed.find('img');

      // 先移除所有已有的图片点击事件，避免重复绑定
      images.off('click.imageResize');

      // 为每个图片添加点击事件
      images.each(function () {
        const img = $(this);

        img.on('click.imageResize', function (e) {
          e.preventDefault();
          e.stopPropagation();
          _self.showImageResizeModal(this);
        });
      });
    },

    // 粘贴后光标位于图片后
    setCursorPosition(imagUrl) {
      setTimeout(() => {
        try {
          const $editor = $('#editor');
          const editorElement = $editor.data('trumbowyg').$ed[0];

          // 找到刚插入的图片元素
          const imgElements = editorElement.querySelectorAll(`img[src="${imagUrl}"]`);
          const imgElement = imgElements[imgElements.length - 1]; // 获取最后一个（最新插入的）

          if (imgElement) {
            const range = document.createRange();
            const selection = window.getSelection();

            // 直接将光标定位在图片元素后面
            range.setStartAfter(imgElement);
            range.setEndAfter(imgElement);

            selection.removeAllRanges();
            selection.addRange(range);

            // 确保编辑器获得焦点
            editorElement.focus();
          }
        } catch (error) {
          console.error('设置光标位置失败:', error);
        }
      }, 100); // 延迟确保DOM更新完成
    },

    // 检查当前选中的图片是否还存在于编辑器中
    checkImageExistence() {
      // 如果没有显示模态框或没有当前图片，直接返回
      if (!this.showImageModal || !this.currentImage) {
        return;
      }

      try {
        const trumbowyg = $('#editor').data('trumbowyg');
        if (!trumbowyg || !trumbowyg.$ed) {
          return;
        }

        // 获取编辑器中所有的图片元素
        const editorImages = trumbowyg.$ed.find('img');

        // 检查当前选中的图片是否还在编辑器中
        let imageExists = false;
        editorImages.each((_, img) => {
          if (img === this.currentImage) {
            imageExists = true;
            return false; // 跳出each循环
          }
        });

        // 如果图片不存在了，关闭模态框
        if (!imageExists) {
          console.log('检测到图片已被删除，关闭模态框');
          this.closeImageModal();
        }
      } catch (error) {
        console.error('检查图片存在性时出错:', error);
        // 出错时也关闭模态框，避免显示无效的模态框
        this.closeImageModal();
      }
    },
  },
};
</script>

<style>
.editor-container {
  position: relative;
}

.trumbowyg-box .trumbowyg-editor {
  height: 368px !important;
}

.trumbowyg-button-pane {
  background: white !important;
  border-bottom: none !important;
}

.trumbowyg-editor {
  padding: 6px 14px !important;
}

.view-box {
  border: 1px solid #ccc;
  min-height: 200px;
  padding: 8px;
}

/* 图片调整模态框样式 */
.image-resize-modal {
  position: absolute;
  z-index: 1000;
  background: white;
  border: 1px solid #ddd;
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  padding: 0;
  min-width: 420px;
  max-width: 500px;
}

.modal-content {
  position: relative;
  padding: 4px 12px;
}

.controls-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 12px;
  justify-content: space-between;
}

.size-input-group {
  display: flex;
  align-items: center;
  gap: 4px;
}

.size-input-group label {
  font-size: 12px;
  color: #666;
  min-width: 32px;
}

.size-input-group input {
  width: 60px;
  padding: 4px 6px;
  border: 1px solid #ddd;
  border-radius: 3px;
  font-size: 12px;
  text-align: center;
}

.size-input-group span {
  font-size: 12px;
  color: #999;
}

.zoom-controls {
  display: flex;
  align-items: center;
  gap: 8px;
}

.zoom-btn {
  width: 28px;
  height: 28px;
  border: 1px solid #ddd;
  border-radius: 4px;
  background: white;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  font-weight: bold;
  transition: all 0.2s;
}

.zoom-btn:hover:not(:disabled) {
  background: #f5f5f5;
  border-color: #999;
}

.zoom-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.zoom-display {
  font-size: 12px;
  color: #666;
  min-width: 40px;
  text-align: center;
}

.close-btn {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 20px;
  height: 20px;
  border: none;
  background: none;
  cursor: pointer;
  font-size: 24px;
  color: #999;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 2px;
}

.close-btn:hover {
  background: #f5f5f5;
  color: #666;
}

/* 图片选中状态 */
.trumbowyg-editor img:hover {
  outline: 2px solid #007bff;
  outline-offset: 2px;
  cursor: pointer;
}
</style>