// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

<template>
  <a-menu
      :mode="mode"
      :theme="theme"
      :openKeys="openKeys"
      v-model:selectedKeys="selectedKeys"
      @click="selectMenu"
      @openChange="onOpenChange"
    >
    <template v-for="(item, index) in menuData" :key="index">
      <a-sub-menu v-if="item.children && !item.hideChildrenInMenu" :key="item.path">
        <template #title>
          <span>
            <render-icon
            v-if="item.meta.icon && typeof (item.meta.icon) === 'string'"
            :icon="item.meta.icon"
            @click="() => { handleClickParentMenu(item) }" />
            <span @click="() => { handleClickParentMenu(item) }">{{ $t(item.meta.title) }}</span>
          </span>
        </template>
        <template v-for="children in item.children" :key="children.path">
          <a-menu-item :key="children.path" v-if="!children.hidden">
            <router-link :to="{ name: children.name, target: children.meta.target || null }">
              <render-icon
                v-if="children.meta.icon && typeof (children.meta.icon) === 'string'"
                :icon="children.meta.icon" />
              <font-awesome-icon
                v-else-if="children.meta.icon && Array.isArray(children.meta.icon)"
                :icon="children.meta.icon"
                class="anticon"
                :style="[$store.getters.darkMode ? { color: 'rgba(255, 255, 255, 0.65)' } : { color: '#888' }]" />
              <render-icon v-else :svgIcon="children.meta.icon" />
              <span>{{ $t(children.meta.title) }}</span>
            </router-link>
          </a-menu-item>
        </template>
      </a-sub-menu>
      <a-menu-item v-else :key="item.path">
        <router-link :to="{ name: item.name, target: item.meta.target || null }">
          <render-icon
            v-if="item.meta.icon && typeof (item.meta.icon) === 'string'"
            :icon="item.meta.icon"
            @click="() => { handleClickParentMenu(item) }" />
          <font-awesome-icon
            v-else-if="item.meta.icon && Array.isArray(item.meta.icon)"
            :icon="item.meta.icon"
            class="anticon"
            :style="[$store.getters.darkMode ? { color: 'rgba(255, 255, 255, 0.65)' } : { color: '#888' }]"
            @click="() => { handleClickParentMenu(item) }" />
          <span>{{ $t(item.meta.title) }}</span>
        </router-link>
      </a-menu-item>
    </template>
  </a-menu>
</template>

<script>

export default {
  name: 'SMenu',
  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 () {
    return {
      openKeys: [],
      selectedKeys: [],
      cachedOpenKeys: [],
      cachedPath: null
    }
  },
  computed: {
    rootSubmenuKeys: vm => {
      const keys = []
      vm.menu.forEach(item => keys.push(item.path))
      return keys
    },
    menuData () {
      return this.menu.filter(item => !item.hidden)
    }
  },
  created () {
    this.updateMenu()
  },
  watch: {
    collapsed (val) {
      this.openKeys = val ? [] : this.cachedOpenKeys
    },
    '$route.fullPath': function () {
      this.updateMenu()
    }
  },
  methods: {
    selectMenu (obj) {
      this.selectedKeys = [obj.key]
    },
    onOpenChange (openKeys) {
      const latestOpenKey = openKeys.find(key => this.openKeys.indexOf(key) === -1)
      if (this.rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
        this.openKeys = openKeys
      } else {
        this.openKeys = latestOpenKey ? [latestOpenKey] : []
      }
    },
    updateMenu () {
      const routes = this.$route.matched.concat()

      if (routes.length >= 4 && this.$route.meta.hidden) {
        routes.pop()
        this.selectedKeys = [routes[2].path]
      } else {
        this.selectedKeys = [routes.pop().path]
      }

      const openKeys = []
      if (this.mode === 'inline') {
        routes.forEach(item => {
          openKeys.push(item.path)
        })
      }

      this.cachedPath = this.selectedKeys[0]
      this.cachedOpenKeys = openKeys
      if (!this.collapsed) {
        this.openKeys = openKeys
      }
    },
    handleClickParentMenu (menuItem) {
      if (this.cachedPath === menuItem.redirect) {
        return
      }
      if (menuItem.redirect) {
        this.cachedPath = menuItem.redirect
        setTimeout(() => this.$router.push({ path: menuItem.path }))
      }
    }
  }
}
</script>

<style>
.sider .ant-menu-vertical .ant-menu-item {
  margin-right: 0;
}
</style>
