// [REQ D1]  React Suspense i Error Boundaries – Suspense + ErrorBoundary opakowują całą aplikację
// [REQ D5]  React.lazy i dynamic imports – DashboardPage i AdminPage ładowane on-demand
// [REQ T3]  React Router – BrowserRouter, Routes, Route, Navigate, ProtectedRoute
// lazy - funkcja reacta do dzielenia kodu i ładowania ich w danym momencie - żeby nie ładować wszystkiego na raz
// Suspense - komponent reacta do wyświetlania ekranu ładowania podczas ładowania komponentu lazy
import { lazy, Suspense } from 'react';
// BrowserRouter jest potrzebny do routingu w aplikacji React - sychronizacja url z widokiem
// Routers jest potrzebny do definiowania ścieżek w aplikacji React - grupowanie ścieżek w aplikacji
// Route jest potrzebny do definiowania pojedynczej ścieżki w aplikacji React - definiowanie widoku dla danej ścieżki
// Navigate jest potrzebny do przekierowywania w aplikacji React - zmiana widoku na inną ścieżkę
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
// AuthProvider jest potrzebny do przechowywania stanu zalogowanego użytkownika
//useAuth jest potrzebny do pobierania stanu zalogowanego użytkownika
import { AuthProvider, useAuth } from './context/AuthContext';
// ThemeProvider jest potrzbny do przechowywania stanu motywu aplikacji
import { ThemeProvider } from './context/ThemeContext';
// ProtectedRoute jest potrzebny do ochrony ścieżek w aplikacji React - sprawdzanie czy użytkownik ma dostęp do danej ścieżki
import ProtectedRoute from './components/ProtectedRoute';
// ErrorBoundary jest potrzebny do obsługi błędów - wyświetlanie komunikatu o błędzie zamiast crashowania aplikacji
import ErrorBoundary from './components/ErrorBoundary';
// LoadingSpinner jest potrzebny do wyświetlania animacji ładowania podczas ładowania komponentu lazy
import LoadingSpinner from './components/LoadingSpinner';
// LoginPage to komponent strony logowania
// RegisterPage to komponent strony rejestracji
// ReservationsPage to komponent strony rezerwacji
import LoginPage from './pages/LoginPage';
import RegisterPage from './pages/RegisterPage';
import ReservationsPage from './pages/ReservationsPage';
// Importowanie stylów głównych aplikacji z scss - po zbudowaniu css zostanie wstrzyknięty do html
import './styles/main.scss';

// Lazy loading komponentów stron, aby nie ładować ich od razu przy starcie aplikacji
// Ładowane w momencie wejścia na daną ścieżkę 
// Dostępne tylko dla admina lub klienta w zależności od roli użytkownika
const DashboardPage = lazy(() => import('./pages/DashboardPage'));
const AdminPage     = lazy(() => import('./pages/AdminPage'));

// Komponent RootRedirect sprawdza czy użytkownik jest zalogowany i przekierowuje go na odpowiednią stronę
// useAuth custom hook do pobierania stanu zalogowanego użytkownika z AuthContext
const RootRedirect = () => {
  // desrukturyzacja user z useAuth - pobieramy zalogowanego użytkownika z kontekstu
  const { user } = useAuth();
  if (!user) return <Navigate to="/login" replace />;
  // Jeśli użytkownik jest zalogowany, sprawdzamy jego rolę i przekierowujemy go na odpowiednią stronę
  // replace podmienia URL w historii przeglądarki żeby cofnij nie nie wracało do strony root
  return <Navigate to={user.role === 'admin' ? '/admin' : '/dashboard'} replace />;
};

// Główny komponent aplikacji React, który zawiera wszystkie ścieżki i contexty
const App = () => (
  // BrowserRouter jest potrzebny do routingu w aplikacji React - sychronizacja url z widokiem
  <BrowserRouter>
  {/* // ThemeProvider jest potrzebny do przechowywania stanu motywu aplikacji */}
    <ThemeProvider>
      {/* // AuthProvider jest potrzebny do przechowywania stanu zalogowanego użytkownika */}
      <AuthProvider>
        {/* // ErrorBoundary jest potrzebny do obsługi błędów - wyświetlanie komunikatu o błędzie zamiast crashowania aplikacji */}
        <ErrorBoundary>
          {/* // Suspense jest potrzebny do wyświetlania ekranu ładowania podczas ładowania komponentu lazy */}
          {/* // Inline określamy jaki ma być ekran ładowania w tym przypadku jest to spinner i napis "Loading page…" */}
          <Suspense fallback={<LoadingSpinner message="Loading page…" />}>
            {/* // Routes jest potrzebny do definiowania ścieżek w aplikacji React - grupowanie ścieżek w aplikacji */}
            <Routes>
              {/* //Route pojedyncze ścieżki w aplikacji React - definiowanie widoku dla danej ścieżki */}
              {/* // Powiązuje URL z komponentem React, który ma być renderowany w momencie wejścia na daną ścieżkę */}
              <Route path="/login" element={<LoginPage />} />
              <Route path="/register" element={<RegisterPage />} />
              {/* // Ścieżki chronione przez ProtectedRoute 
              // określamy jedną scieżke i pakujemy w nie wszsytkie które mają byc chronione
              // */}
              <Route element={<ProtectedRoute allowedRoles={['client']} />}>
                <Route path="/dashboard" element={<DashboardPage />} />
                <Route path="/reservations" element={<ReservationsPage />} />
              </Route>

              <Route element={<ProtectedRoute allowedRoles={['admin']} />}>
                <Route path="/admin" element={<AdminPage />} />
              </Route>

              <Route path="/" element={<RootRedirect />} />
              <Route path="*" element={<Navigate to="/" replace />} />
            </Routes>
          </Suspense>
        </ErrorBoundary>
      </AuthProvider>
    </ThemeProvider>
  </BrowserRouter>
);

// export aby móc importować komponent App w innych plikach
export default App;
