import React, {useState, useRef} from 'react';
import {useLocation, useNavigate} from "react-router-dom";
import { IoMdMenu } from "react-icons/io";
import {MdOutlineKeyboardArrowDown,MdOutlineKeyboardArrowRight} from "react-icons/md";
import { useMediaQuery,
         CssBaseline,
         Box, 
         Toolbar, 
         List, 
         ListItem, 
         ListItemButton, 
         ListItemIcon, 
         ListItemText,  
         Divider, 
         IconButton, 
         Collapse, 
         Popover } from "@mui/material";
import { useTheme,} from '@mui/material/styles';
import { Appbar, DrawerHeader, StyleDrawer } from './styles';
import { checkIfAnyActiveChild, hasChildren } from "./utils";

interface SidebarProps {
    variant:'permanent',  
    anchor:	'left',
    sx?:any,
    sidedata?:Array<NavLink>,
    appbar?:boolean,
    drawerheader?:boolean,
    handlecallback?:any,
    drawerWidth?:any,
    openDrawer?:boolean,
    ROUTE_MAPPER ?: {
      [key : string] : string
  },
}

interface UrlLink{
  id : string,
  label ?: string,
  url ?: string,
  isSubLinks ?: boolean,
  sublinks ?:  Array<UrlLink>, 
  shouldOpenNewTab ?: boolean
}

export interface NavLink extends UrlLink{
  icon ?: React.ReactNode,
  navigate ?: () => void  
}

const MenuItem = ({item, open, location, isDesktop, anchorEl, setAnchorEl, navigate = () => {}, openchild, setOpenchild}:any) => {

    const menuRef = useRef<HTMLLIElement|null>(null);
    const popoverRef = useRef<HTMLDivElement|null>(null);
    const [subChildOpen, setSubChildOpen] = useState(null);
    const hasSubLinks = hasChildren(item);
    const isSelected = hasSubLinks ?
          checkIfAnyActiveChild(item?.sublinks, location) : 
          item.url === location?.pathname;
    
    const openPopup = menuRef.current && anchorEl?.contains(menuRef?.current);

    const handlePopoverOpen = (event: React.MouseEvent<HTMLElement>) => {
        !open && setAnchorEl(event.currentTarget);
        event.stopPropagation();
        event.preventDefault();
    }

    const handleClick = (id: string) => {
      if(openchild == id){
        setOpenchild(null)
      }
      else{
        setOpenchild(id)
      }
    }
    const handleNavigateClick = () => {
      if(hasSubLinks) return;
      if(!(item?.sublinks) && (item?.shouldOpenNewTab)){
        window.open(item?.url, "_blank");
      }
      else{
        navigate(item?.url as string)
      }
    }

    return <>
        <ListItem id={item?.id} onClick={() => open && isDesktop && hasSubLinks ? handleClick(item?.id) : {}} aria-owns={openPopup ? 'mouse-over-popover' : undefined}
        aria-haspopup="true"
        ref={menuRef}
        onMouseEnter={handlePopoverOpen}
        sx={{
          backgroundColor:'transparent',
          "& .Mui-selected": {
            color:'#1c84ee',
            backgroundColor:'transparent',
            ':hover':{
              backgroundColor:  'white'
            },
            }
        }}>   
        <ListItemButton selected={isSelected} onClick={handleNavigateClick}>
        <ListItemIcon>{item.icon}</ListItemIcon>
        <ListItemText primary={item.label} />
        {hasSubLinks && <>
            {openchild == item?.id ? <MdOutlineKeyboardArrowDown /> : <MdOutlineKeyboardArrowRight />}
        </>}
        </ListItemButton>
      </ListItem>
      <Collapse in={open && isDesktop && hasSubLinks && openchild == item?.id}  timeout="auto" unmountOnExit>
        <List component="div" disablePadding >
          {item?.sublinks?.map((child:any, key:any) => (         
            <Box sx={{paddingLeft:'10px'}}>
                <MenuItem key={key} item={child} open={open} openchild={subChildOpen} setOpenchild={setSubChildOpen} navigate={navigate} isDesktop/>
            </Box>
          ))}
        </List>
      </Collapse>
      {!open && openPopup && menuRef.current && 
            <Popover
            id="mouse-over-popover"
            sx={{ pointerEvents: 'none'}}
            open={openPopup}
            anchorEl={menuRef.current}
            anchorOrigin={{
            vertical: 'top',
            horizontal: 'right',
            }}
            transformOrigin={{
            vertical: 'top',
            horizontal: 'left',
            }}
            // disablePortal
            >
            {hasSubLinks ? 
                <Box sx={{ minWidth: "200px"}} ref={popoverRef}>
                    <ListItemText primary={item.label} sx={{paddingLeft:"10px",color:  '#1c84ee'}} />
                    <List>
                        {item?.sublinks?.map((child:string, key:any) => (
                            <MenuItem key={key} item={child} open={open} openchild={subChildOpen} setOpenchild={setSubChildOpen}/>  
                        ))}
                    </List>
                </Box> :
                <ListItemText 
                    primary={item.label} 
                    sx={{ color:'#1c84ee',
                        width:"150px",
                        height:"40px",
                        paddingLeft:"20px",
                        paddingTop:"10px"}}/>}
            </Popover>
    }
    </>
};

const Sidebar = ({ 
    sidedata, 
    appbar,
    drawerWidth = 300,
    openDrawer = true,
    drawerheader,
    handlecallback = () => {},
    ROUTE_MAPPER,
    ...other } : SidebarProps) => {

  const theme = useTheme();
  const location = useLocation();
  const navigate = useNavigate();
  const isDesktop = useMediaQuery('(min-width:600px)');
  const [open, setOpen] = useState(false);
  const [openchild, setOpenchild] = useState(null);
  const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
  
  React.useEffect(()=>{
    setOpen(!open)
   },[openDrawer])

  const onDrawerHandler = (value: boolean) => () => setOpen(value);
  
  return (
    <Box sx={{ display: 'flex' }}>
      <CssBaseline />
    {appbar &&  
    <Appbar position="fixed" open={open} drawerWidth={drawerWidth}>
        <Toolbar>
          <IconButton
            color="inherit"
            aria-label="open drawer"
            onClick={onDrawerHandler(true)}
            edge="start"
            sx={{
              marginRight: 5,
              ...(open && { display: 'none' }),
            }}
          >
            <IoMdMenu />
          </IconButton>
        </Toolbar>
      </Appbar>}
      <StyleDrawer 
      drawerWidth={drawerWidth}
      appbar={appbar}
        open={open}             
        theme={theme}
        sx={{
          textOverflow:'hidden'
        }}
        {...other}>
       {
        drawerheader &&  <DrawerHeader>
        <IconButton onClick={onDrawerHandler(false)}>
            {theme.direction === 'ltr' &&  <IconButton
            color="inherit"
            aria-label="open drawer"
          >
             <IoMdMenu />
          </IconButton> }
           </IconButton>
        </DrawerHeader>
       }
        <Divider />    
        {sidedata?.map((item, key) => 
            <MenuItem 
                key={key} 
                {...{
                    item,
                    open,
                    location,
                    isDesktop,
                    anchorEl, 
                    setAnchorEl,
                    navigate,
                    openchild, 
                    setOpenchild,
                    ROUTE_MAPPER
                }}/>)}   
      </StyleDrawer>    
    </Box>
  );
}

export default Sidebar;