import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import TwoStepPromptHost from './components/auth/TwoStepPromptHost';
import ConfirmHost from './components/shared/ConfirmHost';
import ErrorBoundary from './components/ErrorBoundary';
import { ToastProvider } from './hooks/useToast';
import { AccessibilityProvider } from './contexts/AccessibilityContext';
import { installTableKeyboardNavigation } from './utils/tableKeyboardNavigation';
import { installVisualViewportVars } from './utils/visualViewportVars';
import { reportError } from './services/errorReporter';
import { releaseFirstPaint } from './utils/loadingScene';
import { trackingTokenFromPath } from './utils/tripTracking';
import { requestCompanyFromPath } from './utils/rideRequests';
import './index.css';
// Visual refresh layer (tables, shell, surfaces); see the file header.
import './styles/design-refresh.css';
// Agape v3 (2026-10-17): the opened trip page's grammar for every page.
import './styles/agape-v3.css';
// Keep the driver trip-window contract last so global page/table refinements
// cannot restyle or reposition safety-critical trip actions.
import './styles/tripWindows.css';

// Runtime safety net: unhandled failures must never die silently. They are
// logged with enough context to diagnose, without leaking user data, and
// reported to Cloud Error Reporting (services/errorReporter, scrubbed).
const reportUnhandled = (kind) => (event) => {
  const reason = event?.reason || event?.error || event;
  const message = reason?.message || String(reason || 'Unknown error');
  console.error(`[agape:${kind}]`, message, reason?.stack || '');
  reportError(reason, { kind });
  try {
    window.dispatchEvent(new CustomEvent('agape-runtime-warning', { detail: { kind, message } }));
  } catch { /* noop */ }
};
window.addEventListener('unhandledrejection', reportUnhandled('unhandled-rejection'));
window.addEventListener('error', reportUnhandled('unhandled-error'));

installTableKeyboardNavigation(document);
// Windows stay above the phone keyboard (index.css, agape-keyboard-open).
installVisualViewportVars(window);

// The app's loading scene removes index.html's first paint when it takes
// over (utils/loadingScene); this is the backstop if it never does.
window.setTimeout(() => releaseFirstPaint(), 15000);

// A live ride tracking link (/track/<code>, utils/tripTracking) opens its own
// small public page: no sign-in, no portal.
const trackingToken = trackingTokenFromPath(window.location.pathname);
const TrackRidePage = trackingToken ? React.lazy(() => import('./components/track/TrackRidePage')) : null;
// The public ride request page (/request/<company>, utils/rideRequests).
const requestCompany = trackingToken ? '' : requestCompanyFromPath(window.location.pathname);
const RideRequestPage = requestCompany ? React.lazy(() => import('./components/requests/RideRequestPage')) : null;

ReactDOM.createRoot(document.getElementById('root')).render(
  TrackRidePage || RideRequestPage ? (
    <React.StrictMode>
      <ErrorBoundary>
        <React.Suspense fallback={null}>
          {TrackRidePage ? <TrackRidePage token={trackingToken} /> : <RideRequestPage company={requestCompany} />}
        </React.Suspense>
      </ErrorBoundary>
    </React.StrictMode>
  ) : (
  <React.StrictMode>
    <ErrorBoundary>
      <AccessibilityProvider>
        <ToastProvider>
          <App />
          <TwoStepPromptHost />
          <ConfirmHost />
        </ToastProvider>
      </AccessibilityProvider>
    </ErrorBoundary>
  </React.StrictMode>
  ),
);
