import { ref, watch } from "vue";
import type { Ref } from "vue";
import type { RouteLocationNormalizedLoaded } from "vue-router";

interface UseOpenedMenusOptions {
  route: RouteLocationNormalizedLoaded;
  accordion: Ref<boolean>;
}

export const useOpenedMenus = ({ route, accordion }: UseOpenedMenusOptions) => {
  const openedMenus = ref<string[]>([]);

  const stringify = (arr: string[]) => JSON.stringify([...arr].sort());

  const normalizePath = (path: string) => (path.startsWith("/") ? path : `/${path}`);

  const collectAncestorPaths = (path?: string) => {
    if (!path) return [];
    const normalized = normalizePath(path);
    const segments = normalized.split("/").filter(Boolean);
    return segments.reduce<string[]>((acc, _, index) => {
      if (index === segments.length - 1) return acc;
      acc.push(`/${segments.slice(0, index + 1).join("/")}`);
      return acc;
    }, []);
  };

  const buildTargetOpenedPaths = () => {
    const targetSet = new Set<string>();
    // 检查 route.path 是否存在
    if (route && route.path) {
      collectAncestorPaths(route.path).forEach(path => targetSet.add(path));
    }
    // 检查 route.meta 是否存在
    if (route && route.meta) {
      const activeMenuPath = route.meta.activeMenu as string | undefined;
      if (activeMenuPath) {
        const normalizedActive = normalizePath(activeMenuPath);
        collectAncestorPaths(normalizedActive).forEach(path => targetSet.add(path));
        targetSet.add(normalizedActive);
      }
    }
    return Array.from(targetSet);
  };

  const calculateOpenedMenus = () => {
    const targetPaths = buildTargetOpenedPaths();
    if (!targetPaths.length) {
      return accordion.value ? [] : [...openedMenus.value];
    }
    if (accordion.value) return targetPaths;
    const menuSet = new Set(openedMenus.value);
    targetPaths.forEach(path => menuSet.add(path));
    return Array.from(menuSet);
  };

  watch(
    () => [route.path, route.meta.activeMenu, accordion.value],
    () => {
      const newOpenedMenus = calculateOpenedMenus();
      if (stringify(newOpenedMenus) !== stringify(openedMenus.value)) {
        openedMenus.value = newOpenedMenus;
      }
    },
    { immediate: true }
  );

  return {
    openedMenus
  };
};
