<template>
  <el-menu
    :default-openeds="openKeys"
    :default-active="getSelectedKeys"
    :theme="getTheme"
    :collapse="getCollapsed"
    :collapse-transition="false"
    :unique-opened="getUniqueOpened"
    :mode="props.mode"
    style="width: 100%"
    @select="menuItemClick"
    @open="subMenuItemClick"
  >
    <template v-for="item in menus" :key="item.key">
      <el-menu-item v-if="!item.children" :key="getMenuKey(item.key)" :index="item.key">
        <template #title>
          <icon :name="item.icon" :size="20" v-if="item.icon"/>
          <span>{{ item.title }}</span>
        </template>
      </el-menu-item>
      <template v-else><ReSubMenu :parent="item" /></template>
    </template>
  </el-menu>
</template>

<script lang="ts" setup>
  import { ref, computed, watch, onMounted, unref, inject } from 'vue';
  import { useRoute, useRouter } from 'vue-router';

  import { generatorMenu, generatorMenuMix } from '@/utils';

  import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
  import { useAsyncRouteStore } from '@/store/modules/asyncRoute';
  import { useProjectSettingStore } from '@/store/modules/projectSetting';
  import ReSubMenu from './ReSubMenu.vue';

  const collapsed = inject('collapsed');

  const { getMenuSetting, getNavMode, getNavTheme } = useProjectSetting();

  const navMode = getNavMode;

  defineEmits(['update:collapsed']);

  const props = defineProps({
    mode: {
      type: String,
      default: 'vertical',
    },
    theme: {
      type: String,
      default: 'dark',
    },
    //位置
    location: {
      type: String,
      default: 'left',
    },
  });

  // 当前路由
  const currentRoute = useRoute();
  const router = useRouter();

  const settingStore = useProjectSettingStore();

  const menus = ref<any>([]);
  const headerMenuSelectKey = ref<string>('');

  // 获取当前打开的子菜单
  const matched = currentRoute.matched;
  const activeMenu = currentRoute.meta?.activeMenu ?? null;
  const selectedKeys = ref<string>((activeMenu ?? currentRoute.name) as string);
  const openKeys = ref(matched && matched.length ? matched.map((item) => item.name) : []);

  const asyncRouteStore = useAsyncRouteStore();

  const getCollapsed = computed(() => {
    let location = props.location;
    return location === 'left' ? unref(collapsed) : false;
  });

  const getUniqueOpened = computed(() => {
    return getMenuSetting.value.uniqueOpened;
  });

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

  // 监听分割菜单
  watch(
    () => settingStore.menuSetting.mixMenu,
    () => {
      updateMenu();
    },
  );

  // 跟随页面路由变化，切换菜单选中状态
  watch(
    () => currentRoute.fullPath,
    () => {
      updateMenu();
      const matched = currentRoute.matched;
      openKeys.value = matched.map((item) => item.name);
      const activeMenu: string = (currentRoute.meta?.activeMenu as string) || '';
      selectedKeys.value = activeMenu ? activeMenu : (currentRoute.name as string);
    },
  );

  function getMenuKey(key) {
    return `${props.location}_${key}`;
  }

  function updateMenu() {
    if (!settingStore.menuSetting.mixMenu) {
      menus.value = generatorMenu(asyncRouteStore.getMenus);
    } else {
      //混合菜单
      const firstRouteName: string = (currentRoute.matched[0].name 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) || '';
    }
  }

  // const getMenuMode = computed(() => {
  //   if (props.mode === 'vertical') {
  //     return getMenuIsPop.value ? 'pop' : 'vertical';
  //   } else {
  //     return props.mode;
  //   }
  // });

  const getTheme = computed(() => {
    return getNavTheme.value === 'light' ? 'light' : props.theme;
  });

  //点击菜单项时触发
  function menuItemClick(key) {
    if (/http(s)?:/.test(key)) {
      window.open(key);
    } else {
      router.push({ name: key });
    }
  }

  function subMenuItemClick(_, keys) {
    if (!keys) return;
    const latestOpenKey = keys.find((key) => openKeys.value.indexOf(key) === -1);
    const isExistChildren = findChildrenLen(latestOpenKey as string);
    openKeys.value = isExistChildren ? (latestOpenKey ? [latestOpenKey] : []) : keys;
  }

  //查找是否存在子路由
  function findChildrenLen(key: string) {
    if (!key) return false;
    const subRouteChildren: string[] = [];
    for (const { children, key } of unref(menus)) {
      if (children && children.length) {
        subRouteChildren.push(key as string);
      }
    }
    return subRouteChildren.includes(key);
  }

  onMounted(() => {
    updateMenu();
  });
</script>
