import React from "react";

type NavItemProps = {
  to?: string;
  children?: React.ReactNode;
  [key: string]: any;
};

/**
 * Filters navigation items based on user's roles & dynamic permission config.
 */
export const filterNavLinksByRole = (
  navItems: React.ReactNode,
  userRoles?: string[],
  permissions?: Record<string, string[]>
): React.ReactNode => {
  if (!userRoles || userRoles.length === 0) return null;

  if (userRoles.includes("super_admin")) return navItems;

  const filteredItems = React.Children.map(navItems, (item) => {
    if (!React.isValidElement<NavItemProps>(item)) return null;

    const props = item.props as NavItemProps;
    const path = props.to;
    const children = props.children;

    if (children) {
      const filteredChildren = React.Children.map(children, (child) => {
        if (!React.isValidElement<NavItemProps>(child)) return null;

        const childProps = child.props as NavItemProps;
        const childPath = childProps.to;

        return childPath && shouldShowItem(childPath, userRoles, permissions)
          ? child
          : null;
      })?.filter(Boolean);

      if (filteredChildren?.length) {
        // Cast item as ReactElement<NavItemProps> to allow children
        return React.cloneElement<NavItemProps>(item, {
          ...props,
          children: filteredChildren,
        });
      }

      return path && shouldShowItem(path, userRoles, permissions) ? item : null;
    }

    return path && shouldShowItem(path, userRoles, permissions) ? item : null;
  })?.filter(Boolean);

  return filteredItems ?? null;
};

const shouldShowItem = (
  path: string,
  userRoles?: string[],
  permissions?: Record<string, string[]>
): boolean => {
  if (!userRoles || userRoles.length === 0) return false;
  if (!permissions) return false;

  const cleanPath = path.startsWith("/") ? path.slice(1) : path;

  if (!permissions[cleanPath]) return false;

  return userRoles.some((role) => permissions[cleanPath].includes(role));
};
