import React, { memo, useCallback, useMemo } from "react";
import { useLocation } from "react-router-dom";

import Avatar from "@mui/material/Avatar";
import ListItemButton, { ListItemButtonProps } from "@mui/material/ListItemButton";
import ListItemIcon from "@mui/material/ListItemIcon";
import ListItemText from "@mui/material/ListItemText";
import { styled } from "@mui/material/styles";
import { Box } from "@mui/system";

import { RouteInfo, useRouter } from "../../contexts/RouterContext";
import { LogoType } from "../../types";
import Logo from "../Logo";

export interface NavRailItemProps extends Omit<ListItemButtonProps, "onClick"> {
  icon?: LogoType;
  href?: string;
  onClick?: () => void;
  route?: RouteInfo;
  subtitle?: string | React.ReactNode;
  title: string;
}

export const StyledListItemButton = styled(ListItemButton, {
  name: "BananasNavRail",
  slot: "Item",
})(({ theme }) =>
  theme.unstable_sx({
    color: "inherit",
    px: "unset",
    marginInline: 0.5,
    py: 1,

    "&.Mui-selected .MuiBox-root": {
      bgcolor: theme.palette.mode == "light" ? "rgba(0, 0, 0, 0.25)" : "rgba(0, 0, 0, 0.25)",
    },
    "&:hover": {
      bgcolor: "transparent",
    },
    "&:hover .MuiBox-root, &.Mui-selected:hover .MuiBox-root": {
      bgcolor: theme.palette.mode == "light" ? "rgba(0, 0, 0, 0.25)" : "rgba(255, 255, 255, 0.1)",
    },
    "&.Mui-selected, &.Mui-selected:hover": {
      bgcolor: "transparent",
    },
    "&:hover .navRailItemTextPrimary": {
      fontWeight: 600,
    },
  }),
);

export const StyledListItemIconBox = styled(Box, {
  name: "BananasNavRail",
  slot: "ItemIconBox",
})(({ theme }) =>
  theme.unstable_sx({
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    borderRadius: "999px",
    width: 56,
    height: 32,
    transition: theme.transitions.create(["background-color"], {
      duration: theme.transitions.duration.shortest,
    }),
  }),
);

export const StyledListItemIcon = styled(ListItemIcon, {
  name: "BananasNavRail",
  slot: "ItemIcon",
})(({ theme }) =>
  theme.unstable_sx({
    p: 1,
    py: 0.4,
    color: "currentColor",
    justifyContent: "center",
    ".MuiSvgIcon-root": {
      height: 22,
    },
    transition: theme.transitions.create(["transform"], {
      duration: theme.transitions.duration.shortest,
    }),
  }),
);

export const NavRailItem: React.FC<React.PropsWithChildren<NavRailItemProps>> = ({
  children,
  icon: Icon,
  href,
  onClick,
  route,
  subtitle,
  sx,
  title,
  ...props
}) => {
  const location = useLocation();
  const { navigate } = useRouter();
  const isHref = href != null;

  const handleClick = useCallback(() => {
    if (isHref) {
      return;
    } else if (onClick != null) {
      onClick();
    } else if (route != null) {
      navigate(route);
    } else {
      console.error(`[NAV_RAIL_ITEM] ${title} must have either a route or an onClick prop.`);
    }
  }, [isHref, navigate, onClick, route]);

  if (route == null && onClick == null && !isHref) {
    console.error(`[NAV_RAIL_ITEM] ${title} must have either a route or an onClick prop.`);
  }

  if (route != null && onClick != null) {
    console.error(`[NAV_RAIL_ITEM] ${title} cannot have both a route and an onClick prop.`);
  }
  const isSelected = useMemo(
    () => (route?.path ? location.pathname.startsWith(route?.path) : false),
    [location.pathname, route?.path],
  );

  return (
    <StyledListItemButton
      disableRipple
      component={isHref ? "a" : "div"}
      selected={isSelected}
      sx={{
        justifyContent: "center",
        flexDirection: "column",
        ...sx,
      }}
      onClick={handleClick}
      {...props}
      {...(isHref ? { href } : {})}
    >
      <StyledListItemIconBox>
        <StyledListItemIcon sx={{ width: 26, height: 26 }}>
          {Icon != null ? (
            <Logo src={Icon} />
          ) : (
            <Avatar sx={{ width: 18, height: 18, fontWeight: 600 }}>{title.substring(0, 1)}</Avatar>
          )}
        </StyledListItemIcon>
      </StyledListItemIconBox>

      <ListItemText
        classes={{ primary: "navRailItemTextPrimary" }}
        primary={title}
        primaryTypographyProps={{
          fontSize: { xs: 10, sm: 11 },
          lineHeight: { xs: "12px", sm: "14px" },
          sx: {
            fontWeight: isSelected ? 600 : 400,
            fontVariationSettings: { sm: '"wdth" 100', xs: '"wdth" 75' },
            transition: "font-weight 150ms ease",
          },
        }}
        secondary={subtitle}
        sx={{
          opacity: 1,
          textWrap: "wrap",
          textAlign: "center",
        }}
      />
      {children}
    </StyledListItemButton>
  );
};

export default memo(NavRailItem);
