/**
 * Main Entry Point — deploy trigger: smoke test with pre-installed Chromium
 *
 * Clean provider setup using our own auth and workspace management.
 * NO Bird dependencies (apikit, shared/auth).
 */

// =============================================================================
// STYLES - Must be imported before components for Tailwind to work
// =============================================================================
import "@bird-ai/ui-agent/style-core.css"

// =============================================================================
// BUILD INFO — accessible via window.__BUILD_INFO__ in browser devtools
// =============================================================================
if (typeof window !== "undefined") {
  ;(window as unknown as Record<string, unknown>).__BUILD_INFO__ = Object.freeze({
    commit: __BUILD_COMMIT__,
    buildTime: __BUILD_TIME__,
    env: import.meta.env.MODE,
  })
}

// =============================================================================
// ERROR REPORTING - Initialize early to capture all errors
// =============================================================================
import { errorReporter } from "./lib/error-reporter"

// Defer Sentry to after first paint — removes ~300KB from critical path
if (typeof window !== "undefined") {
  const initSentryDeferred = () => import("./lib/sentry").then((m) => m.initSentry())
  if ("requestIdleCallback" in window) {
    requestIdleCallback(() => initSentryDeferred(), { timeout: 3000 })
  } else {
    setTimeout(() => initSentryDeferred(), 1)
  }
}

// Defer heavy feature CSS (editor prose, syntax highlighting, slide deck, xyflow)
// to after first paint — loaded via dynamic import which Vite resolves to the hashed filename.
if (typeof window !== "undefined") {
  const loadFeatureCSS = () => import("@bird-ai/ui-agent/style-artifacts.css")
  if ("requestIdleCallback" in window) {
    requestIdleCallback(() => loadFeatureCSS(), { timeout: 3000 })
  } else {
    setTimeout(() => loadFeatureCSS(), 1)
  }
}

// Initialize internal error reporting
errorReporter.init()

// =============================================================================
// REACT & PROVIDERS
// =============================================================================
import { createRoot } from "react-dom/client"
import { BrowserRouter } from "react-router"
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
import { IntlProvider } from "react-intl"
import { useDocumentLocale } from "./hooks/useDocumentLocale"
import { StrictMode, useState, useEffect, type FC, type ReactNode } from "react"
import enMessages from "./locales/en.json"
import { LocalAuthProvider } from "./auth"
import { AnonymousProvider } from "./context/AnonymousContext"
import { WorkspaceProvider } from "./context/WorkspaceContext"
import { PermissionsProvider } from "./context/PermissionsContext"
import { GlobalErrorBoundary } from "./components/GlobalErrorBoundary"
import { ActionIntentProvider } from "./context/ActionIntentContext"
import { App } from "./App"
import { SUPPORTED_LOCALES } from "./lib/locale"
import { initWebVitals } from "./lib/web-vitals"

if ("requestIdleCallback" in window) {
  requestIdleCallback(() => initWebVitals(), { timeout: 5000 })
} else {
  setTimeout(() => initWebVitals(), 100)
}

if ("serviceWorker" in navigator && import.meta.env.PROD) {
  const registerSW = () => {
    navigator.serviceWorker.register("/sw.js", { scope: "/" }).catch(() => {})
  }
  if ("requestIdleCallback" in window) {
    requestIdleCallback(registerSW, { timeout: 5000 })
  } else {
    setTimeout(registerSW, 1)
  }
}

// Strip the cache-busting _reload parameter injected by ArtifactErrorFallback when
// a chunk-load error forces a hard navigation to bypass stale HTTP caches.
// This runs before React mounts so the URL is clean before any route-matching occurs.
;(() => {
  try {
    const url = new URL(window.location.href)
    if (url.searchParams.has("_reload")) {
      url.searchParams.delete("_reload")
      window.history.replaceState(null, "", url.toString())
    }
  } catch {
    // ignore URL parsing errors (e.g. in unusual browser environments)
  }
})()

// Detect locale prefix from URL so React Router strips it via basename.
// CloudFront redirects / → /{locale}/ for SEO; the SPA must be aware.
const LOCALE_SLUGS_LOWER = new Set(SUPPORTED_LOCALES.map((l) => l.toLowerCase()))

function detectLocaleBasename(): string | undefined {
  const match = window.location.pathname.match(/^\/([a-z]{2}(?:-[a-z]+?)?)(?:\/|$)/)
  if (match && LOCALE_SLUGS_LOWER.has(match[1])) {
    return `/${match[1]}`
  }
  return undefined
}

const localeBasename = detectLocaleBasename()

// =============================================================================
// QUERY CLIENT
// =============================================================================

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 5 * 60 * 1000, // 5 minutes
      retry: 1,
      refetchOnWindowFocus: false,
    },
  },
})

// Note: QueryClient is exposed via React context (QueryClientProvider) instead of window
// to prevent untrusted scripts from accessing/mutating cached data

// =============================================================================
// LOCALE PROVIDER — dynamic locale detection + message loading
// =============================================================================

const LocaleProvider: FC<{ children: ReactNode }> = ({ children }) => {
  const locale = useDocumentLocale()
  const [messages, setMessages] = useState<Record<string, string>>(
    enMessages as Record<string, string>
  )

  useEffect(() => {
    if (locale === "en") {
      setMessages(enMessages as Record<string, string>)
      return
    }
    // Validate locale against allowlist before dynamic import to prevent path traversal
    if (!SUPPORTED_LOCALES.includes(locale)) {
      setMessages(enMessages as Record<string, string>)
      return
    }
    import(`./locales/${locale}.json`)
      .then((mod) => setMessages((mod.default ?? mod) as Record<string, string>))
      .catch(() => setMessages(enMessages as Record<string, string>))
  }, [locale])

  return (
    <IntlProvider locale={locale} defaultLocale="en" messages={messages}>
      {children}
    </IntlProvider>
  )
}

// =============================================================================
// RENDER
// =============================================================================

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <GlobalErrorBoundary>
      <LocaleProvider>
        <QueryClientProvider client={queryClient}>
          <ActionIntentProvider>
            <BrowserRouter basename={localeBasename}>
              <LocalAuthProvider>
                <AnonymousProvider>
                  <WorkspaceProvider>
                    <PermissionsProvider>
                      <App />
                    </PermissionsProvider>
                  </WorkspaceProvider>
                </AnonymousProvider>
              </LocalAuthProvider>
            </BrowserRouter>
          </ActionIntentProvider>
        </QueryClientProvider>
      </LocaleProvider>
    </GlobalErrorBoundary>
  </StrictMode>
)
// Force rebuild Sat Jan 17 13:25:38 CET 2026
// Trigger build 1768653986
// Rebuild with correct role 1768654061
// Force rebuild 1768654984
// Rebuild with cleared Turbo cache 1768655026
// Fix all auth paths 1768655570
// Complete auth fix 1768655607
// Build trigger: Sat Jan 17 23:51:46 CET 2026
