import React, { useEffect, useMemo } from "react";

import LinkIcon from "@mui/icons-material/Link";

import { useI18n } from "../../contexts/I18nContext";
import { RouteInfo, useRouter } from "../../contexts/RouterContext";
import { useUser } from "../../contexts/UserContext";
import { NavigationOverrides } from "../../types";
import { hasGroup } from "../../util/has_group";
import { hasPermission } from "../../util/has_permission";
import { isURL } from "../../util/is_url";

import NavRailItem from "./NavRailItem";

export interface NavRailRoutesProps {
  navigation: NavigationOverrides;
}

export const NavRailRoutes: React.FC<NavRailRoutesProps> = ({ navigation }) => {
  const { routes, setCustomRoutes } = useRouter();
  const { user } = useUser();
  const { t } = useI18n();

  useEffect(() => {
    const newRoutes = Object.values(navigation)
      .filter((entry): entry is { route: RouteInfo } => Boolean(entry && entry?.route))
      .map((entry) => entry.route);
    setCustomRoutes(newRoutes);
  }, [navigation, setCustomRoutes]);

  const navItems = useMemo(() => {
    const appItems: React.ReactNode[] = [];

    for (const [routeId, navEntry] of Object.entries(navigation)) {
      if (navEntry == null || navEntry === false || navEntry.hidden) continue;

      const navInfo = typeof navEntry === "object" ? navEntry : {};

      if (navInfo.permission && !hasPermission(user, navInfo.permission)) continue;
      if (navInfo.group && !hasGroup(user, navInfo.group)) continue;
      if (navInfo.excludedGroup && hasGroup(user, navInfo.excludedGroup)) continue;

      let title = navInfo.title;
      let icon = navInfo.icon;
      let route: RouteInfo | undefined;
      let href: string | undefined;

      if (isURL(routeId)) {
        icon ??= LinkIcon;
        href = routeId;
      } else {
        route = routes.find((r) => r.id === routeId);
        if (route == null) {
          console.warn(`No route found for navigation entry ${routeId}`);
          continue;
        }

        title ??= route.title;
      }

      appItems.push(
        <NavRailItem
          key={routeId}
          href={href}
          icon={icon}
          route={route}
          title={t(title ?? "Missing title")}
        />,
      );
    }

    return appItems;
  }, [routes, navigation, user, t]);

  return <>{navItems}</>;
};

export default NavRailRoutes;
