import { StrictMode, useLayoutEffect } from 'react'
import { createRoot } from 'react-dom/client'
import {
  Outlet,
  Route,
  RouterProvider,
  createBrowserRouter,
  createRoutesFromElements,
  Navigate,
  useLocation,
  useNavigationType,
  useParams,
  type NavigateOptions,
  type To,
} from 'react-router-dom'
import { CurrentUserProvider, RequireAuth } from './lib/current-user.tsx'
import { LoginModalProvider } from './lib/login-modal.tsx'
import { PageTransition } from './components/PageTransition.tsx'
import { ScrollToTop } from './components/ScrollToTop.tsx'
import { SiteFooter } from './components/SiteFooter.tsx'
import { SiteHeader } from './components/SiteHeader.tsx'
import { LoginModal } from './components/LoginModal.tsx'
import AboutPage from './pages/AboutPage.tsx'
import CollectionPage from './pages/CollectionPage.tsx'
import CollectionsPage from './pages/CollectionsPage.tsx'
import FeedbackNewPage from './pages/FeedbackNewPage.tsx'
import HelpPage from './pages/HelpPage.tsx'
import PrivacyPage from './pages/PrivacyPage.tsx'
import TermsPage from './pages/TermsPage.tsx'
import DiscoveriesPage from './pages/DiscoveriesPage.tsx'
import DiscoverNewPage from './pages/DiscoverNewPage.tsx'
import HomePage from './pages/HomePage.tsx'
import PlacesCatalogPage from './pages/PlacesCatalogPage.tsx'
import LoginPage from './pages/LoginPage.tsx'
import NotificationsPage from './pages/NotificationsPage.tsx'
import PlaceAlbumPage from './pages/PlaceAlbumPage.tsx'
import PlacePage from './pages/PlacePage.tsx'
import PlaceReviewsPage from './pages/PlaceReviewsPage.tsx'
import PlaceCheckInsPage from './pages/PlaceCheckInsPage.tsx'
import PlaceNearbyPage from './pages/PlaceNearbyPage.tsx'
import PlaceWishersPage from './pages/PlaceWishersPage.tsx'
import ProfileEditPage from './pages/ProfileEditPage.tsx'
import AdminCollectionFormPage from './pages/AdminCollectionFormPage.tsx'
import AdminCollectionsPage from './pages/AdminCollectionsPage.tsx'
import AdminPlaceFormPage from './pages/AdminPlaceFormPage.tsx'
import AdminPlacesPage from './pages/AdminPlacesPage.tsx'
import AdminFeedbacksPage from './pages/AdminFeedbacksPage.tsx'
import AdminPoisPage from './pages/AdminPoisPage.tsx'
import AdminPoiFormPage from './pages/AdminPoiFormPage.tsx'
import OpsLoginPage from './pages/OpsLoginPage.tsx'
import { RequireOps } from './components/RequireOps.tsx'
import {
  MeDiscoveriesPage,
  MeListingsPage,
  MePage,
  MeReviewsPage,
  MeWishesPage,
  UserDiscoveriesPage,
  UserListingsPage,
  UserPage,
  UserReviewsPage,
  UserWishesPage,
} from './pages/ProfilePage.tsx'
import ReviewNewPage from './pages/ReviewNewPage.tsx'
import ListingNewPage from './pages/ListingNewPage.tsx'
import PlaceListingsPage from './pages/PlaceListingsPage.tsx'
import PlaceQuestionsPage from './pages/PlaceQuestionsPage.tsx'
import PoiPage from './pages/PoiPage.tsx'
import QuestionNewPage from './pages/QuestionNewPage.tsx'
import RentalNewPage from './pages/RentalNewPage.tsx'
import RentalsPage from './pages/RentalsPage.tsx'
import ReviewPage from './pages/ReviewPage.tsx'
import NotFoundPage from './pages/NotFoundPage.tsx'
import './index.css'

function AppShell() {
  const action = useNavigationType()
  const { pathname } = useLocation()
  const wideStage = pathname === '/places'

  useLayoutEffect(() => {
    document.documentElement.dataset.nav = action === 'POP' ? 'back' : 'forward'
  }, [action, pathname])

  return (
    <CurrentUserProvider>
      <LoginModalProvider>
        <ScrollToTop />
        <div className="flex min-h-screen flex-col bg-stage text-label">
          <SiteHeader />
          <div
            className={`mx-auto flex w-full flex-1 flex-col bg-canvas ${
              wideStage ? 'max-w-[68rem]' : 'max-w-2xl overflow-x-clip'
            }`}
          >
            <div className="flex-1">
              <PageTransition>
                <Outlet />
              </PageTransition>
            </div>
            {wideStage ? null : <SiteFooter />}
          </div>
        </div>
        <LoginModal />
      </LoginModalProvider>
    </CurrentUserProvider>
  )
}

function RedirectPlaceCheckIn() {
  const { placeId } = useParams()
  if (!placeId) return <Navigate to="/" replace />
  return <Navigate to={`/places/${placeId}/check-ins`} replace />
}

function RedirectQuestionDetail() {
  const { placeId, questionId } = useParams()
  if (!placeId) return <Navigate to="/" replace />
  const qs = questionId ? `?question=${questionId}` : ''
  return <Navigate to={`/places/${placeId}/questions${qs}`} replace />
}

