import { useMemo, 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 type { ModuleId, UserRole } from '@/shared/types/app';
import {
  DEFAULT_GUEST_PREVIEW_ROLE,
  GUEST_PREVIEW_USER_NAME,
  GUEST_PREVIEW_ROLE_OPTIONS,
} from '@/shared/constants/guestPreviewRoles';
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, guestPreviewRole: UserRole): UserRole {
  return options.isAuthenticated && options.profile?.role ? options.profile.role : guestPreviewRole;
}

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

function getUserCampus(options: UseAppShellOptions): string {
  return options.isAuthenticated && options.profile?.campus ? 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 [showSignInModal, setShowSignInModal] = useState(false);
  const [guestPreviewRole, setGuestPreviewRole] = useState<UserRole>(DEFAULT_GUEST_PREVIEW_ROLE);
  const [showGuestRolePicker, setShowGuestRolePicker] = useState(false);

  const userRole = getUserRole(options, guestPreviewRole);
  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 currentGuestPreviewRole = useMemo(
    () => GUEST_PREVIEW_ROLE_OPTIONS.find((role) => role.value === guestPreviewRole) || GUEST_PREVIEW_ROLE_OPTIONS[0],
    [guestPreviewRole],
  );

  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 guestBannerProps = {
    guestPreviewRole,
    guestPreviewRoles: GUEST_PREVIEW_ROLE_OPTIONS,
    currentGuestPreviewRole,
    showGuestRolePicker,
    setGuestPreviewRole,
    setShowGuestRolePicker,
    onSignInClick: () => setShowSignInModal(true),
  };

  const footerProps = {
    isAuthenticated: options.isAuthenticated,
    userName,
    userRole,
    currentGuestPreviewRole,
    setCurrentModule,
  };

  const signInModalProps = {
    isOpen: showSignInModal,
    onClose: () => setShowSignInModal(false),
  };

  return {
    activeModule,
    currentModule: activeModule,
    userRole,
    userName,
    userCampus,
    campusInfo,
    sidebarCollapsed,
    mobileSidebarOpen,
    mobileOverlayVisible,
    zoneCheckIn,
    showSignInModal,
    guestPreviewRole,
    showGuestRolePicker,
    guestPreviewRoles: GUEST_PREVIEW_ROLE_OPTIONS,
    currentGuestPreviewRole,
    sidebarProps,
    topBarProps,
    shellOutletContext,
    guestBannerProps,
    footerProps,
    signInModalProps,
    setSidebarCollapsed,
    setMobileSidebarOpen,
    setZoneCheckIn,
    setShowSignInModal,
    setGuestPreviewRole,
    setShowGuestRolePicker,
    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),
  };
}
