// 导入Ant Design Vue的Menu和Icon组件
import Menu from 'ant-design-vue/es/menu';
import Icon from 'ant-design-vue/es/icon';

// 从Menu组件中解构出Item和SubMenu
const { Item, SubMenu } = Menu;

export default {
  // 组件名称
  name: 'SMenu',
  // 定义props，包括menu（菜单项数组），theme（主题），mode（模式），collapsed（折叠状态）
  props: {
    menu: {
      type: Array,
      required: true
    },
    theme: {
      type: String,
      required: false,
      default: 'dark'
    },
    mode: {
      type: String,
      required: false,
      default: 'inline'
    },
    collapsed: {
      type: Boolean,
      required: false,
      default: false
    }
  },
  // data函数返回组件的初始状态
  data () {
    return {
      openKeys: [], // 展开的菜单项的key数组
      selectedKeys: [], // 选中的菜单项的key数组
      cachedOpenKeys: [] // 缓存的展开项的key数组
    }
  },
  // 计算属性，返回menu的根路径数组
  computed: {
    rootSubmenuKeys: vm => {
      const keys = [];
      vm.menu.forEach(item => keys.push(item.path));
      return keys;
    }
  },
  // created生命周期钩子，组件创建后调用updateMenu方法
  created () {
    this.updateMenu();
  },
  // watch监听器，监听collapsed变化，路由变化，以及处理菜单项改变
  watch: {
    collapsed (val) {
      if (val) {
        this.cachedOpenKeys = this.openKeys.concat();
        this.openKeys = [];
      } else {
        this.openKeys = this.cachedOpenKeys;
      }
    },
    $route: function () {
      this.updateMenu();
    }
  },
  // 定义methods，包括处理菜单项改变，更新菜单，渲染菜单项和子菜单项，渲染图标等
  methods: {
    // 渲染图标的方法
    renderIcon: function (h, icon) {
      if (icon === 'none' || icon === undefined) {
        return null;
      }
      const props = {};
      typeof (icon) === 'object' ? props.component = icon : props.type = icon;
      return h(Icon, { props: { ...props } });
    },
    // 渲染菜单项的方法
    renderMenuItem: function (h, menu, pIndex, index) {
      // ...
    },
    // 渲染子菜单的方法
    renderSubMenu: function (h, menu, pIndex, index) {
      // ...
    },
    // 渲染菜单项的方法
    renderItem: function (h, menu, pIndex, index) {
      // ...
    },
    // 更新菜单的方法
    updateMenu: function () {
      // ...
    },
    // 处理菜单项改变的方法
    onOpenChange: function (openKeys) {
      // ...
    },
  },
  // render函数，返回组件的最终渲染结果
  render (h) {
    return h(
      Menu,
      {
        props: {
          theme: this.$props.theme,
          mode: this.$props.mode,
          openKeys: this.openKeys,
          selectedKeys: this.selectedKeys
        },
        on: {
          openChange: this.onOpenChange,
          select: obj => {
            this.selectedKeys = obj.selectedKeys
            this.$emit('select', obj)
          }
        }
      },
      this.renderMenu(h, this.menu)
    )
  }
}