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

import { collapsedSidebarPath, setSidebarStatus } from 'src/utils/sidebar';

type SidebarContextType = {
  isSidebarCollapsed: boolean;
  collapseSidebar: (persist?: boolean) => void;
  expandSidebar: () => void;
  toggleSidebar: () => void;
};

const SidebarContext = createContext<SidebarContextType | null>(null);

type SidebarProviderProps = PropsWithChildren;

const getPersistedSidebarStatus = (): boolean =>
  JSON.parse(localStorage.getItem('sidebarStatus') || 'false');

export const SidebarProvider = ({ children }: SidebarProviderProps) => {
  const location = useLocation();

  const [sidebarCollapsedPreference, setSidebarCollapsedPreference] =
    useState<boolean>(getPersistedSidebarStatus);
  const [autoCollapseOverride, setAutoCollapseOverride] = useState(false);

  const isAutoCollapsed = collapsedSidebarPath(location.pathname);
  const isSidebarCollapsed = isAutoCollapsed
    ? !autoCollapseOverride
    : sidebarCollapsedPreference;

  // biome-ignore lint/correctness/useExhaustiveDependencies: isAutoCollapsed is an intentional trigger to reset the override when entering/leaving auto-collapsed routes
  useEffect(() => {
    setAutoCollapseOverride(false);
  }, [isAutoCollapsed]);

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

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

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

  const value = useMemo(
    () => ({
      isSidebarCollapsed,
      collapseSidebar,
      expandSidebar,
      toggleSidebar,
    }),
    [isSidebarCollapsed, collapseSidebar, expandSidebar, toggleSidebar],
  );

  return (
    <SidebarContext.Provider value={value}>{children}</SidebarContext.Provider>
  );
};

export const useSidebarContext = () => {
  const context = useContext(SidebarContext);

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

  return context;
};
