<template>
  <el-menu
    :default-active="activeMenuIndex"
    class="el-menu-demo"
    :key="updateTopMenuActive"
    ref="menuContainer"
    mode="horizontal"
    @select="handleSelect"
  >
    <template v-for="(menu,index) in copy_Menus.filter(m => !m.hidden)">
      <el-menu-item
        v-if="!menu.children || menu.children.length == 0"
        :key="index"
        :index="menu.alias"
      >{{ menu.name}}</el-menu-item>
      <el-submenu v-else :key="index" :index="menu.alias">
        <template slot="title">{{ menu.name }}</template>
        <template v-if="menu.children && menu.children.length > 0">
          <el-menu-item
            v-for="(item,index) in menu.children"
            :key="index"
            :index="item.alias"
          >{{ item.name }}</el-menu-item>
        </template>
      </el-submenu>
    </template>
  </el-menu>
</template>

<script>
import { mapState, mapActions } from "vuex";
import utils from "@/hotent-ui-util.js";
import frontUtils from "@/utils.js";

export default {
  data() {
    return {
      updateTopMenuActive: 0,
      copy_Menus:[],
      resizeTick: false,
      firstMenuChange: false,
      templateMoreAlias: "_templateMoreMenu", //临时更多目录的别名
      activeMenuIndex: "" //默认选择首页
    };
  },
  computed: mapState({
    menus: state => state.menu.all,
    residual: state => state.menu.residual,
    menuMaps: state => state.menu.menuMaps,
    currentMenu: state => state.menu.currentMenu
  }),
  watch: {
    menus: {
      handler(newVal, oldVal){
        this.initMenus(newVal, oldVal);
      },
      immediate: true
    },
    "currentMenu.alias":{
      handler(val){
        this.activeMenuIndex = val
      }
    }
  },
  methods: {
    //动态新增二级路由
    addList(path,list){
      const that = this;
      let isAddPath = false;
      let isChildren = false;
      for(let i =0;i<list.length;i++){
        //判断当前点击菜单的路由别名是否存在 router.js 里面
        if(path == list[i].path){//存在
          //动态注册路由
          let index = path.replace("/","");
          let templatePreview_new = {path: "template/preview/:templateKey", name: "templatePreview_"+index,  props: true,
            component :resolve => require(["@/components/dataTemplate/templatePreview.vue"], resolve)};//数据报表
          let templateHref_new = {path: "href/template/:alias", name: "templateHref_"+index,  props: true,
            component :resolve => require(["@/components/dataTemplate/templateHref.vue"], resolve)};//URL菜单
          let querySql_new = {path: "querySql/queryView/:sqlAlias/:alias", name: "querySql_"+index,  props: true,
            component :resolve => require(["@/components/querySql/querySqlContent.vue"], resolve)};//自定义视图
          let template_new = {path: "template/form/:templateKey/:action", name: "template_"+index,  props: true,
            component :resolve => require(["@/components/dataTemplate/templateForm.vue"], resolve)};//数据报表
          let templateSingle_new = {path: "template/form/:templateKey/:action/:single", name: "templateSingle_"+index,  props: true,
            component :resolve => require(["@/components/dataTemplate/templateForm.vue"], resolve)};//数据报表
          let templateQuerys_new = {path: "template/preview/:templateKey/:single/:parameterqQuerys", name: "templateQuerys_"+index,  props: true,
            component :resolve => require(["@/components/dataTemplate/templatePreview.vue"], resolve)};//数据报表
          let draftList_new = {path: "draftList/:tempAlias/:dataViewFlag", name: "template_" + index, props: true,
            component: resolve => require(["@/components/dataTemplate/TemplateDraft.vue"], resolve)};//数据报表

          if (list[i].children){
            //判断是否重复添加路由
            for(let j=0;j<list[i].children.length;j++){
              let children = list[i].children[j];
              if(children.name == templatePreview_new.name){
                isAddPath = true;// true ： 重复路由
                break;
              }
            }
            if(!isAddPath){
              list[i].children.push(templatePreview_new);
              list[i].children.push(templateHref_new);
              list[i].children.push(querySql_new);
              list[i].children.push(template_new);
              list[i].children.push(templateSingle_new);
              list[i].children.push(templateQuerys_new);
              list[i].children.push(draftList_new);
              that.$router.$addRoutes(list);
            }
            isChildren = true;
            break;
          }
        }
      }
      return isChildren;
    },
    //动态添加路由
    routerAdd(path){
      const that = this;
      let isChildren = that.addList(path,that.$router.options.routes);//动态新增二级路由
      //当前点击菜单的路由别名不存在 router.js 里面
      if(!isChildren){
        let alias_new = {path: path, name: "alias_"+path.replace("/",""),
            component :resolve => require(["@/views/menuContent.vue"], resolve),children: []};
        that.$router.options.routes.push(alias_new);
        that.addList(path,that.$router.options.routes);//动态新增二级路由
      }
    },
    handleSelect(alias) {
      if (!alias) {
        return;
      }
      //把选择的一级菜单别名存入sessionStorage
      sessionStorage.menu_alias = alias;
      //选择一级菜单时
      let clickMenu = this.menus.find(m => m.alias == alias);
      if (!clickMenu) {
        const moreMenu = this.menus.find(
          m => m.alias == this.templateMoreAlias
        );
        moreMenu &&
          moreMenu.children &&
          (clickMenu = moreMenu.children.find(m => m.alias == alias));
      }

      if (clickMenu) {
        let path = "";
        if (clickMenu.path == undefined) {
          path = clickMenu.alias;
        } else {
          path = clickMenu.path;
        }
        if (path.indexOf("/") < 0) {
          path = "/" + path;
        }
        this.setCurrentMenu(alias);
        if(sessionStorage.menu_path && sessionStorage.menu_path.indexOf(alias)!=-1){
          path = sessionStorage.menu_path;
        }else{
          sessionStorage.menu_path = "";
        }
        //点击首页
        if(alias=="home"){
          sessionStorage.menu_alias="";
          this.$router.push({ path: path });
        }else{//其他一级菜单
          this.routerAdd("/" + alias);//动态添加路由
          this.$router.push({ path: path });
        }
      }
    },
    setCurrentMenu(alias) {
      let that = this;
      for (let i = 0; i < that.menus.length; i++) {
        if (that.menus[i].alias === alias) {
          this.$store.dispatch("menu/getCurrentMenu", {
            alias: that.menus[i].alias,
            name: that.menus[i].name
          });
          break;
        }
      }
    },
    // 页面缩放计时触发器（避免页面缩放频繁触发，导致菜单会频繁更新）
    resizeTimerTrigger() {
      if (this.resizeTick || this.residual) {
        return;
      }
      this.resizeTick = true;
      setTimeout(() => {
        this.handleMenuOverMore();
        this.resizeTick = false;
      }, 600);
    },
    // 移除Menus中的临时更多菜单
    removeTemplateMoreMenu(menus) {
      let targetIndex = -1;
      // 查找菜单中是否有临时更多菜单
      const moreMenu = menus.find((m, index) => {
        if (m.alias == this.templateMoreAlias) {
          targetIndex = index;
          return m;
        }
      });
      // 如果有，则删掉这个菜单
      if (targetIndex > -1) {
        menus.splice(targetIndex, 1);
      }
      return targetIndex > -1;
    },
    // 处理目录显示宽度超限的情况
    handleMenuOverMore() {
      const menuContainer = this.$refs.menuContainer;
      if (
        !menuContainer ||
        !menuContainer.$children ||
        menuContainer.$children.length == 0
      ) {
        return;
      }

      const containerWidth = menuContainer.$el.clientWidth;
      // 目录宽度超限的元素索引
      let boundaryIndex = 0;
      var childrenTotalWidth = menuContainer.$children.reduce(
        (cur, child, index) => {
          let t = child.$el.clientWidth + cur;
          if (t > containerWidth && boundaryIndex == 0) {
            boundaryIndex = index;
          }
          return t;
        },
        0
      );
      // 如果宽度超限，把menus分为常规菜单和更多菜单
      if (childrenTotalWidth > containerWidth) {
        let copyMenus = [...this.menus];
        this.removeTemplateMoreMenu(copyMenus);
        // 在超限索引大于2时才把超过的目录显示在更多中
        if (boundaryIndex > 2) {
          let moreMenuChildren = [];

          copyMenus
            .filter((m, i) => i > boundaryIndex - 2)
            .forEach(m => {
              let nm = { ...m };
              moreMenuChildren.push(nm);
              // 把超出部分的菜单标记为隐藏
              m.hidden = true;
            });

          let moreMenu = {
            id: "-2",
            name: "更多",
            alias: this.templateMoreAlias,
            children: moreMenuChildren
          };
          copyMenus.push(moreMenu);
          this.$store.dispatch("menu/setTemplateMenus", copyMenus);
        } else {
          throw "屏幕太窄，菜单可能显示不全";
        }
      }
      // 否则把更多菜单合并到menus中
      else {
        let copyMenus = [...this.menus],
          needDispath = this.removeTemplateMoreMenu(copyMenus);

        // 如果有，则重置为原来的菜单
        if (needDispath) {
          copyMenus.forEach(m => delete m["hidden"]);
          this.$store.dispatch("menu/setTemplateMenus", copyMenus);
        }
      }
    },
    init(){
      let isFalg = false;
      //模块开发添加为前端菜单点击待办处理任务时判断
      if(this.$route.matched.length==1 && JSON.stringify(this.$route.params) !="{}"){
        isFalg = false;
      }
      if(this.$route.matched.length==1 && JSON.stringify(this.$route.params) =="{}"){
        isFalg = true;
      }
      //管理端发起流程，处理任务，自由跳转会携带showMenu参数。需要展示菜单
      if((this.$route.query && this.$route.query.showMenu) || (this.$route.matched.length>1)){
        isFalg = true;
      }
    
      if (!this.currentMenu.alias && isFalg) {
        const this_ = this;
        this_.$store.dispatch("menu/getStaticMenus").then(() => {
          this_.$store.dispatch("menu/getDefaultMenus").then(() => {
            if (sessionStorage.menu_alias) {
              this_.activeMenuIndex = sessionStorage.menu_alias;
            }
            this_.handleSelect(this_.activeMenuIndex);
          });
        });
      }
      this.$root.$on("resize", this.resizeTimerTrigger);
    },
    initMenus(newVal, oldVal) {
      if (newVal.length>0){
        let newMenus= [...newVal]
        newMenus.sort(function(a,b){
          return a.sn - b.sn
        })
        this.copy_Menus = newMenus;
      }else{
        this.copy_Menus = newVal;
      }

      if (newVal && newVal.length > 1 && !this.residual) {
        if(!utils.arrayEquals(newVal, oldVal) || !this.firstMenuChange){
          this.firstMenuChange = true;
          setTimeout(() => this.handleMenuOverMore(), 100);
        }
      }
      if(newVal && newVal.length > 1 ){
        let copyMenus = [...this.copy_Menus];
        //判断第一个菜单是否是更多菜单，如果是则把更多菜单放在最后
        if(copyMenus[0].id=="-2"){
          let copyObj = copyMenus[0];
          copyMenus.splice(0, 1);
          copyMenus.push(copyObj);
          this.copy_Menus = [...copyMenus];
        }
      }
      frontUtils.Menu.addSyncMenus(this, newVal);
    }
  },
  created() {
    this.init();
    let _this = this;
    this.$root.$on("updateTopMenuActive",(name)=>{
      // 首页跳转更新一级菜单的状态
      if( _this.$route.fullPath && _this.$route.fullPath.split("/").length>=1){
        let path = _this.$route.fullPath.split("/")[1];
        sessionStorage.menu_alias = path;
        _this.setCurrentMenu(path);
        //_this.updateTopMenuActive++;
      }
    });
  }
};
</script>

<style lang="scss" scoped>
@import "@/assets/css/element-variables.scss";
.el-menu, .el-menu > li, ul.el-menu > li.el-submenu /deep/ div.el-submenu__title {
  height: 48px;
  line-height: 48px;
  background-color: $--theme-color !important;
}
.el-menu--horizontal .el-menu-item:not(.is-disabled):hover {
    outline: none;
    outline-color: initial;
    outline-style: none;
    outline-width: initial;
    color: #ffd600;
    
}
.el-menu--horizontal .el-menu-item:not(.is-disabled):focus{
  color: #fff;
}
.el-menu-demo{
  /deep/ .el-menu-item{
    color: #fff;
  }
  /deep/ .el-menu-item.is-active{
    color: #fff;
    border-bottom: 2px solid #fff;
  }
}
</style>
