import * as Sentry from '@sentry/react';
import { StrictMode, useEffect, useState } from 'react';
import { createRoot } from 'react-dom/client';
import { RouterProvider } from 'react-router-dom';
import { useAuthStore } from './store/auth';
import { useNotificationStore } from './store/notifications';
import StreamChatProvider from './providers/StreamChatProvider';
import { ErrorBoundary } from './components/ErrorBoundary';
import { router } from './router';
import { isMockActive, installMockApi } from './dev/mockApi';
import { initAnalytics, identify, resetIdentity } from './lib/analytics';
import './styles/globals.css';

// Initialize Sentry before anything else. Noops when DSN is absent.
if (import.meta.env.VITE_SENTRY_DSN) {
  Sentry.init({
    dsn: import.meta.env.VITE_SENTRY_DSN,
    environment: import.meta.env.MODE,
    tracesSampleRate: import.meta.env.PROD ? 0.1 : 1.0,
    integrations: [Sentry.browserTracingIntegration()],
  });
}

// Initialize PostHog before React mounts. Noops in mock mode and when
// VITE_POSTHOG_KEY is missing.
if (!isMockActive()) {
  initAnalytics();
}

// Bridge auth → PostHog distinct_id so pre-auth splash exposure stitches
// to the post-auth experience.
let lastIdentifiedUserId: string | null = null;
useAuthStore.subscribe((state) => {
  const id = state.user?.id ?? null;
  if (id && id !== lastIdentifiedUserId) {
    identify(id);
    lastIdentifiedUserId = id;
  } else if (!id && lastIdentifiedUserId) {
    resetIdentity();
    lastIdentifiedUserId = null;
  }
});

function App() {
  const initAuth = useAuthStore((s) => s.initialize);
  const initNotifications = useNotificationStore((s) => s.initialize);
  const [mockReady, setMockReady] = useState(!isMockActive());

  // Install mock API + hydrate fake auth before anything else boots when
  // running inside the /dev/states gallery (or with ?_mock=1).
  useEffect(() => {
    if (!isMockActive()) return;
    installMockApi().then(() => setMockReady(true));
  }, []);

  useEffect(() => {
    if (!mockReady) return;
    // In mock mode, auth is already hydrated in-memory by installMockApi().
    // Skip the real init path which would hit localStorage + /auth/me and
    // race against other iframes sharing the same origin.
    if (!isMockActive()) {
      initAuth();
    }
    initNotifications();
  }, [mockReady, initAuth, initNotifications]);

  if (!mockReady) return null;

  return (
    <StreamChatProvider>
      <RouterProvider router={router} />
    </StreamChatProvider>
  );
}

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <ErrorBoundary>
      <App />
    </ErrorBoundary>
  </StrictMode>,
);
