import { StrictMode } from 'react'
import ReactDOM from 'react-dom/client'
import { QueryClientProvider } from '@tanstack/react-query'
import { RouterProvider, createRouter } from '@tanstack/react-router'
import { useAuthStore } from '@/stores/auth-store'
import { useWebSocketStore } from '@/stores/websocket-store'
import { initAuthBroadcastListener } from '@/lib/auth/auth-broadcast'
import {
  startProactiveRefresh,
  stopProactiveRefresh,
} from '@/lib/auth/proactive-refresh'
import { queryClient, setQueryClientNavigator } from '@/lib/query-client'
import { getTenantSlug } from '@/lib/tenant'
import { WebSocketService } from '@/lib/websocket'
import { issueWsTicket } from '@/lib/websocket/ws-ticket.api'
import { TooltipProvider } from '@/components/ui/tooltip'
import { FontProvider } from './context/font-provider'
import { ThemeProvider } from './context/theme-provider'
// Generated Routes
import { routeTree } from './routeTree.gen'
// Styles
import './styles/index.css'

// Create a new router instance
const router = createRouter({
  routeTree,
  context: { queryClient },
  defaultPreload: 'intent',
  defaultPreloadStaleTime: 0,
  defaultViewTransition: true,
})

// Set up navigation for query client error handling
setQueryClientNavigator(
  (redirectPath: string) => {
    const tenant = getTenantSlug()
    if (tenant) {
      router.navigate({
        to: '/$tenant/sign-in',
        params: { tenant },
        search: { redirect: redirectPath },
      })
    }
  },
  () => router.navigate({ to: '/500' })
)

// Register the router instance for type safety
declare module '@tanstack/react-router' {
  interface Register {
    router: typeof router
  }

  interface HistoryState {
    userSettingsHistoryIndex?: number
  }
}

// Initialize WebSocket Service (before React renders)
WebSocketService.initialize({
  wsHost: import.meta.env.VITE_WS_HOST || 'localhost:8080',
  wsSecure: import.meta.env.VITE_WS_SECURE === 'true',
  getConnectTicket: async () => {
    try {
      return await issueWsTicket()
    } catch (error) {
      // Terminal auth failure clears the store (coordinator); a transient
      // error does not — rethrow it so the WS backoff can retry.
      if (!useAuthStore.getState().isAuthenticated) return null
      throw error
    }
  },
  getIsAuthenticated: () => useAuthStore.getState().isAuthenticated,
  onStatusChange: (status) => {
    useWebSocketStore.getState().setStatus(status)
  },
  onReconnectAttemptsChange: (attempts) => {
    useWebSocketStore.getState().setReconnectAttempts(attempts)
  },
  getPendingSubscriptions: () =>
    useWebSocketStore.getState().getPendingSubscriptions(),
  addPendingSubscription: (conversationId) => {
    useWebSocketStore.getState().addPendingSubscription(conversationId)
  },
  clearPendingSubscriptions: () => {
    useWebSocketStore.getState().clearPendingSubscriptions()
  },
  queryClient,
})

// Cross-tab auth coordination: adopt refreshed tokens from other tabs.
initAuthBroadcastListener()

// Proactive refresh: start/stop with the authenticated state.
if (useAuthStore.getState().isAuthenticated) {
  startProactiveRefresh()
}
useAuthStore.subscribe((state) => {
  if (state.isAuthenticated) {
    startProactiveRefresh()
  } else {
    stopProactiveRefresh()
  }
})

// Render the app
const rootElement = document.getElementById('root')!
const root = ReactDOM.createRoot(rootElement)
root.render(
  <StrictMode>
    <QueryClientProvider client={queryClient}>
      <ThemeProvider>
        <FontProvider>
          <TooltipProvider>
            <RouterProvider router={router} />
          </TooltipProvider>
        </FontProvider>
      </ThemeProvider>
    </QueryClientProvider>
  </StrictMode>
)
