import type { Breakpoint } from '@mui/material/styles';

import { merge } from 'es-toolkit';
import { useBoolean } from 'minimal-shared/hooks';

import Box from '@mui/material/Box';
import Alert from '@mui/material/Alert';
import { useTheme } from '@mui/material/styles';
import Typography from '@mui/material/Typography';
import useMediaQuery from '@mui/material/useMediaQuery';

import { _langs, _notifications } from 'src/_mock';

import { NavMobile, NavDesktop } from './nav';
import { layoutClasses } from '../core/classes';
import { _account } from '../nav-config-account';
import { dashboardLayoutVars } from './css-vars';
import { navData } from '../nav-config-dashboard';
import { MainSection } from '../core/main-section';
import { Searchbar } from '../components/searchbar';
import { _workspaces } from '../nav-config-workspace';
import { MenuButton } from '../components/menu-button';
import { HeaderSection } from '../core/header-section';
import { LayoutSection } from '../core/layout-section';
import { AccountPopover } from '../components/account-popover';
import { LanguagePopover } from '../components/language-popover';
import { NotificationsPopover } from '../components/notifications-popover';

import type { MainSectionProps } from '../core/main-section';
import type { HeaderSectionProps } from '../core/header-section';
import type { LayoutSectionProps } from '../core/layout-section';

// ----------------------------------------------------------------------

type LayoutBaseProps = Pick<LayoutSectionProps, 'sx' | 'children' | 'cssVars'>;

export type DashboardLayoutProps = LayoutBaseProps & {
  layoutQuery?: Breakpoint;
  slotProps?: {
    header?: HeaderSectionProps;
    main?: MainSectionProps;
  };
};

export function DashboardLayout({
  sx,
  cssVars,
  children,
  slotProps,
  layoutQuery = 'lg',
}: DashboardLayoutProps) {
  const theme = useTheme();
  const isDesktop = useMediaQuery(theme.breakpoints.up(layoutQuery));

  const {
    value: mobileOpen,
    onFalse: onMobileClose,
    onToggle: onMobileToggle,
  } = useBoolean();

  const {
    value: desktopOpen,
    onFalse: onDesktopClose,
    onToggle: onDesktopToggle,
  } = useBoolean(true);

  const renderHeader = () => {
    const headerSlotProps: HeaderSectionProps['slotProps'] = {
      container: {
        maxWidth: false,
      },
    };

    const inheritedHeaderSx = slotProps?.header?.sx;

    const headerSx: HeaderSectionProps['sx'] = [
      (t) => ({
        bgcolor: '#a52431',
        color: t.vars.palette.common.white,
        zIndex: 'var(--layout-header-zIndex)',
        '--color': t.vars.palette.common.white,
        '& .MuiButtonBase-root, & .MuiIconButton-root, & .MuiTypography-root, & .MuiSvgIcon-root': {
          color: t.vars.palette.common.white,
        },
        '& .MuiInputBase-root': {
          color: t.vars.palette.common.white,
          bgcolor: 'rgba(255, 255, 255, 0.12)',
          '& .MuiInputBase-input::placeholder': {
            color: 'rgba(255, 255, 255, 0.72)',
          },
          '& .MuiSvgIcon-root': {
            color: t.vars.palette.common.white,
          },
        },
      }),
      ...(Array.isArray(inheritedHeaderSx)
        ? inheritedHeaderSx
        : inheritedHeaderSx
          ? [inheritedHeaderSx]
          : []),
    ];

    const headerSlots: HeaderSectionProps['slots'] = {
      topArea: (
        <Alert severity="info" sx={{ display: 'none', borderRadius: 0 }}>
          This is an info Alert.
        </Alert>
      ),
      leftArea: (
        <Box sx={{ display: 'flex', alignItems: 'center', gap: 1.25 }}>
          {/** @slot Nav mobile */}
          <MenuButton
            onClick={isDesktop ? onDesktopToggle : onMobileToggle}
            sx={{ ml: -1 }}
          />
          <Typography variant="h6" sx={{ fontWeight: 700 }}>
            Digital Data Hub
          </Typography>
          <NavMobile
            data={navData}
            open={mobileOpen}
            onClose={onMobileClose}
            workspaces={_workspaces}
            layoutQuery={layoutQuery}
          />
        </Box>
      ),
      rightArea: (
        <Box sx={{ display: 'flex', alignItems: 'center', gap: { xs: 0, sm: 0.75 } }}>
          {/** @slot Searchbar */}
          <Searchbar />

          {/** @slot Language popover */}
          <LanguagePopover data={_langs} />

          {/** @slot Notifications popover */}
          <NotificationsPopover data={_notifications} />

          {/** @slot Account drawer */}
          <AccountPopover data={_account} />
        </Box>
      ),
    };

    return (
      <HeaderSection
        disableElevation
        disableOffset
        layoutQuery={layoutQuery}
        {...slotProps?.header}
        slots={{ ...headerSlots, ...slotProps?.header?.slots }}
        slotProps={merge(headerSlotProps, slotProps?.header?.slotProps ?? {})}
        sx={headerSx}
      />
    );
  };

  const renderFooter = () => null;

  const renderMain = () => <MainSection {...slotProps?.main}>{children}</MainSection>;

  return (
    <LayoutSection
      /** **************************************
       * @Header
       *************************************** */
      headerSection={renderHeader()}
      /** **************************************
       * @Sidebar
       *************************************** */
      sidebarSection={
        <NavDesktop
          open={desktopOpen}
          data={navData}
          layoutQuery={layoutQuery}
          workspaces={_workspaces}
        />
      }
      /** **************************************
       * @Footer
       *************************************** */
      footerSection={renderFooter()}
      /** **************************************
       * @Styles
       *************************************** */
      cssVars={{ ...dashboardLayoutVars(theme), ...cssVars }}
      sx={[
        {
          [`& .${layoutClasses.main}`]: {
            [theme.breakpoints.up(layoutQuery)]: {
              pl: desktopOpen ? 'var(--layout-nav-vertical-width)' : 0,
              transition: theme.transitions.create(['padding-left'], {
                easing: 'var(--layout-transition-easing)',
                duration: 'var(--layout-transition-duration)',
              }),
            },
          },
        },
        ...(Array.isArray(sx) ? sx : [sx]),
      ]}
    >
      {renderMain()}
    </LayoutSection>
  );
}
