<template>
  <NMenu
    :options="menus"
    :inverted="inverted"
    :mode="mode"
    :collapsed="collapsed"
    :collapsed-width="64"
    :collapsed-icon-size="20"
    :indent="24"
    :accordion="true"
    :expanded-keys="openKeys"
    keyField="path"
    labelField="'name"
    @update:value="clickMenuItem"
    @update:expanded-keys="menuExpanded"
    :value="getSelectedKeys"
    ref="NMenuRef"
  />
  <!--         -->
</template>

<script lang="ts">
import { defineComponent, ref, onMounted, reactive, computed, watch, toRefs, unref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useAsyncRouteStore } from '@/store/modules/asyncRoute'
import { generatorMenu, generatorMenuMix } from '@/utils'
import { useProjectSettingStore } from '@/store/modules/projectSetting'
import { useProjectSetting } from '@/hooks/setting/useProjectSetting'
import { Searchs } from '@/utils/searchs'
import { cNotM } from 'naive-ui'
export default defineComponent({
  name: 'Menu',
  components: {},
  props: {
    mode: {
      // 菜单模式
      type: String,
      default: 'vertical'
    },
    collapsed: {
      // 侧边栏菜单是否收起
      type: Boolean
    },
    //位置
    location: {
      type: String,
      default: 'left'
    }
  },
  emits: ['update:collapsed', 'clickMenuItem'],
  setup(props, { emit }) {
    // 当前路由
    const currentRoute = useRoute()
    const router = useRouter()
    const asyncRouteStore = useAsyncRouteStore()
    const settingStore = useProjectSettingStore()
    const searchs = new Searchs('')
    const menus = ref<any[]>([])
    const NMenuRef = ref()
    const selectedKeys = ref<string>(currentRoute.path as string)
    // const selectedKeys = ref<string>("momodangqianluyou");
    const headerMenuSelectKey = ref<string>('')

    const { getNavMode } = useProjectSetting()

    const navMode = getNavMode

    // 获取当前打开的子菜单
    const matched = currentRoute.matched[currentRoute.matched.length - 1].path
    // const matched = [] as any[];

    const getOpenKeys = matched ? [matched] : []
    const state = reactive({
      openKeys: getOpenKeys as any
    })

    const inverted = computed(() => {
      return ['dark', 'header-dark'].includes(settingStore.navTheme)
    })

    const getSelectedKeys = computed(() => {
      let location = props.location
      return location === 'left' || (location === 'header' && unref(navMode) === 'horizontal')
        ? unref(selectedKeys)
        : unref(headerMenuSelectKey)
    })

    // 监听分割菜单
    watch(
      () => settingStore.menuSetting.mixMenu,
      () => {
        updateMenu()
        if (props.collapsed) {
          emit('update:collapsed', !props.collapsed)
        }
      }
    )

    // 监听菜单收缩状态
    // watch(
    //   () => props.collapsed,
    //   (newVal) => {
    //   }
    // );

    // 跟随页面路由变化，切换菜单选中状态
    watch(
      () => currentRoute.fullPath,
      () => {
        updateMenu()
      }
    )

    function updateSelectedKeys() {
      const matched = currentRoute.matched[currentRoute.matched.length - 1]
      // 这里去找 把树的父元素找出来

      const str = currentRoute.meta?.parentPermission
        ? currentRoute.meta?.parentPermission
        : (matched.path as any)

      state.openKeys = (getMenuListName(str, menus.value) as any) || []

      const activeMenu: string =
        (currentRoute.meta?.parentPermission as string) || currentRoute.path || ''
      selectedKeys.value = activeMenu ? (activeMenu as string) : (currentRoute.path as string)
    }

    function updateMenu() {
      if (!settingStore.menuSetting.mixMenu) {
        menus.value = generatorMenu(asyncRouteStore.getMenus)
        NMenuRef.value.showOption()
      }
      // else {
      //   //混合菜单
      //   const firstRouteName: string = (currentRoute.matched[0].path as string) || ''
      //   //
      //   menus.value = generatorMenuMix(asyncRouteStore?.getMenus, firstRouteName, props.location)
      //   const activeMenu: string = currentRoute?.matched[0].meta?.activeMenu as string
      //   headerMenuSelectKey.value = (activeMenu ? activeMenu : firstRouteName) || ''
      // }
      updateSelectedKeys()
    }
    // 获取当前选中菜单的父级
    const getMenuListName = (path: string, list = [] as any, result = [] as any) => {
      for (let i = 0; i < list.length; i += 1) {
        const item = list[i]
        // 找到目标
        if (item.path === path || item.meta?.parentPermission === path) {
          // 加入到结果中
          result.push(item.path)
          // 因为可能在第一层就找到了结果，直接返回当前结果
          if (result.length === 1) return result
          return true
        }

        // ||
        // 如果存在下级节点，则继续遍历
        if (item.children) {
          // 预设本次是需要的节点并加入到最终结果result中
          result.push(item.path)
          const find = getMenuListName(path, item.children, result)
          // 如果不是false则表示找到了，直接return，结束递归
          if (find) {
            return result
          }
          // 到这里，意味着本次并不是需要的节点，则在result中移除
          result.pop()
        }
      }
      // 如果都走到这儿了，也就是本轮遍历children没找到，将此次标记为false
      return false
    }
    //
    // 点击菜单
    function clickMenuItem(key: string) {
      if (/http(s)?:/.test(key)) {
        window.open(key)
      } else {
        const allRouter = router.getRoutes()

        const tagRouter = allRouter.find((item) => {
          return item.path == key
        })

        searchs.removeByRouter(tagRouter?.path as string)
        router.push({ path: key })
      }
      emit('clickMenuItem' as any, key)
    }

    //展开菜单
    function menuExpanded(openKeys: string[]) {
      if (!openKeys) return
      const latestOpenKey = openKeys.find((key) => {
        return state.openKeys.indexOf(key) === -1 || state.openKeys[state.openKeys.length - 1]
      })

      const isExistChildren = findChildrenLen(latestOpenKey as string)
      state.openKeys = isExistChildren ? (latestOpenKey ? [latestOpenKey] : []) : openKeys
    }

    //查找是否存在子路由
    function findChildrenLen(key: string) {
      if (!key) return false
      const subRouteChildren: string[] = []

      for (const { children, path } of unref(menus)) {
        if (children && children.length) {
          subRouteChildren.push(path as string)
        }
      }

      return subRouteChildren.includes(key)
    }

    onMounted(() => {
      updateMenu()
    })

    return {
      ...toRefs(state),
      inverted,
      menus,
      selectedKeys,
      headerMenuSelectKey,
      getSelectedKeys,
      clickMenuItem,
      menuExpanded,
      NMenuRef
    }
  }
})
</script>
