/**
 * @Move (?)
 * App-level, consumed by contexts - move with contexts refactor
 */
import { type FC, type ReactNode, useMemo } from 'react';
import { Outlet } from 'react-router-dom';

import Stack, { type StackProps } from '@material-hu/mui/Stack';
import { styled } from '@material-hu/mui/styles';

import { FEATURE_FLAG_KEYS } from 'src/config/firebase';
import { useFeatureFlag } from 'src/contexts/FeatureFlagsContext';
import useAuth from 'src/contexts/JWTContext';
import {
  LayoutMetricsProvider,
  useLayoutMetrics,
} from 'src/contexts/LayoutMetricsContext';
import {
  SidebarProvider,
  useSidebarContext,
} from 'src/contexts/SidebarContext';
import { SocketProvider } from 'src/contexts/SocketContext';
import { useDashboardLayoutPadding } from 'src/utils/sidebar';

import ErrorBoundary from '../ErrorBoundary';
import ZendeskContainer from '../ZendeskContainer/ZendeskContainer';

import DashboardNavbar from './DashboardNavbar';
import DashboardSidebar from './DashboardSidebar';

type DashboardLayoutProps = {
  children?: ReactNode;
};

type DashboardLayoutWrapperProps = {
  dashboardLayoutPaddingLeft: number;
};

const DashboardLayoutRoot = styled('main')(({ theme }) => ({
  backgroundColor: theme.palette.background.default,
  display: 'flex',
  height: '100%',
  width: '100%',
}));

const DashboardLayoutWrapper = ({
  dashboardLayoutPaddingLeft,
  ...props
}: DashboardLayoutWrapperProps & Pick<StackProps, 'id' | 'children'>) => {
  const { navbarHeight, fluid } = useLayoutMetrics();
  return (
    <Stack
      sx={{
        flex: '1 1 auto',
        overflow: fluid ? '' : 'hidden',
        paddingLeft: fluid ? undefined : `${dashboardLayoutPaddingLeft}px`,
        marginLeft: fluid ? `${dashboardLayoutPaddingLeft}px` : undefined,
        paddingTop: `${navbarHeight}px`,
        maxWidth: fluid
          ? `calc(100% - ${dashboardLayoutPaddingLeft}px)`
          : undefined,
      }}
      {...props}
    />
  );
};

const DashboardLayoutContainer = styled('div')({
  display: 'flex',
  flex: '1 1 auto',
  overflow: 'inherit',
});

const DashboardLayoutContent = styled('div')({
  flex: '1 1 auto',
  height: '100%',
  overflow: 'auto',
  position: 'inherit',
  WebkitOverflowScrolling: 'touch',
});

const DashboardLayoutInner = () => {
  const { instance } = useAuth();
  const { isSidebarCollapsed, toggleSidebar } = useSidebarContext();

  const {
    value: { instances: allowedInstances },
  } = useFeatureFlag(FEATURE_FLAG_KEYS.ALLOWED_INSTANCES_TO_SUPPORT_CENTER);

  const showSupportButton = useMemo(() => {
    if (!instance) return false;
    return allowedInstances.includes(instance.id);
  }, [instance]);

  const dashboardLayoutPaddingLeft =
    useDashboardLayoutPadding(isSidebarCollapsed);

  return (
    <DashboardLayoutRoot>
      <DashboardNavbar onSidebarInteraction={toggleSidebar} />
      <DashboardSidebar />
      <DashboardLayoutWrapper
        id="dashboard-layout-wrapper"
        dashboardLayoutPaddingLeft={dashboardLayoutPaddingLeft}
      >
        <DashboardLayoutContainer>
          <DashboardLayoutContent id="dashboard-layout-content">
            <ErrorBoundary resetOnLocationChange>
              <Outlet />
            </ErrorBoundary>
            {showSupportButton && <ZendeskContainer />}
          </DashboardLayoutContent>
        </DashboardLayoutContainer>
      </DashboardLayoutWrapper>
    </DashboardLayoutRoot>
  );
};

const DashboardLayout: FC<DashboardLayoutProps> = () => (
  <SocketProvider>
    <LayoutMetricsProvider>
      <SidebarProvider>
        <DashboardLayoutInner />
      </SidebarProvider>
    </LayoutMetricsProvider>
  </SocketProvider>
);

export default DashboardLayout;
