export default function (editor) {
  // 前面板，拖入组件时，定位到鼠标位置
  editor.Commands.extend('core:component-drag', {
    onStart() {
      const { target, editor, isTran, opts } = this;
      const { center } = opts;
      const { Canvas } = editor;
      const style = target.getStyle();
      const position = 'absolute';
      if (isTran) return;

      if (style.position !== position) {

        let { left, top, width, height } = Canvas.offset(target.getEl());

        /**
         * line 19-30 新增逻辑, 其余grapesjs源码 
         * 查找相对于当前拖动节点最近的且不是static定位的父元素
         * 获取父元素相对于画布的left，top
         * 得出差值为拖动节点的left，top
         */
        let relativeEl;
        $(target.getEl()).parents().each(function () {
          if ($(this).css('position') === 'absolute') {
            relativeEl = this;
            return false;
          };
        });

        if (relativeEl) {
          left -= Canvas.offset(relativeEl).left;
          top -= Canvas.offset(relativeEl).top;
        }

        // Check if to center the target to the pointer position
        if (center) {
          /**
           * 下面被注释的三行代码为grapejs源码
           */
          // const { x, y } = Canvas.getMouseRelativeCanvas(event);
          // left = x;
          // top = y;
          left = opts.event.clientX;
          top = opts.event.clientY;
        }

        this.setPosition({
          x: left,
          y: top,
          width: `${width}px`,
          height: `${height}px`,
          position
        });
      }
    }
  })

  editor.on('load', () => {
    /*
     * 缺省情况下，grapesjs是以组件的左上角坐标为基准，定位组件，当组件拖入画布时，鼠标坐在的位置不是组件的中心点，而是左上角
     * hack：在向前面板画布拖入组件后，调整组件位置
     **/

    const hackDroppableDrgEnd = editor.Canvas.droppable.handleDragEnd;
    editor.Canvas.droppable.handleDragEnd = function (model, dt) {
      if (model) {
        const { left, top } = model.getStyle();
        const $el = model.getEl();
        model.addStyle({ left: `${parseInt(left) - $el.clientWidth / 2}px`, top: `${parseInt(top) - $el.clientHeight / 2}px` })
      }

      hackDroppableDrgEnd.call(this, model, dt);
    }
  });
}
