import { createRoot } from 'react-dom/client'
import { BrowserRouter } from 'react-router-dom'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
// Шрифты дизайн-системы — self-hosted через @fontsource (без внешних CDN),
// импортируются ДО ./index.css, чтобы @font-face объявились раньше стилей.
// Агрегатные <вес>.css включают все subset'ы, включая кириллицу (интерфейс
// русский). Веса — по DESIGN_SYSTEM.md: Unbounded 400/600/700 (display),
// Inter 400/500/600/700 (body), JetBrains Mono 500 (mono).
import '@fontsource/unbounded/400.css'
import '@fontsource/unbounded/600.css'
import '@fontsource/unbounded/700.css'
import '@fontsource/inter/400.css'
import '@fontsource/inter/500.css'
import '@fontsource/inter/600.css'
import '@fontsource/inter/700.css'
import '@fontsource/jetbrains-mono/500.css'
import './index.css'
import App from './App.tsx'
import { AuthProvider } from '@/auth/AuthProvider'
import { ToastProvider } from '@/components/ui/ToastProvider'

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      // Данные почти всегда актуализируются через собственные refetchInterval —
      // не рефетчим агрессивно при каждом фокусе окна.
      refetchOnWindowFocus: false,
      retry: 1,
    },
  },
})

/*
 * Без <StrictMode>: намеренно, из-за экрана конференции (RoomPage).
 *
 * `@livekit/components-react` <LiveKitRoom> (хук useLiveKitRoom) создаёт
 * `Room` в useEffect и вызывает `room.disconnect()` в cleanup-эффекте при
 * размонтировании. Двойной вызов эффектов StrictMode в dev (mount → cleanup
 * → mount) укладывается в ровно тот гоночный сценарий, от которого сама
 * библиотека предупреждает в комментарии к своему (неиспользуемому внутри
 * <LiveKitRoom>) хуку useSequentialRoomConnectDisconnect: «room.connect() в
 * теле эффекта может продолжить выполняться, пока ещё не завершился
 * room.disconnect() из cleanup предыдущего рендера» — т.е. первый Room
 * успевает частично подключиться (в т.ч. опубликовать локальный трек камеры
 * с реальным sid) и почти сразу схлопывается вместе со вторым, из-за чего
 * реальный (переживший гонку) Room получает событие Disconnected и роняет
 * нас в /lobby через onDisconnected, а GridLayout/useVisualStableUpdate
 * параллельно ловит смену идентичности трека (placeholder → реальный трек
 * → снова placeholder) и логирует `Error while running updatePages()`.
 * Внутри `<LiveKitRoom>` эта гонка не сериализуется (в отличие от
 * useSequentialRoomConnectDisconnect), поэтому единственный надёжный фикс на
 * уровне приложения — не выполнять эффекты дважды. В production-сборке
 * StrictMode всё равно не даёт двойного вызова эффектов, так что для
 * собранного бандла разницы нет — риск только в dev-режиме, где мы и теряли
 * подключение к комнате.
 */
createRoot(document.getElementById('root')!).render(
  <BrowserRouter>
    <QueryClientProvider client={queryClient}>
      <ToastProvider>
        <AuthProvider>
          <App />
        </AuthProvider>
      </ToastProvider>
    </QueryClientProvider>
  </BrowserRouter>,
)
