<template>
  <div
    ref="esNav"
    class="es-nav"
    :class="biserial ? 'es-nav-biserial' : ''"
    :style="{ width: boxWidth, height: height }"
  >
    <div
      class="es-nav-initial"
      v-if="biserial"
      :style="{
        width: _navWidth,
        left:
          this.overlap && !this.subMenu.length
            ? '15px'
            : show
            ? '-' + boxWidth
            : ''
      }"
    >
      <es-menu
        :class="{ 'es-nav-overlap': overlap }"
        v-bind="$attrs"
        sub-nav
        :data="menu"
        :is-default="isDefault"
        :deep="false"
        :default-active="subActive"
        :biserial="biserial"
        :menu-icons="menuIcon"
        :icons="icons"
        :sub-icon="subIcon"
        @select="handleTrigger"
      ></es-menu>
    </div>
    <div
      class="es-nav-main"
      :class="{ 'es-nav-overlap': overlap }"
      :biserial="biserial"
      :style="{
        width: biserial ? width : boxWidth,
        left: biserial ? (show ? '15px' : navWidth) : ''
      }"
      v-show="showMenu"
    >
      <div class="es-nav-title" v-if="showTitle" ref="navTitle">
        <span v-show="!isCollapse">{{ headline }}</span>
        <template v-if="showCollapse">
          <i
            v-show="!isCollapse"
            class="es-icon-shouqi es-collapse-handle"
            @click="handleChange"
          ></i>
          <i
            v-show="isCollapse"
            class="es-icon-zhankai es-collapse-handle"
            @click="handleChange"
          ></i>
        </template>
      </div>
      <es-menu
        v-bind="$attrs"
        :class="biserial ? 'es-nav-biserial' : ''"
        :data="biserial ? subMenu : menu"
        :collapse="isCollapse"
        :default-active="menuActive"
        :width="isTop ? boxWidth : menuWidth"
        :height="menuHeight"
        :style="{ height: menuHeight }"
        :is-default="isDefault"
        :biserial="biserial"
        :paddingLeft="paddingLeft"
        :menu-icon="menuIcon"
        :icons="icons"
        :sub-icon="subIcon"
        @select="handleSelect"
        @open="handleOpen"
        @close="handleClose"
      ></es-menu>
    </div>
    <es-enable-drag
      v-show="show"
      :distance="0"
      topDistance="100px"
      leftDistance="0px"
      @click="handleClick"
    ></es-enable-drag>
  </div>
