import { useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { MODULES } from '@/shared/constants/appData';
import {
  DEFAULT_CAMPUS_LABEL,
  findCampusByNameOrCode,
} from '@/shared/constants/campusDisplay';
import {
  getModuleIdByRoutePath,
  getModuleRoutePath,
} from '@/shared/constants/moduleRoutes';
import { DEFAULT_PRODUCT_ROLE } from '@/shared/constants/roles';
import type { ModuleId, UserRole } from '@/shared/types/app';
import {
  getAccessibleModuleId,
  getAccessibleModules,
  getSidebarCampusInitial,
  getSidebarRoleLabel,
  shouldShowMobileSidebarOverlay,
} from '@/business/app-shell/selectors';
import { useCampusCatalog } from '@/business/campuses/hooks';
import type {
  AppShellState,
  SidebarPage,
  SidebarProps,
  UseAppShellOptions,
} from '@/business/app-shell/types';

function getUserRole(options: UseAppShellOptions): UserRole {
  return options.profile?.role ?? DEFAULT_PRODUCT_ROLE;
}

function getUserName(options: UseAppShellOptions): string {
  return options.profile?.full_name ?? '';
}

function getUserCampus(options: UseAppShellOptions): string {
  return options.profile?.campus ?? DEFAULT_CAMPUS_LABEL;
}

export function useAppShell(options: UseAppShellOptions): AppShellState {
  const location = useLocation();
  const navigate = useNavigate();
  const campusCatalog = useCampusCatalog();
  const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
  const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false);
  const [zoneCheckIn, setZoneCheckIn] = useState<string | null>(null);

  const userRole = getUserRole(options);
  const userName = getUserName(options);
  const userCampus = getUserCampus(options);
  const currentRouteModule = getModuleIdByRoutePath(location.pathname);
  const currentModule = getAccessibleModuleId(MODULES, currentRouteModule, userRole);
  const activeModule = getAccessibleModuleId(MODULES, currentModule, userRole);
  const campusInfo = findCampusByNameOrCode(campusCatalog.campuses, userCampus);
  const mobileOverlayVisible = shouldShowMobileSidebarOverlay(options.isMobile, mobileSidebarOpen);

  const setCurrentModule = (id: ModuleId) => {
    navigate(getModuleRoutePath(id));

    if (options.isMobile) {
      setMobileSidebarOpen(false);
    }
  };

  const toggleSidebar = () => {
    if (options.isMobile) {
      setMobileSidebarOpen((current) => !current);
      return;
    }

    setSidebarCollapsed((current) => !current);
  };

  const sidebarProps: SidebarProps = {
    currentModule: activeModule,
    setCurrentModule,
    userRole,
    collapsed: options.isMobile ? false : sidebarCollapsed,
    setCollapsed: setSidebarCollapsed,
    campusInfo,
  };

  const topBarProps = {
    userRole,
    userName,
    campusInfo,
    toggleSidebar,
  };

  const shellOutletContext = {
    userRole,
    userName,
    userCampus,
    zoneCheckIn,
    setZoneCheckIn,
    setCurrentModule,
  };

  const footerProps = {
    userName,
    userRole,
    setCurrentModule,
  };

  return {
    activeModule,
    currentModule: activeModule,
    userRole,
    userName,
    userCampus,
    campusInfo,
    sidebarCollapsed,
    mobileSidebarOpen,
    mobileOverlayVisible,
    zoneCheckIn,
    sidebarProps,
    topBarProps,
    shellOutletContext,
    footerProps,
    setSidebarCollapsed,
    setMobileSidebarOpen,
    setZoneCheckIn,
    setCurrentModule,
  };
}

export function useSidebarPage({
  currentModule,
  setCurrentModule,
  userRole,
  collapsed,
  setCollapsed,
  campusInfo,
}: SidebarProps): SidebarPage {
  return {
    currentModule,
    userRole,
    collapsed,
    campusInfo,
    modules: getAccessibleModules(MODULES, userRole),
    roleLabel: getSidebarRoleLabel(userRole),
    campusInitial: getSidebarCampusInitial(campusInfo),
    setCurrentModule,
    toggleCollapsed: () => setCollapsed(!collapsed),
  };
}
