import React, { memo } from 'react';
import clsx from 'clsx';
import makeStyles from '@mui/styles/makeStyles';
import AppBar from '@mui/material/AppBar';
import Toolbar from '@mui/material/Toolbar';
import { Breadcrumbs } from '../@navigation/breadcrumbs';
import type { BreadcrumbsProps } from '../@navigation/breadcrumbs';
import { UserControls } from '../user-controls';
import type { UserControlsProps } from '../user-controls';
import type { Theme } from '../@styles/theme-provider';

const createClasses = makeStyles<Theme, ClassesProps>(theme => ({
  root: props => {
    const { drawerWidthClose, drawerWidthOpen, sidebarOpen } = props;
    return {
      zIndex: 96,
      top: 0,
      position: 'sticky',
      display: 'flex',
      justifyContent: 'center',
      backgroundColor: theme.palette.common.white,
      borderBottom: `1px solid ${theme.palette.primary[200]}`,
      width: `calc(100% - ${sidebarOpen ? drawerWidthOpen : drawerWidthClose})`,
      marginLeft: `${sidebarOpen ? drawerWidthOpen : drawerWidthClose}`,
      height: '64px',
      boxSizing: 'content-box'
    };
  },
  toolbar: {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'space-between',
    padding: theme.spacing(0, 4)
  }
}));

interface ClassesProps {
  drawerWidthClose: string;
  drawerWidthOpen: string;
  sidebarOpen: boolean;
}

export type HeaderProps = ClassesProps &
  (
    | {
        /**
         * If passed, then `userControlsProps`, `breadcrumbsProps` and `classes` will become
         * redundant and it will be displayed instead of all the original content.
         */
        ContentComponent: () => JSX.Element;
        userControlsProps?: never;
        breadcrumbsProps?: never;
        classes?: never;
      }
    | {
        /**
         * Props which will be passed to the to the user controls component.
         */
        userControlsProps: UserControlsProps;
        /**
         * Props which will be passed to the to the breadcrumbs component.
         */
        breadcrumbsProps: BreadcrumbsProps;
        /**
         * Override classes.
         */
        classes?: ReturnType<typeof createClasses>;
        ContentComponent?: never;
      }
  );

const Header = (props: HeaderProps) => {
  const {
    userControlsProps,
    breadcrumbsProps,
    drawerWidthClose,
    drawerWidthOpen,
    sidebarOpen,
    classes,
    ContentComponent
  } = props;

  const styles = createClasses({
    drawerWidthClose,
    drawerWidthOpen,
    sidebarOpen
  });

  return (
    <AppBar elevation={0} position="static" className={clsx(styles.root, classes?.root)}>
      <Toolbar className={clsx(styles.toolbar, classes?.toolbar)}>
        {ContentComponent ? (
          <ContentComponent />
        ) : (
          <>
            {breadcrumbsProps && <Breadcrumbs {...breadcrumbsProps} />}
            {userControlsProps && <UserControls {...userControlsProps} />}
          </>
        )}
      </Toolbar>
    </AppBar>
  );
};

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