import clsx from "clsx";
import type { ReactNode } from "react";
import { Link } from "react-router";

interface INavListProps {
  items: INavItem[][];
  className?: string;
}

interface INavEntryProps {
  items?: INavItem[];
  children?: ReactNode;
  className?: string;
}

interface INavHeaderProps {
  text?: string;
  className?: string;
  icon?: string;
  children?: ReactNode;
}

interface INavItemProps {
  link: string;
  text?: string;
  className?: string;
  isExternal?: boolean;
  color?: string;
  icon?: string;
  children?: ReactNode;
}

export interface INavItem {
  disable?: boolean;
  header?: boolean;
  link?: string;
  text?: string;
  className?: string;
  icon?: string;
  isExternal?: boolean;
  color?: string;
  onClick?: (event: unknown) => Promise<void>
}

export function NavList({ items, className }: INavListProps) {
  return (
    <>
      {items.map((items, index) => (
        <NavEntry key={index} items={items} className={className} />
      ))}
    </>
  );
}

export function NavEntry({ items, className, children }: INavEntryProps) {
  return (
    <div className={clsx("global-sidebar-entry", className)}>
      {children ?? (
        <>
          {items?.reduce<JSX.Element[]>((navItems, item, index) => {
            if (item.disable) {
              return navItems;
            }

            if (item.header) {
              const navItem = item.link ? (
                <NavItem
                  key={item.text}
                  link={item.link}
                  text={item.text}
                  className={clsx("clickable-header", item.className)}
                  icon={item.icon}
                />
              ) : (
                <NavHeader
                  key={index}
                  text={item.text}
                  className={item.className}
                  icon={item.icon}
                />
              );

              navItems.push(navItem);
            } else {
              const navItem = (
                <NavItem
                  key={index}
                  // @ts-expect-error not sure about the usage
                  link={item.link}
                  text={item.text}
                  className={item.className}
                  isExternal={item.isExternal}
                  color={item.color}
                  icon={item.icon}
                />
              );

              navItems.push(navItem);
            }

            return navItems;
          }, [])}
        </>
      )}
    </div>
  );
}

export function NavHeader({
  text,
  icon,
  className,
  children,
}: INavHeaderProps) {
  return (
    <div className={clsx("global-sidebar-entry-item", "header", className)}>
      {icon && <img src={icon} className="global-sidebar-entry-item-icon" />}
      {children ?? text}
    </div>
  );
}

export function NavItem({
  link,
  isExternal,
  color,
  icon,
  text = link,
  className,
  children,
}: INavItemProps) {
  return (
    <Link
      to={link}
      target={isExternal ? "_blank" : undefined}
      className={clsx("global-sidebar-entry-item", className)}
      style={color ? { color } : undefined}
    >
      {icon && <img className="global-sidebar-entry-item-icon" src={icon} />}
      {children ?? text}
    </Link>
  );
}