const router = createBrowserRouter(
  createRoutesFromElements(
    <Route element={<AppShell />}>
      <Route path="/" element={<HomePage />} />
      <Route path="/discoveries" element={<DiscoveriesPage />} />
      <Route path="/discoveries/new" element={<RequireAuth><DiscoverNewPage /></RequireAuth>} />
      <Route path="/collections" element={<CollectionsPage />} />
      <Route path="/collections/:collectionId" element={<CollectionPage />} />
      <Route path="/reviews/new" element={<RequireAuth><ReviewNewPage /></RequireAuth>} />
      <Route path="/reviews/:reviewId" element={<ReviewPage />} />
      <Route path="/listings/new" element={<RequireAuth><ListingNewPage /></RequireAuth>} />
      <Route path="/rentals" element={<RentalsPage />} />
      <Route path="/rentals/new" element={<RequireAuth><RentalNewPage /></RequireAuth>} />
      <Route path="/pois/:poiId" element={<PoiPage />} />
      <Route path="/questions/new" element={<RequireAuth><QuestionNewPage /></RequireAuth>} />
      <Route path="/places" element={<PlacesCatalogPage />} />
      <Route path="/places/:placeId/photos" element={<PlaceAlbumPage />} />
      <Route path="/places/:placeId/wishes" element={<PlaceWishersPage />} />
      <Route path="/places/:placeId/check-in" element={<RedirectPlaceCheckIn />} />
      <Route path="/places/:placeId/check-ins" element={<PlaceCheckInsPage />} />
      <Route path="/places/:placeId/nearby" element={<PlaceNearbyPage />} />
      <Route path="/places/:placeId/listings" element={<PlaceListingsPage />} />
      <Route path="/places/:placeId/questions" element={<PlaceQuestionsPage />} />
      <Route path="/places/:placeId/reviews" element={<PlaceReviewsPage />} />
      <Route
        path="/places/:placeId/questions/:questionId"
        element={<RedirectQuestionDetail />}
      />
      <Route path="/places/:placeId" element={<PlacePage />} />
      <Route path="/notifications" element={<RequireAuth><NotificationsPage /></RequireAuth>} />
      <Route path="/about" element={<AboutPage />} />
      <Route path="/help" element={<HelpPage />} />
      <Route path="/feedback" element={<FeedbackNewPage />} />
      <Route path="/privacy" element={<PrivacyPage />} />
      <Route path="/terms" element={<TermsPage />} />
      <Route path="/ranking" element={<Navigate to="/about" replace />} />
      <Route path="/contact" element={<Navigate to="/help#contact" replace />} />
      <Route path="/login" element={<LoginPage />} />
      <Route path="/me" element={<RequireAuth><MePage /></RequireAuth>} />
      <Route path="/me/wishes" element={<RequireAuth><MeWishesPage /></RequireAuth>} />
      <Route path="/me/reviews" element={<RequireAuth><MeReviewsPage /></RequireAuth>} />
      <Route path="/me/discoveries" element={<RequireAuth><MeDiscoveriesPage /></RequireAuth>} />
      <Route path="/me/listings" element={<RequireAuth><MeListingsPage /></RequireAuth>} />
      <Route path="/me/edit" element={<RequireAuth><ProfileEditPage /></RequireAuth>} />
      <Route path="/ops" element={<OpsLoginPage />} />
      <Route path="/ops/collections/new" element={<RequireOps><AdminCollectionFormPage /></RequireOps>} />
      <Route path="/ops/collections/:collectionId/edit" element={<RequireOps><AdminCollectionFormPage /></RequireOps>} />
      <Route path="/ops/collections" element={<RequireOps><AdminCollectionsPage /></RequireOps>} />
      <Route path="/ops/places/new" element={<RequireOps><AdminPlaceFormPage /></RequireOps>} />
      <Route path="/ops/places/:placeId/edit" element={<RequireOps><AdminPlaceFormPage /></RequireOps>} />
      <Route path="/ops/places" element={<RequireOps><AdminPlacesPage /></RequireOps>} />
      <Route path="/ops/pois" element={<RequireOps><AdminPoisPage /></RequireOps>} />
      <Route path="/ops/pois/:poiId/edit" element={<RequireOps><AdminPoiFormPage /></RequireOps>} />
      <Route path="/ops/feedbacks" element={<RequireOps><AdminFeedbacksPage /></RequireOps>} />
      <Route path="/users/:userId/wishes" element={<UserWishesPage />} />
      <Route path="/users/:userId/reviews" element={<UserReviewsPage />} />
      <Route path="/users/:userId/discoveries" element={<UserDiscoveriesPage />} />
      <Route path="/users/:userId/listings" element={<UserListingsPage />} />
      <Route path="/users/:userId" element={<UserPage />} />
      <Route path="*" element={<NotFoundPage />} />
    </Route>,
  ),
)

const navigate = router.navigate.bind(router)
router.navigate = ((to: To | number, opts?: NavigateOptions) => {
  if (typeof to === 'number') return navigate(to)
  return navigate(to, { ...opts, viewTransition: opts?.viewTransition ?? true })
}) as typeof router.navigate

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <RouterProvider router={router} />
  </StrictMode>,
)
