<template>
  <div v-if="menuShow" class="rightMenuContext" ref="rightMenuContext" :style="{
      position: 'fixed',
      left: position.x + 'px',
      top: position.y + 'px',
      minWidth: style.minWidth + 'px',
      zIndex: style.zIndex,
      opacity: opacity,
    }"></div>
</template>

<script>
import {
  getCurrentInstance,
  nextTick,
  h,
  render,
  reactive,
  toRefs,
  useCssModule,
  onMounted,
  onUnmounted,
  provide,
} from "vue";
import { getElementsByClassName } from "./util";
export default {
  props: {},
  setup (props, context) {
    let $style = useCssModule();
    let { proxy } = getCurrentInstance();
    let mainMenuInstance;
    let _data = reactive({
      rightMenuContext: null,
      position: {
        x: 0,
        y: 0,
      },
      style: {
        zIndex: 2,
        minWidth: 150,
      },
      opacity: 0,
      mouseListening: false,
      menuShow: false,
    });
    let _methods = {
      newInstance (event, instance, options) {
        _data.position.x = event.clientX;
        _data.position.y = event.clientY;
        _data.style.zIndex = options.zIndex || 2;
        _data.style.minWidth = options.minWidth || 150;
        _data.opacity = 0;
        _data.menuShow = true;
        nextTick(() => {
          mainMenuInstance = instance({ destroy: _methods.destroy });
          render(mainMenuInstance, _data.rightMenuContext);
          setTimeout(() => {
            _methods.addListener();
            let domWidth = _data.rightMenuContext.clientWidth,
              domHeight = _data.rightMenuContext.clientHeight;
            let height = document.body.clientHeight,
              width = document.body.clientWidth;
            if (event.clientY + domHeight > height) {
              _data.position.y = _data.position.y - domHeight;
            }
            if (event.clientX + domWidth > width) {
              _data.position.x = _data.position.x - domWidth;
            }
            _data.opacity = 1;
          }, 0);
        });
      },
      getInstance () {
        return mainMenuInstance;
      },
      destroy () {
        _methods.removeListener();
        _data.menuShow = false;
        // 卸载子组件
        let umList = mainMenuInstance.component.um;
        umList &&
          umList.forEach((element) => {
            element();
          });
      },
      mousewheelListener () {
        _methods.destroy();
      },
      outSlideDestroy (el) {
        let hasMean = false;
        // return
        while (el.parentElement && !hasMean) {
          if (el.className.indexOf("rightMenuContext") !== -1) {
            hasMean = true;
          } else {
            el = el.parentElement;
          }
        }
        if (!hasMean) {
          _methods.destroy();
        }
      },
      mouseDownListener (e) {
        let el = e.target;
        _methods.outSlideDestroy(el);
      },
      mouseClickListener (e) {
        let el = e.target;
        _methods.outSlideDestroy(el);
      },
      addListener () {
        if (!_data.mouseListening) {
          document.addEventListener("click", _methods.mouseClickListener);
          document.addEventListener("mousedown", _methods.mouseDownListener);
          // document.addEventListener("mousewheel", _methods.mousewheelListener);
          _data.mouseListening = true;
        }
      },
      removeListener () {
        if (_data.mouseListening) {
          document.removeEventListener("click", _methods.mouseClickListener);
          document.removeEventListener("mousedown", _methods.mouseDownListener);
          // document.removeEventListener("mousewheel", _methods.mousewheelListener);
          _data.mouseListening = false;
        }
      },
    };
    // :style="{left: style.left + 'px', top: style.top + 'px', minWidth: style.minWidth + 'px', zIndex: style.zIndex}"
    // node.style.left=
    onUnmounted(() => {
      _methods.removeListener();
      if (mainMenuInstance) {
      }
    });
    return {
      ...toRefs(_data),
      ..._methods,
    };
  },
};
</script>

<style module>
.menu,
.menu_item,
.menu_item__clickable,
.menu_item__unclickable {
  box-sizing: border-box;
}
</style>