import { Disposition } from '@/components/ra-forms/LongForm/types';
import { Box, Grid, GridProps, Stack } from '@mui/material';
import _ from 'lodash';
import { Children, isValidElement, useMemo } from 'react';
import { default as StickyBox } from 'react-sticky-box';

enum SidebarSectionPosition {
  TOP = 'top',
  BOTTOM = 'bottom'
}

type ISidebarProps = {
  sticky?: boolean;
  disposition?: Disposition;
} & GridProps;

type ISidebarSectionProps = React.PropsWithChildren<{
  position: SidebarSectionPosition;
}>;

function Sidebar(props: ISidebarProps) {
  const { sticky = true, disposition = { xl: 3, lg: 3, md: 4, sm: 4, xs: 12 }, spacing = 2 } = props;
  const gridProps = _.omit(props, ['sticky', 'disposition', 'spacing']);
  const Wrapper = sticky ? StickyBox : Box;
  const wrapperProps = useMemo(() => {
    return sticky ? { offsetTop: 74, offsetBottom: (spacing as number) * 2 } : {};
  }, [sticky, spacing]);
  return (
    <Grid {...gridProps} item {...disposition}>
      <Wrapper {...wrapperProps}>
        <Stack spacing={spacing}>{props.children}</Stack>
      </Wrapper>
    </Grid>
  );
}

function SidebarSection(props: ISidebarSectionProps) {
  return <>{props.children}</>;
}

type ISidebarChildren = {
  top: Array<React.ReactNode>;
  bottom: Array<React.ReactNode>;
};

function useSidebarChildren(props: React.PropsWithChildren): ISidebarChildren {
  const { children } = props;
  const result = useMemo<ISidebarChildren>(() => {
    const result: ISidebarChildren = {
      top: [],
      bottom: []
    };
    Children.forEach<React.ReactNode>(children, (Child) => {
      if (isValidElement(Child) && Child?.type === SidebarSection) {
        const { position } = Child.props;
        switch (position) {
          case SidebarSectionPosition.TOP:
            result.top.push(Child);
            break;
          case SidebarSectionPosition.BOTTOM:
            result.bottom.push(Child);
            break;
        }
      }
    });
    return result;
  }, [children]);
  return result;
}

export { Sidebar, SidebarSection, SidebarSectionPosition, useSidebarChildren };
