import { BrowserRouter, Routes, Route } from 'react-router-dom'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { AppShell } from './components/layout/AppShell'
import { AuthProvider } from './contexts/AuthContext'
import { RepoListSkeleton } from './ui/Skeleton'
import { Suspense, lazy, useEffect } from 'react'
import { bootstrapCSRF } from './api/client'
import './index.css'

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 30_000,
      retry: false,
      placeholderData: (prev: unknown) => prev,
    },
  },
})

const LoginPage         = lazy(() => import('./pages/LoginPage'))
const RegisterPage      = lazy(() => import('./pages/RegisterPage'))
const DashboardPage     = lazy(() => import('./pages/DashboardPage'))
const ReposPage         = lazy(() => import('./pages/ReposPage'))
const CreateRepoPage    = lazy(() => import('./pages/CreateRepoPage'))
const ImportRepoPage    = lazy(() => import('./pages/ImportRepoPage'))
const RepoPage          = lazy(() => import('./pages/RepoPage'))
const BlobPage          = lazy(() => import('./pages/BlobPage'))
const RepoSettingsPage  = lazy(() => import('./pages/RepoSettingsPage'))
const RepoIssuesPage    = lazy(() => import('./pages/RepoIssuesPage'))
const RepoPRsPage       = lazy(() => import('./pages/RepoPRsPage'))
const CreatePRPage      = lazy(() => import('./pages/CreatePRPage'))
const PRDetailPage      = lazy(() => import('./pages/PRDetailPage'))
const CommitsPage       = lazy(() => import('./pages/CommitsPage'))
const BranchesPage      = lazy(() => import('./pages/BranchesPage'))
const StarredPage       = lazy(() => import('./pages/StarredPage'))
const PRsPage           = lazy(() => import('./pages/PRsPage'))
const PipelinesPage     = lazy(() => import('./pages/PipelinesPage'))
const PipelineRunPage      = lazy(() => import('./pages/PipelineRunPage'))
const RepoPipelinesPage    = lazy(() => import('./pages/RepoPipelinesPage'))
const EnvironmentsPage        = lazy(() => import('./pages/EnvironmentsPage'))
const RepoTimelinePage        = lazy(() => import('./pages/RepoTimelinePage'))
const RepoSecretsPage         = lazy(() => import('./pages/RepoSecretsPage'))
const RepoSecurityPage        = lazy(() => import('./pages/RepoSecurityPage'))
const WorkspacesPage          = lazy(() => import('./pages/WorkspacesPage'))
const WorkspacePage           = lazy(() => import('./pages/WorkspacePage'))
const WorkspaceSettingsPage   = lazy(() => import('./pages/WorkspaceSettingsPage'))
const ProfilePage       = lazy(() => import('./pages/ProfilePage'))
const ExplorePage       = lazy(() => import('./pages/ExplorePage'))
const SettingsPage      = lazy(() => import('./pages/SettingsPage'))

function S({ children }: { children: React.ReactNode }) {
  return <Suspense fallback={<div className="p-6"><RepoListSkeleton /></div>}>{children}</Suspense>
}

function CSRFBootstrap() {
  useEffect(() => { bootstrapCSRF() }, [])
  return null
}

function NotFound() {
  return (
    <div className="flex flex-col items-center justify-center h-full gap-3 text-center py-24">
      <p className="text-4xl font-bold text-[var(--c-border)]">404</p>
      <p className="text-sm text-[var(--c-muted)]">Page not found.</p>
    </div>
  )
}

export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <BrowserRouter>
        <CSRFBootstrap />
        <AuthProvider>
          <Routes>
            <Route path="/login"    element={<S><LoginPage /></S>} />
            <Route path="/register" element={<S><RegisterPage /></S>} />

            <Route path="/" element={<AppShell />}>
              <Route index element={<S><DashboardPage /></S>} />

              <Route path="repos"                                    element={<S><ReposPage /></S>} />
              <Route path="repos/new"                              element={<S><CreateRepoPage /></S>} />
              <Route path="repos/import"                           element={<S><ImportRepoPage /></S>} />
              <Route path="repos/:owner/:repo"                     element={<S><RepoPage /></S>} />
              <Route path="repos/:owner/:repo/blob"               element={<S><BlobPage /></S>} />
              <Route path="repos/:owner/:repo/commits"             element={<S><CommitsPage /></S>} />
              <Route path="repos/:owner/:repo/branches"            element={<S><BranchesPage /></S>} />
              <Route path="repos/:owner/:repo/settings"            element={<S><RepoSettingsPage /></S>} />
              <Route path="repos/:owner/:repo/issues"              element={<S><RepoIssuesPage /></S>} />
              <Route path="repos/:owner/:repo/pulls"               element={<S><RepoPRsPage /></S>} />
              <Route path="repos/:owner/:repo/pulls/new"           element={<S><CreatePRPage /></S>} />
              <Route path="repos/:owner/:repo/pulls/:prId"         element={<S><PRDetailPage /></S>} />
              <Route path="repos/:owner/:repo/pipelines"           element={<S><RepoPipelinesPage /></S>} />
              <Route path="repos/:owner/:repo/environments"        element={<S><EnvironmentsPage /></S>} />
              <Route path="repos/:owner/:repo/timeline"           element={<S><RepoTimelinePage /></S>} />
              <Route path="repos/:owner/:repo/secrets"            element={<S><RepoSecretsPage /></S>} />
              <Route path="repos/:owner/:repo/security"           element={<S><RepoSecurityPage /></S>} />
              <Route path="repos/:owner/:repo/runs/:runId"         element={<S><PipelineRunPage /></S>} />

              <Route path="starred"   element={<S><StarredPage /></S>} />
              <Route path="pulls"     element={<S><PRsPage /></S>} />
              <Route path="pipelines" element={<S><PipelinesPage /></S>} />
              <Route path="workspaces" element={<S><WorkspacesPage /></S>} />
              <Route path="workspaces/:handle" element={<S><WorkspacePage /></S>} />
              <Route path="workspaces/:handle/settings" element={<S><WorkspaceSettingsPage /></S>} />
              <Route path="explore"   element={<S><ExplorePage /></S>} />
              <Route path="profile"   element={<S><ProfilePage /></S>} />
              <Route path="settings"  element={<S><SettingsPage /></S>} />

              <Route path="*" element={<NotFound />} />
            </Route>
          </Routes>
        </AuthProvider>
      </BrowserRouter>
    </QueryClientProvider>
  )
}