</template>
<script>
import util from 'eoss-ui/src/utils/util';
import { throttle } from 'throttle-debounce';
export default {
  name: 'EsNav',
  inheritAttrs: false,
  props: {
    isTop: Boolean,
    data: {
      type: Array,
      default: []
    },
    title: {
      type: [String, Boolean],
      default: ''
    },
    width: {
      type: String,
      default: '200px'
    },
    navWidth: {
      type: String,
      default: '70px'
    },
    showCollapse: {
      type: Boolean,
      default: true
    },
    collapse: {
      type: Boolean,
      default: false
    },
    //是否双列导航
    biserial: Boolean,
    defaultActive: [String, Array],
    isDefault: Boolean,
    paddingLeft: Number,
    menuIcon: String,
    icons: Object,
    subIcon: {
      type: Boolean,
      default: true
    },
    overlap: Boolean,
    //隐藏菜单
    hideSubMenu: Boolean
  },
  computed: {
    show() {
      return this.overlap && this.subMenu.length;
    },
    showMenu() {
      return this.biserial ? this.subMenu.length : this.menu.length;
    },
    menu() {
      return this.data;
    },
    showTitle() {
      if (this.title === false && this.showCollapse === false) {
        return false;
      }
      return true;
    },
    subActive() {
      let active =
        this.biserial &&
        Array.isArray(this.defaultActive) &&
        this.defaultActive.length
          ? this.defaultActive[0]
          : undefined;
      return active;
    },
    menuActive() {
      let active =
        typeof this.defaultActive === 'string'
          ? this.defaultActive
          : this.defaultActive && this.defaultActive.length
          ? this.defaultActive[this.defaultActive.length - 1]
          : undefined;
      return active;
    },
    boxWidth() {
      if (!this.biserial) {
        if (this.overlap) {
          return this.navWidth;
        }
        if (this.isShow) {
          return this.width;
        } else {
          return this.navWidth;
        }
      }
      return this.subMenu &&
        this.subMenu.length &&
        this.isShow &&
        !this.overlap &&
        !this.hideSubMenu
        ? parseInt(this.width, 10) + parseInt(this.navWidth, 10) + 'px'
        : this.navWidth;
    },
    _navWidth() {
      return this.overlap
        ? parseInt(this.navWidth, 10) - 30 + 'px'
        : this.navWidth;
    }
  },
  watch: {
    collapse(val) {
      this.isCollapse = this.biserial ? false : val;
    },
    title(val) {
      if (typeof val === 'string' && val) {
        this.headline = val;
      }
    },
    boxWidth() {
      this.getHeight();
    },
    biserial: {
      handler(val) {
        this.isShow = !val;
        this.getHeight();
      }
    },
    defaultActive: {
      immediate: true,
      deep: true,
      handler(val) {
        if (val && val.length) {
          if (typeof val !== 'string' && val.length) {
            this.isShow = true;
            if (this.biserial) {
              this.active = val[0];
            } else {
              this.active = val[val.length - 1];
            }
            this.menu.forEach((item) => {
              if (item.id === this.active) {
                this.subMenu = item.children || [];
                this.headline = this.title ? this.title : item.text;
                return;
              }
            });
          }
        }
      }
    },
    menu(val) {
      if (val && val.length) {
        if (
          this.defaultActive &&
          typeof this.defaultActive !== 'string' &&
          this.defaultActive.length
        ) {
          this.isShow = true;
          if (this.biserial) {
            this.active = this.defaultActive[0];
          } else {
            this.active = this.defaultActive[this.defaultActive.length - 1];
          }
          val.forEach((item) => {
            if (item.id === this.active) {
              this.subMenu = item.children || [];
              this.headline = this.title ? this.title : item.text;
              return;
            }
          });
        }
      } else {
        this.subMenu = [];
      }
    },
    showMenu(val) {
      if (val) {
        this.getHeight();
      }
    }
  },
  data() {
    return {
      menuWidth: this.width,
      height: '',
      menuHeight: '',
      active: '',
      isCollapse: this.biserial ? false : this.collapse,
      isShow: this.biserial ? false : true,
      headline: this.title,
      subMenu: []
    };
  },
  beforeCreate() {
    this.getHeight = throttle(500, () => {
      this.resetHeight();
    });
  },
  mounted() {
    this.getHeight();
  },
  methods: {
    //设置按钮拖动
    handleClick() {
      this.subMenu = [];
    },
    handleChange() {
      if (this.biserial) {
        this.isShow = !this.isShow;
      } else {
        this.isCollapse = !this.isCollapse;
        if (this.isCollapse) {
          this.isShow = false;
          this.menuWidth = this.navWidth;
        } else {
          this.isShow = true;
          this.menuWidth = this.width;
        }
      }
    },
    handleTrigger(res) {
      let { node } = res;
      if (node.children && node.children.length) {
        this.subMenu = node.children;
        this.headline = node.text;
        this.isShow = true;
      }
      this.$emit('trigger', res);
    },
    handleSelect(res) {
      this.$emit('select', res);
    },
    handleOpen(res) {
      this.$emit('open', res);
    },
    handleClose(res) {
      this.$emit('close', res);
    },
    resetHeight() {
      this.$nextTick(() => {
        let height = this.$refs.esNav.parentNode.offsetHeight;
        Array.from(this.$refs.esNav.parentNode.children).forEach((item) => {
          if (item !== this.$refs.esNav) {
            let mt = util.getStyle(item, 'margin-top');
            let mb = util.getStyle(item, 'margin-bottom');
            mt = mt ? parseInt(mt, 10) : 0;
            mb = mb ? parseInt(mb, 10) : 0;
            height -= item.offsetHeight + mt + mb;
          }
        });
        if (this.overlap) {
          height -= 15;
        }
        this.height = height + 'px';
        if (this.showTitle) {
          let theight = this.$refs.navTitle.offsetHeight;
          this.menuHeight = height - theight + 'px';
        } else {
          this.menuHeight = height + 'px';
        }
      });
    }
  }
};
</script>
