import Sidebar from './components/shared/Sidebar';
import Header from './components/shared/Header';
import 'bootstrap/dist/css/bootstrap.min.css';
import { useEffect, useRef, useState } from 'react';
import AppRoutes from './AppRoutes';
import { routes } from './AppRoutes';
import { useLocation } from 'react-router-dom';
import { MsalProvider } from '@azure/msal-react';
import { PublicClientApplication } from '@azure/msal-browser';
import { matchRoute } from './auth/ProtectedRoute';
import { ToastProvider } from './components/Toast/ToastContext';
import Toasts from './components/Toast/Toasts';

interface AppProps {
  instance: PublicClientApplication; // Type the msal instance prop
}

// Main page layout component
const App: React.FC<AppProps> = ({ instance }) => {
  // Retrieve current auth information
  const account = instance.getActiveAccount();
  useEffect(() => {
    if (!account) {
      setIsSidebarOpen(false);
    }
  }, [account]);

  // Keep track of sidebar open state
  const [isSidebarOpen, setIsSidebarOpen] = useState(false);
  // Function that can be passed to other components to update sidebar open state
  const toggleSidebar = () => {
    setIsSidebarOpen(!isSidebarOpen);
  };

  const location = useLocation();
  const mainRef = useRef<HTMLDivElement>(null);
  // Automatically scroll to top of page on location change
  useEffect(() => {
    const body = document.querySelectorAll('#root')[0];
    if (body) {
      body.scrollIntoView({ behavior: 'instant' });
    }
  }, [location.pathname]);

  // Keep track of hide layout state
  const [hideLayout, setHideLayout] = useState(true);
  useEffect(() => {
    // Find the route that matches the current pathname
    // Handles cases like roster page where :sectionId (or etc.) is replaced with an actual value
    const route = routes.find((route) =>
      matchRoute(route.path, location.pathname)
    );

    // Update hide layout state
    if (route?.layoutHidden) {
      setHideLayout(true);
    } else {
      setHideLayout(false);
    }

    // Set page title
    document.title = 'ShipME' + (route ? ' | ' + route.name : '');
  }, [location.pathname]); // Dependency on path change

  const header = useRef<HTMLDivElement>(null);
  const [pageHeight, setPageHeight] = useState('100vh');
  // Function to update the page height based on the header element's height
  const updatePageHeight = () => {
    if (header.current) {
      const height = header.current.getBoundingClientRect().height;
      setPageHeight(`calc(100vh - ${height}px - 4rem)`);
    }
  };
  // Use effect to update the height when the component mounts or window resizes
  useEffect(() => {
    updatePageHeight();
    window.addEventListener('resize', updatePageHeight);

    // Cleanup event listener on unmount
    return () => {
      window.removeEventListener('resize', updatePageHeight);
    };
  }, []);

  const sidebar = useRef<HTMLDivElement>(null);
  const navbarCollapseButton = useRef<HTMLElement>(null);

  return (
    <ToastProvider>
      <Toasts />
      <MsalProvider instance={instance}>
        <div ref={header}>
          <Header
            toggleSidebar={toggleSidebar}
            fullHeader={!hideLayout}
            navbarButtonRef={navbarCollapseButton}
          />
        </div>
        {!hideLayout && (
          <div
            ref={sidebar}
            className='position-fixed shadow-lg'
            style={{ zIndex: 1000 }}
          >
            <Sidebar
              isSidebarOpen={isSidebarOpen}
              toggleSidebar={toggleSidebar}
              height={pageHeight}
            />
          </div>
        )}
        {
          // Transparent overlay div that acts to prevent clicks in <main> when sidebar is open
          isSidebarOpen && (
            <div
              onClick={(event) => {
                event.stopPropagation();
                event.preventDefault();
                setIsSidebarOpen(false);
              }}
              className='position-fixed'
              style={{
                top: 0,
                left: 0,
                width: '100vw',
                height: '100vh',
                background: 'transparent',
                zIndex: 999,
              }}
            />
          )
        }
        <main
          ref={mainRef}
          className='container-fluid d-flex flex-column p-3'
          style={{
            minHeight: pageHeight,
            marginTop: '4rem',
            filter: isSidebarOpen ? 'blur(1px)' : '',
            opacity: isSidebarOpen ? 0.5 : 1,
            transition: 'filter 0.25s ease-in-out, opacity 0.25s ease-in-out',
          }}
        >
          <AppRoutes />
        </main>
      </MsalProvider>
    </ToastProvider>
  );
};

export default App;
