<template>
  <div class="el-nav-menu" ref='navMenu'>
    <template v-for='menu in useMenus'>
      <template v-if='!menu[useProps.hidden]'>
        <el-popover
          v-if='menu.hasChild'
          :key='menu.fullPath'
          placement="bottom-start"
          :class='["el-nav-menu-header", "el-nav-menu-header-" + menu[useProps.key], useActivePath.indexOf(menu.fullPath) > -1 ? "is-active" : ""]'
          popper-class='el-nav-menu-popover'
          :visible-arrow='false'
          :offset='-8'
          trigger="hover"
          @show='show(menu[useProps.key])'
          @hide='hide(menu[useProps.key])'>
          <div class='el-nav-menu-popover-container'>
            <!-- 有三级菜单 -->
            <template v-if='menu.hasGrandson'>
              <template v-for='subs in menu[useProps.subs]'>
                <div v-if='!subs[useProps.hidden]' :key='subs.fullPath' class='el-nav-menu-popover-container-item'>
                  <!-- 区分当前节点是否有子节点 -->
                  <template v-if='subs.hasChild'>
                    <div class='el-nav-menu-popover-container-item-title'>{{subs[useProps.label]}}</div>
                    <template v-for='item in subs[useProps.subs]'>
                      <div
                        v-if='!item[useProps.hidden]'
                        :key='item.fullPath'
                        :class='["el-nav-menu-router", useActivePath.indexOf(item.fullPath) > -1 ? "is-active" : ""]'
                        @click='routerPush(item.fullPath, item)'
                      >{{item[useProps.label]}}</div>
                    </template>
                  </template>
                  <template v-else>
                    <div
                      :key='subs.fullPath'
                      :class='["el-nav-menu-router", useActivePath.indexOf(subs.fullPath) > -1 ? "is-active" : ""]'
                      @click='routerPush(subs.fullPath, subs)'
                    >{{subs[useProps.label]}}</div>
                  </template>
                </div>
              </template>
            </template>
            <!-- 无三级菜单 -->
            <template v-else>
              <div class='el-nav-menu-popover-container-item'>
                <template v-for='subs in menu[useProps.subs]'>
                  <div
                    v-if='!subs[useProps.hidden]'
                    :key='subs.fullPath'
                    :class='["el-nav-menu-router", useActivePath.indexOf(subs.fullPath) > -1 ? "is-active" : ""]'
                    @click='routerPush(subs.fullPath, subs)'
                  >{{subs[useProps.label]}}</div>
                </template>
              </div>
            </template>
          </div>
          <div slot="reference">
            <div class='el-nav-menu-header-label'>
              <span>{{menu[useProps.label]}}</span>
              <i class="el-nav-menu-header-icon el-icon-arrow-down"></i>
            </div>
          </div>
        </el-popover>
        <div
          v-else
          :key='menu.fullPath'
          class='el-nav-menu-header'
          :class='{ "is-active": useActivePath.indexOf(menu.fullPath) > -1 }'
          @click='routerPush(menu.fullPath, menu)'
        >{{menu[useProps.label]}}</div>
      </template>
    </template>
  </div>
</template>

<script>
import ElPopover from '@ued_fpi/element-ui/packages/popover';
export default {
  name: 'ElNavMenu',
  components: { ElPopover },
  props: {
    menus: Array,
    // 是否使用 vue-router 的模式，启用该模式会在激活导航时以 index 作为 path 进行路由跳转
    router: {
      type: Boolean,
      default: false
    },
    // 路径分隔符
    separator: {
      type: String,
      default: '/'
    },
    activePath: String,
    props: Object
  },
  data() {
    return {
      // 当前路由地址
      useActivePath: ''
    };
  },
  computed: {
    useProps() {
      return {
        key: 'key',
        label: 'label',
        hidden: 'hidden',
        subs: 'subs',
        ...this.props
      };
    },
    useMenus() {
      const { key, label, hidden, subs } = this.useProps;
      const separator = this.separator;
      const menus = [];
      this.menus.forEach(menu => {
        const useMenu = {};
        useMenu[key] = menu[key];
        useMenu[label] = menu[label];
        useMenu[hidden] = menu[hidden];
        useMenu.fullPath = separator + menu[key];
        // 需要给一级菜单增加是否有二/三级菜单的标记
        useMenu.hasChild = false;
        useMenu.hasGrandson = false;
        if (Array.isArray(menu[subs]) && menu[subs].length > 0) {
          // 添加有二级菜单标记
          useMenu.hasChild = true;
          // 遍历子节点时填充
          useMenu[subs] = [];
          let subHiddenTotal = 0;
          menu[subs].forEach(sub => {
            const useSub = {};
            useSub[key] = sub[key];
            useSub[label] = sub[label];
            useSub[hidden] = sub[hidden];
            useSub.fullPath = separator + menu[key] + separator + sub[key];
            useSub.hasChild = false;
            if (Array.isArray(sub[subs]) && sub[subs].length > 0) {
              // 添加有三级菜单标记
              useMenu.hasGrandson = true;
              // 添加有子节点标记
              useSub.hasChild = true;
              // 遍历子节点时填充
              useSub[subs] = [];
              let leafHiddenTotal = 0;
              sub[subs].forEach(item => {
                const useItem = {};
                useItem[key] = item[key];
                useItem[label] = item[label];
                useItem[hidden] = item[hidden];
                if (item[hidden]) leafHiddenTotal++;
                useItem.fullPath = separator + menu[key] + separator + sub[key] + separator + item[key];
                // 填充子级
                useSub[subs].push(useItem);
              });
              if (leafHiddenTotal === sub[subs].length) useSub[hidden] = true;
            }
            if (useSub[hidden]) subHiddenTotal++;
            // 填充子级
            useMenu[subs].push(useSub);
          });
          if (subHiddenTotal === menu[subs].length) useMenu[hidden] = true;
        }
        // 填充子级
        if (!useMenu[hidden]) menus.push(useMenu);
      });
      return menus;
    }
  },
  watch: {
    // 监听路由的变化
    $route: {
      handler(to, form) {
        if (this.activePath) {
          return;
        }
        try {
          this.useActivePath = to.fullPath.split('/').join(this.separator);
        } catch (error) {
          this.useActivePath = '';
        }
      },
      immediate: true
    },
    activePath: {
      handler(value) {
        if (value) {
          this.useActivePath = value;
        }
      },
      immediate: true
    }
  },
  methods: {
    /**
     * 根据router判断是否需要默认跳转
    */
    routerPush(path, menu) {
      if (this.useActivePath === path) return;
      if (this.router) {
        try {
          this.$router.push(path);
        } catch (error) {
          console.log(error);
        }
      }
      this.$emit('select', path, menu);
    },
    show(id) {
      try {
        this.$refs.navMenu.querySelector('.el-nav-menu-header-' + id).classList.add('is-opened');
      } catch (error) {
        console.log(error);
      }
    },
    hide(id) {
      try {
        this.$refs.navMenu.querySelector('.el-nav-menu-header-' + id).classList.remove('is-opened');
      } catch (error) {
        console.log(error);
      }
    }
  }
};
</script>
