<script setup lang="ts">
import { useRouter } from "vue-router";
import path from "path-browserify";
import { isExternal } from "@/utils";
import AppLink from "./Link.vue";
import SvgIcon from "@/components/SvgIcon/index.vue";
import { SidebarRoutes } from "@/layout/components/Sidebar/types";

const router = useRouter();
const props = defineProps({
  /**
   * 路由(eg:level_3_1)
   */
  item: {
    type: Object,
    required: true,
  },
  /**
   * 父层级完整路由路径(eg:/level/level_3/level_3_1)
   */
  basePath: {
    type: String,
    required: true,
  },
});
const itemRoute: SidebarRoutes = reactive(props.item);
const onlyOneChild = ref(); // 临时变量，唯一子路由
/**
 * 判断当前路由是否只有一个子路由
 *
 * 1：如果只有一个子路由： 返回 true
 * 2：如果无子路由 ：返回 true
 *
 * @param children 子路由数组
 * @param parent 当前路由
 */
function hasOneShowingChild(children: any = [], parent: any) {
  // 需要显示的子路由数组
  const showingChildren: any = children.filter((item: any) => {
    if (item.meta?.hidden) {
      return false; // 过滤不显示的子路由
    } else {
      onlyOneChild.value = item; // 唯一子路由赋值（多个子路由情况 onlyOneChild 变量是用不上的）
      return true;
    }
  });
  // 1：如果无显示的子路由, 复制当前路由信息作为其子路由，满足只拥有一个子路由的条件，所以返回 true
  if (showingChildren.length === 0) {
    onlyOneChild.value = { ...parent, path: "", noShowingChildren: true };
    return true;
  }
  // 2：如果只有一个显示的子路由, 判断子路由children
  if (showingChildren.length === 1) {
    if (showingChildren[0].children) {
      // 是否还有可显示的子路由
      if (hasOneShowingChild(showingChildren[0].children, showingChildren[0])) {
        return true;
      }
    }
    return true;
  }
  return false;
}

/**
 * 解析路径
 *
 * @param routePath 路由路径
 */
function resolvePath(routePath: string): string {
  if (isExternal(routePath)) {
    return routePath;
  }
  if (isExternal(props.basePath || "")) {
    return props.basePath || "";
  }
  // 完整路径 = 父级路径(/level/level_3) + 路由路径
  // return fullPath 相对路径 → 绝对路径
  return path.resolve(props.basePath || "", routePath);
}

/**
 * 处理子页面时父级菜单高亮
 */
function addActiveClass(routePath: string) {
  const currentBase: string = routePath.split("/")[1];
  document.querySelectorAll(".el-menu-item").forEach((item) => {
    const pathBase: string = item.attributes
      .getNamedItem("mark")
      .value.split("/")[1];
    if (currentBase == pathBase) {
      const active = document.querySelectorAll(".el-menu-item.is-active");
      if (active && active.length) {
        active.forEach((a) => {
          if (a) {
            a.classList.remove("is-active");
          }
        });
      }
      item.classList.add("is-active");
      //console.log(currentBase, "is-active current路由");
      return;
    }
  });
}

router.afterEach((to, from) => {
  //console.log(from.fullPath, to.fullPath, "路由变动");
  setTimeout(() => {
    addActiveClass(to.fullPath);
  }, 100);
});
if (onMounted) {
  onMounted(() => {
    addActiveClass(router.currentRoute.value.fullPath);
    //console.log(router.currentRoute.value.fullPath,"当前路由");
  });
}
</script>
<template>
  <div v-if="!itemRoute.meta || !itemRoute.meta.hidden">
    <template
      v-if="
        hasOneShowingChild(itemRoute.children, itemRoute) &&
        (!onlyOneChild.children || onlyOneChild.noShowingChildren)
      "
    >
      <!-- 只包含一个子路由节点的路由，显示其【唯一子路由】 -->
      <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
        <el-menu-item
          :index="resolvePath(onlyOneChild.path)"
          :mark="resolvePath(onlyOneChild.path)"
        >
          <svg-icon
            v-if="onlyOneChild.meta && onlyOneChild.meta.icon"
            :icon-class="onlyOneChild.meta.icon"
          />
          <template #title>
            <span>{{ onlyOneChild.meta.title }}</span>
          </template>
        </el-menu-item>
      </app-link>
    </template>
    <el-sub-menu v-else :index="resolvePath(itemRoute.path)" teleported>
      <!-- 包含多个子路由 $route.path  -->
      <template #title>
        <svg-icon
          v-if="itemRoute.meta && itemRoute.meta.icon"
          :icon-class="itemRoute.meta.icon"
        />
        <span v-if="itemRoute.meta && itemRoute.meta.title">{{
          itemRoute.meta.title
        }}</span>
      </template>
      <sidebar-item
        v-for="child in itemRoute.children"
        :key="child.path"
        :item="child"
        :base-path="resolvePath(child.path)"
      />
    </el-sub-menu>
  </div>
</template>
