// SPDX-License-Identifier: GPL-3.0-or-later

import { Routes, Route, Navigate } from 'react-router-dom';
import Layout from './components/Layout';
import ErrorBoundary from './components/ErrorBoundary';
import ConnectionError from './components/ConnectionError';
import { ToastProvider } from './components/Toast';
import UpdateBanner from './components/UpdateBanner';
import Dashboard from './pages/Dashboard';
import Backup from './pages/Backup';
import Restore from './pages/Restore';
import Snapshots from './pages/Snapshots';
import Jobs from './pages/Jobs';
import Account from './pages/Account';
import Settings from './pages/Settings';
import Setup from './pages/Setup';
import { BackendProvider, useBackend } from './contexts/BackendContext';
import { UpdateProvider } from './contexts/UpdateContext';

function AppRoutes() {
  const { status, isLoading, error, refresh, hasEverConnected, account } = useBackend();

  // During first launch the daemon binds its API only after Tor bootstraps
  // (~30s), so show a friendly "starting" state until the first successful
  // connection instead of a scary connection error.
  if (isLoading || (!hasEverConnected && (error || !status))) {
    return (
      <div className="min-h-screen flex items-center justify-center bg-slate-50 dark:bg-slate-900">
        <div className="text-center">
          <div className="inline-block animate-spin rounded-full h-12 w-12 border-4 border-primary-200 border-t-primary-600"></div>
          <p className="mt-4 text-lg font-medium text-slate-700 dark:text-slate-300">
            Establishing a private, secure connection…
          </p>
          <p className="mt-2 text-sm text-slate-500 dark:text-slate-400 max-w-md mx-auto">
            Private Archive routes your connection through the Tor network, so no one — not
            even us — can see who you are or what you back up. Building those anonymous,
            encrypted circuits takes a little longer than an ordinary connection, especially
            on first launch (up to a minute). The wait is the privacy working for you.
          </p>
        </div>
      </div>
    );
  }

  // Show connection error only after a previously working connection drops.
  if (error || !status) {
    return (
      <ConnectionError
        onRetry={refresh}
        message={error || 'Unable to connect to the backup service'}
      />
    );
  }

  // Check if account needs setup (not registered). The daemon reports this via
  // the account endpoint (status: "not_registered"); /status has no backend field.
  const needsSetup =
    account?.status === 'not_registered' || status?.backend?.registered === false;

  if (needsSetup) {
    return (
      <Routes>
        <Route path="/setup" element={<Setup />} />
        <Route path="*" element={<Navigate to="/setup" replace />} />
      </Routes>
    );
  }

  return (
    <Layout>
      <UpdateBanner />
      <Routes>
        <Route path="/" element={<Dashboard />} />
        <Route path="/backup" element={<Backup />} />
        <Route path="/restore" element={<Restore />} />
        <Route path="/snapshots" element={<Snapshots />} />
        <Route path="/jobs" element={<Jobs />} />
        <Route path="/account" element={<Account />} />
        <Route path="/settings" element={<Settings />} />
        <Route path="/setup" element={<Navigate to="/" replace />} />
        <Route path="*" element={<Navigate to="/" replace />} />
      </Routes>
    </Layout>
  );
}

function App() {
  return (
    <ErrorBoundary>
      <ToastProvider>
        <BackendProvider>
          <UpdateProvider>
            <AppRoutes />
          </UpdateProvider>
        </BackendProvider>
      </ToastProvider>
    </ErrorBoundary>
  );
}

export default App;
