import {
  createContext,
  type Dispatch,
  type SetStateAction,
  useCallback,
  useContext,
  useEffect,
  useState,
} from 'react';
import { useLocation } from 'react-router-dom';

import { useTheme } from '@material-hu/mui/styles';
import useMediaQuery from '@material-hu/mui/useMediaQuery';

import { disableNavbarPath } from 'src/utils/navbar';
import {
  collapsedSidebarPath,
  disableSidebarPath,
  getSidebarStatus,
  hiddenSidebarPath,
  setSidebarStatus,
} from 'src/utils/sidebar';

type LayoutContextType = {
  taskFocus: boolean;
  setTaskFocus: Dispatch<SetStateAction<boolean>>;
  isSidebarHidden: boolean;
  isNavbarDisabled: boolean;
  isSidebarDisabled: boolean;
  isSidebarCollapsed: boolean;
  collapseSidebar: () => void;
  toggleSidebar: () => void;
};

export const LayoutContext = createContext<LayoutContextType | null>(null);

type LayoutProviderProps = {
  children: React.ReactNode;
};

export const LayoutProvider = ({ children }: LayoutProviderProps) => {
  const location = useLocation();
  const [taskFocus, setTaskFocus] = useState(false);
  const theme = useTheme();
  const isDownMd = useMediaQuery(theme.breakpoints.down('md'));
  const [sidebarCollapsedPreference, setSidebarCollapsedPreference] =
    useState<boolean>(isDownMd || getSidebarStatus());
  const [autoCollapseOverride, setAutoCollapseOverride] = useState(false);

  const isSidebarHidden = hiddenSidebarPath(location.pathname);
  const isNavbarDisabled = taskFocus || disableNavbarPath(location.pathname);
  const isSidebarDisabled = taskFocus || disableSidebarPath(location.pathname);
  const isAutoCollapsed = collapsedSidebarPath(location.pathname);
  const isSidebarCollapsed = isAutoCollapsed
    ? !autoCollapseOverride
    : sidebarCollapsedPreference;

  useEffect(() => {
    setAutoCollapseOverride(false);
  }, [isAutoCollapsed]);

  useEffect(() => {
    setTaskFocus(false);
  }, [location.pathname]);

  const collapseSidebar = useCallback(() => {
    if (isAutoCollapsed) {
      setAutoCollapseOverride(false);
    } else {
      setSidebarCollapsedPreference(true);
      setSidebarStatus(true);
    }
  }, [isAutoCollapsed]);

  const toggleSidebar = useCallback(() => {
    if (isAutoCollapsed) {
      setAutoCollapseOverride(prev => !prev);
    } else {
      setSidebarCollapsedPreference(prev => {
        setSidebarStatus(!prev);
        return !prev;
      });
    }
  }, [isAutoCollapsed]);

  return (
    <LayoutContext.Provider
      value={{
        taskFocus,
        setTaskFocus,
        isSidebarHidden,
        isNavbarDisabled,
        isSidebarDisabled,
        isSidebarCollapsed,
        collapseSidebar,
        toggleSidebar,
      }}
    >
      {children}
    </LayoutContext.Provider>
  );
};

export const useLayoutContext = () => {
  const context = useContext(LayoutContext);

  if (!context) {
    throw new Error('useLayoutContext must be used within a LayoutProvider');
  }

  return context;
};
