import * as React from "react";
import NextLink from "next/link";
import { useRouter as useNextRouter } from "next/router";
import { styled } from "@mui/material/styles";
import MuiDrawer from "@mui/material/Drawer";
import Toolbar from "@mui/material/Toolbar";
import List from "@mui/material/List";
import Divider from "@mui/material/Divider";
import Button from "@mui/material/Button";
import IconButton from "@mui/material/IconButton";
import DatasetIcon from "@mui/icons-material/Dataset";
import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
import ListItem from "@mui/material/ListItem";
import ListItemButton from "@mui/material/ListItemButton";
import ListItemIcon from "@mui/material/ListItemIcon";
import ListItemText from "@mui/material/ListItemText";
import ListSubheader from "@mui/material/ListSubheader";
import Typography from "@mui/material/Typography";
import useMediaQuery from "@mui/material/useMediaQuery";
import { useTheme } from "@mui/material/styles";

import { DRAWER_WIDTH } from "@/constants";
import LeftNavCfg from "@/config/leftNavCfg.json";
import { string2Hash, scrollToElementIfInView } from "@/utils";

const Drawer = styled(MuiDrawer, {
  // shouldForwardProp: (prop) => prop !== "open",
})(({ theme, open }) => ({
  "& .MuiDrawer-paper": {
    position: "relative",
    whiteSpace: "nowrap",
    width: DRAWER_WIDTH,
    transition: theme.transitions.create("width", {
      easing: theme.transitions.easing.sharp,
      duration: theme.transitions.duration.enteringScreen,
    }),
    // boxSizing: "border-box",
    // ...(!open && {
    //   overflowX: "hidden",
    //   transition: theme.transitions.create("width", {
    //     easing: theme.transitions.easing.sharp,
    //     duration: theme.transitions.duration.leavingScreen,
    //   }),
    //   width: theme.spacing(7),
    //   [theme.breakpoints.up("sm")]: {
    //     width: theme.spacing(9),
    //   },
    // }),
  },
}));

export interface LeftNavProps {
  open: boolean;
  toggleDrawer: () => void;
}

export default function LeftNav(props: LeftNavProps) {
  const { open, toggleDrawer } = props;

  const theme = useTheme();
  const matches = useMediaQuery(theme.breakpoints.down("md"));

  return (
    <>
      {matches ? (
        <Drawer
          variant="temporary"
          open={open}
          anchor="left"
          onClose={toggleDrawer}
        >
          <Toolbar
            sx={{
              display: "flex",
              alignItems: "center",
              justifyContent: "flex-end",
              px: [1],
            }}
          >
            <IconButton onClick={toggleDrawer}>
              <ChevronLeftIcon />
            </IconButton>
          </Toolbar>
          <Divider />
          <List component="nav">
            <ListItems />
          </List>
        </Drawer>
      ) : (
        <Drawer
          variant="permanent"
          open={true}
          sx={{
            height: "100vh",
          }}
        >
          <Toolbar
            sx={{
              display: "flex",
              alignItems: "center",
              justifyContent: "flex-end",
              px: [1],
            }}
          >
            {/* <IconButton onClick={toggleDrawer}>
              <ChevronLeftIcon />
            </IconButton> */}
          </Toolbar>
          <Divider />
          <List
            component="nav"
            sx={{
              pl: (theme) => theme.spacing(3),
              overflowY: "auto",
            }}
          >
            <ListItems />
          </List>
        </Drawer>
      )}
    </>
  );
}

export type LeftNavItemType = {
  title: string;
  url?: string;
  children?: LeftNavItemChildrenType[];
};

export interface LeftNavItemChildrenType extends LeftNavItemType {}

export type FlattenLeftNavItemType = {
  id: string;
  title: string;
  url?: string;
  depth: number;
};

const flattenLeftNavItems = (
  leftNav: LeftNavItemType[],
  depth = 1
): FlattenLeftNavItemType[] => {
  const flattenItems = leftNav.reduce((acc: FlattenLeftNavItemType[], item) => {
    acc.push({
      id: string2Hash(item.title),
      title: item.title,
      url: item?.url,
      depth,
    });
    if (item.children) {
      const children = flattenLeftNavItems(item.children, depth + 1);
      return [...acc, ...children];
    }
    return acc;
  }, []);
  return flattenItems;
};

const ListItems = () => {
  const { pathname } = useNextRouter();

  const listItemsMemo = React.useMemo(() => {
    return flattenLeftNavItems(LeftNavCfg.leftNav);
  }, []);

  return (
    <>
      {listItemsMemo.map((item) => {
        if (item?.url) {
          return (
            <NavItem key={item.id} active={pathname === item.url} {...item} />
          );
        }
        return <NavItemLabel key={item.id} {...item} />;
      })}
    </>
  );
};

const NavItem = (
  props: FlattenLeftNavItemType & {
    active?: boolean;
  }
) => {
  const { id, title, url, active, depth } = props;

  const eleRef = React.useRef<HTMLLIElement>(null);

  React.useEffect(() => {
    if (eleRef.current && active) {
      scrollToElementIfInView(eleRef.current as any);
    }
  }, [active]);

  return (
    <>
      <ListItem
        ref={eleRef}
        dense
        sx={{
          ...(depth === 1 && {
            pl: (theme) => theme.spacing(1),
          }),
          py: (theme) => theme.spacing(0.2),
        }}
      >
        <Button
          id={id}
          component={NextLink}
          href={url}
          variant="text"
          size="small"
          sx={{
            color: "text.secondary",
            alignItems: "center",
            // borderRadius: 1,
            display: "flex",
            justifyContent: "flex-start",
            ml: (theme) => theme.spacing(1 + (props.depth - 2) * 2),
            textAlign: "left",
            width: "100%",
            fontWeight: 400,
            fontSize: "16px",
            lineHeight: "150%",
            "&.MuiButtonBase-root:hover": {
              backgroundColor: "action.hover",
            },
            ...(depth === 1 && {
              pl: (theme) => theme.spacing(1 + (props.depth - 1) * 2),
              color: "grey.900",
              fontStyle: "normal",
              fontWeight: "bold",
              fontSize: "16px",
              lineHeight: "150%",
            }),
            ...(active && {
              backgroundColor: "action.selected",
              color: "primary.main",
              fontWeight: 600,
            }),
          }}
        >
          <ListItemText
            // primary={props.title}
            disableTypography
            sx={{
              m: 0,
            }}
          >
            <Typography
              component="div"
              sx={{
                fontWeight: "inherit",
                fontSize: "inherit",
                lineHeight: "inherit",
                color: "inherit",
                whiteSpace: "break-spaces",
              }}
            >
              {title}
            </Typography>
          </ListItemText>
        </Button>
      </ListItem>
    </>
  );
};

const NavItemLabel = (props: FlattenLeftNavItemType) => {
  const { id, title } = props;
  return (
    <ListSubheader
      component="div"
      disableSticky
      id={id}
      sx={{
        pl: (theme) => theme.spacing(1 + (props.depth - 1) * 2),
        py: (theme) => theme.spacing(1),
        color: "grey.900",
        fontStyle: "normal",
        fontWeight: "bold",
        fontSize: "16px",
        lineHeight: "150%",
      }}
    >
      {title}
    </ListSubheader>
  );
};
