import { memo, useCallback, useMemo, useState } from 'react';
import type { MouseEventHandler } from 'react';
import clsx from 'clsx';
import Grid from '@mui/material/Grid';
import { Header } from '../header';
import { Sidebar } from '../sidebar';
import type { DrawerStates } from '../sidebar';
import { LayoutContext } from './layout.context';
import createClasses from './styles';
import type { LayoutProps } from './types';
import { useLayoutBehavior } from './layout.hooks';
import { useRightSideBar } from '../right-sidebar';

export const drawerWidthOpen = '240px';
export const drawerWidthClose = '64px';

const Layout = (props: LayoutProps) => {
  const {
    children,
    disableSizeChanges = false,
    initLeftState = (localStorage.getItem('navigationMenuState') || 'closed') as DrawerStates,
    headerProps: { ContentComponent, breadcrumbsProps, classes: headerClasses, userControlsProps },
    sidebarProps,
    classes,
    hideHeader
  } = props;
  const { leftDrawerOpenState, setLeftDrawerOpenState, handleDrawerChange } = useLayoutBehavior(
    disableSizeChanges,
    initLeftState
  );

  const { drawerLocked } = useRightSideBar();

  const headerProps = useMemo(() => {
    if (ContentComponent) {
      return { ContentComponent };
    }
    if (breadcrumbsProps && userControlsProps) {
      return { breadcrumbsProps, classes: headerClasses, userControlsProps };
    }
    return { ContentComponent: () => <div /> };
  }, [ContentComponent, breadcrumbsProps, headerClasses, userControlsProps]);

  const handleDrawerStateChange = useCallback(
    (newState: DrawerStates): MouseEventHandler<HTMLButtonElement> =>
      e => {
        e.stopPropagation();
      },
    []
  );

  const styles = createClasses({ leftDrawerOpenState, hideHeader });

  return (
    <LayoutContext.Provider
      value={{
        leftDrawerOpenState,
        handleDrawerStateChange
      }}
    >
      <Grid container className={clsx(styles.container, classes?.container)} id="layoutContainer">
        <Sidebar
          {...sidebarProps}
          hideHeader={hideHeader}
          drawerWidthClose={drawerWidthClose}
          drawerWidthOpen={drawerWidthOpen}
          open={leftDrawerOpenState}
          setOpen={value => {
            localStorage.setItem('navigationMenuState', value as string);
            setLeftDrawerOpenState(value);
            sidebarProps.setOpen?.(value);
          }}
          handleDrawerChange={() => {
            handleDrawerChange();
            sidebarProps.handleDrawerChange?.();
          }}
        />
        <Grid
          container
          direction="column"
          item
          xs
          className={clsx(styles.innerContainer, classes?.innerContainer)}
        >
          {!hideHeader && (
            <Header
              {...headerProps}
              drawerWidthClose={drawerWidthClose}
              drawerWidthOpen={drawerWidthOpen}
              sidebarOpen={leftDrawerOpenState === 'locked'}
            />
          )}
          <Grid item className={clsx(styles.contentContainer, classes?.contentContainer)}>
            <div className={clsx(styles.content, classes?.content)}>{children}</div>
          </Grid>
        </Grid>
      </Grid>
    </LayoutContext.Provider>
  );
};

const m = memo(Layout);
export { m as Layout };
