<template>
    <el-menu ref="menu"
             :default-active="innerActive"
             :default-openeds="defaultOpeneds"
             :mode="mode"
             :collapse="collapse"
             :background-color="backgroundColor"
             :text-color="textColor"
             :active-text-color="activeTextColor"
             :unique-opened="uniqueOpened"
             :menu-trigger="menuTrigger"
             :router="router"
             @open="openMenu"
             @close="closeMenu"
             @select="selectMenu">
        <sub-menu v-for="(menuItem, index) in innerMenus" :key="index" :menu-item="menuItem"></sub-menu>
    </el-menu>
</template>
<script>
/**
 * Created by fuzl on 2017-11-1.
 */
import subMenu from './sub-menu.vue';
import util from '../utils';

export default {
  name: 'menus',
  components: {
    subMenu,
  },
  data() {
    return {
      innerActive: this.defaultActive,
      innerMenus: [],
      _indexMap: {},
    };
  },
  props: {
    menus: Array,
    mode: String,
    defaultOpeneds: Array,
    defaultActive: [String, Number],
    collapse: Boolean,
    backgroundColor: String,
    textColor: String,
    activeTextColor: String,
    uniqueOpened: Boolean,
    menuTrigger: String,
    router: Boolean,
  },
  created() {
    this._presetMenus();
  },
  methods: {
    /**
        * @description 数据检查一遍，查看index是否存在重复的情况，没有则设置index
        * */
    _presetMenus() {
      this._indexMap = Object.create(null);
      this.innerMenus = this.menus.map((menu, index) => this._checkIndex(menu, `${index}`));
    },
    /**
        * @description 检查菜单索引是否设置正确
        * @param {Object} menu - 菜单项
        * @param {String} genIndex - 自动生成的index
        * */
    _checkIndex(menu, genIndex) {
      // copy menu
      menu = { ...menu };
      if (menu.index) {
        const { index } = menu;
        if (util.asserts.noExistPropertyInMap(index, this._indexMap)) {
          this._indexMap[index] = menu;
        }
      } else {
        menu.index = genIndex;
        this._indexMap[genIndex] = menu;
      }
      // 检查子菜单和分组情况
      if (menu.submenus) {
        menu.submenus = menu.submenus.map((menu, index) => this._checkIndex(menu, `${genIndex}-${index}`));
      }
      if (menu.group) {
        menu.group = menu.group.map((menu, index) => this._checkIndex(menu, `${genIndex}-${index}`));
      }
      return menu;
    },
    openMenu(index) {
      this.$emit('open', index, this.getMenuItemByIndex(index));
    },
    closeMenu(index) {
      this.$emit('close', index, this.getMenuItemByIndex(index));
    },
    selectMenu(index) {
      const menuItem = this.getMenuItemByIndex(index);
      this.$emit('select', index, menuItem);
    },
    /**
        * @description 根据index获取当前的menuItem对象
        * @param {String} index
        * @return {Object}
        * */
    getMenuItemByIndex(index) {
      return this._indexMap[index];
    },
    /**
        * @description 取得一个菜单项中的子菜单列表
        * @param {Object} menuItem
        * @return Array|Null
        * */
    getSubItems(menuItem) {
      if (util.isEmptyArray(menuItem.submenus) === false) {
        return menuItem.submenus;
      } if (util.isEmptyArray(menuItem.group) === false) {
        return menuItem.group;
      }
      return null;
    },
    /**
        * @description 打开子菜单 since 2.0
        * @method open
        * @param {String} index - 需要打开的 sub-menu 的 index
        * */
    open(index) {
      return this.$refs.menu.open(index);
    },
    /**
        * @description 关闭子菜单 since 2.0
        * @method close
        * @param {String} index - 需要收起的 sub-menu 的 index
        * */
    close(index) {
      return this.$refs.menu.close(index);
    },
  },
  watch: {
    menus() {
      this._presetMenus();
    },
    $route() {
      this.innerActive = this.$route.path;
    },
    defaultActive() {
      this.innerActive = this.defaultActive;
    },
  },
};
</script>
