<script>
import { throttle } from 'throttle-debounce';
export default {
  name: 'EsMenu',
  inheritAttrs: false,
  props: {
    data: {
      type: Array,
      default() {
        return [];
      }
    },
    titleIcons: {
      type: Boolean,
      default: true
    },
    deep: {
      type: Boolean,
      default: true
    },
    subNav: {
      type: Boolean,
      default: false
    },
    width: String,
    height: String,
    mode: {
      type: String,
      default: 'vertical'
    },
    collapse: Boolean,
    defaultActive: String,
    uniqueOpened: {
      type: Boolean,
      default: true
    },
    popperClass: String,
    biserial: Boolean,
    paddingLeft: {
      type: Number,
      default: 14
    },
    menuIcon: {
      type: String,
      default: 'es-icon-application'
    },
    icons: Object,
    subIcon: {
      type: Boolean,
      default: true
    },
    menuClass: String,
    color: [String, Array],
    backgroundColor: [String, Array],
    showTitle: {
      type: Boolean,
      default: true
    },
    fourthTabs: Boolean
  },
  computed: {
    maxHeight() {
      return this.height === undefined ? this.maxH : this.height;
    },
    maxWidth() {
      return this.maxW;
    }
  },
  watch: {
    data: {
      deep: true,
      handler() {
        this.getMaxWidth();
      }
    },
    width() {
      this.getMaxWidth();
    },
    height() {
      this.$refs.esMenu.update();
    }
  },
  data() {
    return {
      maxH: '',
      maxW: '',
      menuId: null,
      defaultOpeneds: [],
      isChange: false
    };
  },
  beforeCreate() {
    this.getMaxWidth = throttle(500, () => {
      this.getWidth();
    });
  },
  created() {},
  mounted() {
    this.getMaxWidth();
  },
  methods: {
    setStyle(num) {
      let obj = {};
      if (this.color) {
        obj.color = this.color;
        if (Array.isArray(this.color)) {
          obj.color = this.color[num % this.color.length];
        } else {
          obj.color = this.color;
        }
      }
      if (this.backgroundColor) {
        if (Array.isArray(this.backgroundColor)) {
          obj.backgroundColor =
            this.backgroundColor[num % this.backgroundColor.length];
        } else {
          obj.backgroundColor = this.backgroundColor;
        }
      }
      return obj;
    },
    getWidth() {
      if (this.mode === 'vertical') {
        this.$nextTick(() => {
          this.maxH =
            this.$refs.esMenu.$el.getBoundingClientRect().height + 'px';
          const styles = window.getComputedStyle(
            this.$refs.menu.$el.parentNode
          );
          this.maxW = this.width
            ? parseInt(this.width, 10) -
              parseInt(styles.marginLeft, 10) -
              parseInt(styles.marginRight, 10) +
              'px'
            : '';
        });
      } else {
        this.$nextTick(() => {
          let w = 0;
          this.$refs.menu &&
            Array.from(this.$refs.menu.$el.children).forEach((item) => {
              w += item.getBoundingClientRect().width;
            });
          const styles = window.getComputedStyle(this.$refs.menu.$el);
          w += parseFloat(styles.paddingLeft) + parseFloat(styles.paddingRight);
          if (w > this.$refs.esMenu.$el.getBoundingClientRect().width) {
            this.maxW = w + 'px';
          }
        });
      }
    },
    handleReady() {
      if (this.mode === 'horizontal') {
        this.$refs.esMenu.wrap.onmouseover = (e) => {
          this.$refs.esMenu.wrap.addEventListener(
            'mousewheel',
            this.handleWheel,
            { passive: false }
          ) ||
            this.$refs.esMenu.wrap.addEventListener(
              'DOMMouseScroll',
              this.handleWheel,
              false
            );
          e.preventDefault();
        };
        this.$refs.esMenu.wrap.onmouseout = (e) => {
          this.$refs.esMenu.wrap.removeEventListener(
            'mousewheel',
            this.handleWheel,
            { passive: false }
          ) ||
            this.$refs.esMenu.wrap.removeEventListener(
              'DOMMouseScroll',
              this.handleWheel,
              false
            );
          e.preventDefault();
        };
      }
      // const { scrollHeight, clientHeight } =
      //   this.bodyWrapper.wrap || this.bodyWrapper;
      // if (scrollHeight === clientHeight && this.$refs.fixedWrapper) {
      //   this.$refs.fixedWrapper.onmouseover = (e) => {
      //     this.$refs.fixedWrapper.addEventListener(
      //       'mousewheel',
      //       this.handleWheel,
      //       { passive: false }
      //     ) ||
      //       this.$refs.fixedWrapper.addEventListener(
      //         'DOMMouseScroll',
      //         this.handleWheel,
      //         false
      //       );
      //     e.preventDefault();
      //   };
      //   this.$refs.fixedWrapper.onmouseout = (e) => {
      //     this.$refs.fixedWrapper.removeEventListener(
      //       'mousewheel',
      //       this.handleWheel,
      //       { passive: false }
      //     ) ||
      //       this.$refs.fixedWrapper.removeEventListener(
      //         'DOMMouseScroll',
      //         this.handleWheel,
      //         false
      //       );
      //     e.preventDefault();
      //   };
      // }
    },
    handleWheel(e) {
      if (!this.sizeHeight) {
        const eventDelta = -e.wheelDelta || e.deltaY * 40;
        this.$refs.esMenu.$refs.wrap.scrollLeft =
          this.$refs.esMenu.$refs.wrap.scrollLeft + eventDelta / 4;
        if (
          this.$refs.esMenu.$refs.wrap.scrollLeft > 0 &&
          this.$refs.esMenu.$refs.wrap.scrollLeft <
            this.$refs.esMenu.$refs.wrap.scrollWidth -
              this.$refs.esMenu.$refs.wrap.clientWidth
        ) {
          e.preventDefault();
        }
      }
    },
    getFirst(arry) {
      let item = arry[0];
      if (
        Object.prototype.hasOwnProperty.call(item, 'children') &&
        item.children.length
      ) {
        return this.getFirst(item.children);
      } else {
        this.$emit('select', {
          node: item,
          mode: this.mode,
          auto: true
        });
        return item.id;
      }
    },
    handleSelect(key, keyPath, item) {
      this.isChange = true;
      if (this.menuId !== null && keyPath.indexOf(this.menuId) == -1) {
        this.$refs.menu.close(this.menuId);
      } else {
        let openedMenus = item.rootMenu.openedMenus;
        openedMenus.forEach((item) => {
          if (keyPath.indexOf(item) == -1) {
            this.$refs.menu.close(item);
          }
        });
      }
      this.$emit('select', {
        key: key,
        path: keyPath,
        node: item.$attrs.data,
        fourthTabs: item.$attrs.fourthTabs,
        item: item,
        mode: this.mode
      });
    },
    handleOpen(key, keyPath, item) {
      this.menuId = key;
      this.$emit('open', {
        key: key,
        path: keyPath,
        node: item.$attrs.data,
        item: item,
        mode: this.mode
      });
    },
    handleClose(key, keyPath, item) {
      this.menuId = null;
      this.$emit('close', {
        key: key,
        path: keyPath,
        node: item.$attrs.data,
        item: item,
        mode: this.mode
      });
    },
    getSub(item, h, popper, fourthTabs, subIcon, index, directives) {
      if (popper) {
        popper += this.popperClass
          ? ' ' + this.popperClass + ` es-menu-popper-${this.mode}`
          : ` es-menu-popper-${this.mode}`;
      } else {
        popper = this.popperClass
          ? ' ' + this.popperClass + ` es-menu-popper-${this.mode}`
          : ` es-menu-popper-${this.mode}`;
      }
      let title = [];
      if (subIcon) {
        title.push(
          h('es-icon', {
            props: {
              contents: item.icons || this.menuIcon
            },
            style: this.setStyle(index),
            class: ['es-menu-item-icon']
          })
        );
      }
      title.push(
        h(
          'div',
          {
            class: [
              `es-menu-title-text es-menu-title-${this.mode}`,
              {
                'es-menu-title-margin':
                  this.deep &&
                  item.children &&
                  item.children.length &&
                  (!item.extendData || item.extendData.businessStatus != 0) &&
                  typeof item.tips === 'boolean' &&
                  item.tips
              }
            ],
            directives: directives
              ? [
                  {
                    name: 'show',
                    value: this.showTitle ? true : !this.collapse
                  }
                ]
              : []
          },
          [
            h(
              'el-badge',
              {
                class: [
                  'es-badge',
                  {
                    'es-badge-right':
                      item.tips && typeof item.tips !== 'boolean',
                    'es-dot-right': item.tips && typeof item.tips === 'boolean'
                  }
                ],
                attrs: {
                  title: item.text.length > 18 ? item.text : undefined
                },
                props:
                  typeof item.tips === 'boolean' && item.tips
                    ? {
                        isDot: true
                        //hidden: item.tips
                      }
                    : {
                        value: parseInt(item.tips, 10),
                        max: 99,
                        hidden: !item.tips
                      }
              },
              [item.text]
            )
          ]
        )
      );
      let doms = [
        h('template', { slot: 'title' }, this.titleIcons ? title : [title[1]])
      ];
      if (this.fourthTabs) {
      }
      if (
        this.deep &&
        item.children &&
        item.children.length &&
        (!item.extendData || item.extendData.businessStatus != 0)
      ) {
        doms = doms.concat(
          item.children.map((ele, index) => {
            if (!ele) {
              console.error(`对象子数据中第[${index}]条数据错误`, item);
            } else {
              return this.getSub(ele, h, popper, false, this.subIcon, index);
            }
          })
        );
        return [
          h(
            'el-submenu',
            {
              class: [
                'es-submenu',
                `es-submenu-${this.mode}`,
                item.id === this.active && !this.isChange
                  ? 'es-menu-item-focus'
                  : ''
              ],
              props: {
                popperClass: popper,
                popperAppendToBody: true,
                maxHeight: this.maxHeight,
                paddingLeft: this.paddingLeft
              },
              attrs: { data: item, index: item.id, key: item.id }
            },
            doms
          )
        ];
      }
      if (
        this.deep &&
        (this.mode === 'horizontal', this.fourthTabs) &&
        item.fourthTabs &&
        item.fourthTabs.length &&
        (!item.extendData || item.extendData.businessStatus != 0)
      ) {
        doms = doms.concat(
          item.fourthTabs.map((ele, index) => {
            if (!ele) {
              console.error(`对象子数据中第[${index}]条数据错误`, item);
            } else {
              return this.getSub(ele, h, popper, true, this.subIcon, index);
            }
          })
        );
        return [
          h(
            'el-submenu',
            {
              class: [
                'es-submenu',
                `es-submenu-${this.mode}`,
                item.id === this.active && !this.isChange
                  ? 'es-menu-item-focus'
                  : ''
              ],
              props: {
                popperClass: popper,
                popperAppendToBody: true,
                maxHeight: this.maxHeight,
                paddingLeft: this.paddingLeft
              },
              attrs: { data: item, index: item.id, key: item.id }
            },
            doms
          )
        ];
      } else {
        return [
          h(
            'el-menu-item',
            {
              class: [
                'es-menu-item ' + (this.deep ? '' : `es-item-${this.mode}`)
              ],
              props: {
                paddingLeft: this.paddingLeft,
                disabled: item.extendData && item.extendData.businessStatus == 0
              },
              attrs: {
                data: item,
                index: item.id,
                key: item.id,
                fourthTabs: fourthTabs
              }
            },
            this.titleIcons ? title : [title[1]]
          )
        ];
      }
    }
  },
  render(h) {
    let doms = [];
    this.data.forEach((item, index) => {
      if (
        item.children &&
        item.children.length &&
        (!item.extendData || item.extendData.businessStatus != 0)
      ) {
        doms = doms.concat(
          this.getSub(item, h, 'es-sub-menu', false, true, index, true)
        );
      } else {
        const title = [
          h('es-icon', {
            props: {
              contents: item.icons || this.menuIcon
            },
            style: this.setStyle(index),
            class: ['es-menu-item-icon']
          }),
          h(
            'div',
            {
              class: [`es-menu-title-text es-menu-title-${this.mode}`],
              directives: [
                {
                  name: 'show',
                  value: this.showTitle ? true : !this.collapse
                }
              ]
            },
            [
              h(
                'el-badge',
                {
                  class: [
                    'es-badge',
                    {
                      'es-badge-right':
                        item.tips && typeof item.tips !== 'boolean',
                      'es-dot-right':
                        item.tips && typeof item.tips === 'boolean'
                    }
                  ],
                  props:
                    typeof item.tips === 'boolean' && item.tips
                      ? {
                          isDot: true
                          //hidden: item.tips
                        }
                      : {
                          value: parseInt(item.tips, 10),
                          max: 99,
                          hidden: !item.tips
                        }
                },
                [item.text]
              )
            ]
          )
        ];
        doms.push(
          h(
            'el-menu-item',
            {
              class: [
                'es-menu-item ' + (this.deep ? '' : `es-item-${this.mode}`)
              ],
              props: {
                paddingLeft: this.paddingLeft,
                disabled: item.extendData && item.extendData.businessStatus == 0
              },
              attrs: {
                data: item,
                index: item.id,
                key: item.id
              }
            },
            this.titleIcons ? title : [title[1]]
          )
        );
      }
    });
    return h(
      'el-scrollbar',
      {
        ref: 'esMenu',
        props: {
          horizontal: this.mode === 'horizontal',
          onReady: this.handleReady
        },
        class: `es-menu-${this.mode}-scrollbar`
      },
      [
        h(
          'el-menu',
          {
            class: [
              'es-menu',
              this.menuClass,
              `es-menu-${this.mode}`,
              { 'es-menu-collapse': this.collapse },
              { 'es-menu-nav': this.subNav }
            ],
            ref: 'menu',
            props: {
              defaultOpeneds: this.defaultOpeneds,
              defaultActive: this.defaultActive,
              collapse: this.collapse,
              mode: this.mode,
              uniqueOpened: this.uniqueOpened,
              icons: this.icons
            },
            style: { width: this.maxWidth },
            attrs: { ...this.$attrs },
            on: {
              ...this.$listeners,
              open: this.handleOpen,
              close: this.handleClose,
              select: this.handleSelect
            }
          },
          doms
        )
      ]
    );
  }
};
</script>
