import React from 'react';
import { createRoot } from 'react-dom/client';
import { QueryClient } from '@tanstack/react-query';
import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client';
import { experimental_createQueryPersister } from '@tanstack/query-persist-client-core';
import App from './App';
import './index.css';
import { initializeCacheSystem, initializePrefetching } from './lib/caching';
import { initializeWebSocketManager } from './lib/realtime/websocketManager';

// Initialize caching and network monitoring
initializeCacheSystem();
initializeWebSocketManager();

// Initialize prefetching after DOM is ready
document.addEventListener('DOMContentLoaded', () => {
  initializePrefetching();
});

// Create a client with optimized settings for seamless navigation
const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 10 * 60 * 1000, // 10 minutes - trust cached data longer
      gcTime: 60 * 60 * 1000, // 60 minutes - keep data in cache longer
      retry: (failureCount, error) => {
        // Don't retry on 4xx errors (client errors)
        if (error && typeof error === 'object' && 'status' in error) {
          const status = error.status as number;
          if (status >= 400 && status < 500) return false;
        }
        return failureCount < 2; // Max 2 retries for server errors
      },
      retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000), // Exponential backoff: 1s, 2s, 4s, max 30s
      // Disable aggressive refetching for seamless experience
      refetchOnWindowFocus: false, // Don't refetch on window focus - trust cache
      refetchOnMount: false, // Don't refetch on component mount if data exists
      refetchOnReconnect: true, // Refetch on network reconnect to get fresh data
      refetchInterval: false, // No automatic polling
      networkMode: 'online', // Default to online mode, specific queries can override
      // Use structural sharing to prevent unnecessary re-renders
      structuralSharing: true,
      // Notify only on essential prop changes to reduce re-renders
      notifyOnChangeProps: ['data', 'error', 'isLoading'],
      meta: {
        // Add metadata for monitoring and debugging
        persistCache: true,
        timestamp: Date.now(),
      },
    },
    mutations: {
      retry: (failureCount, error) => {
        // Don't retry client errors (4xx)
        if (error && typeof error === 'object' && 'status' in error) {
          const status = error.status as number;
          if (status >= 400 && status < 500) return false;
        }
        // Retry server errors once
        return failureCount < 1;
      },
      retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 10000), // Exponential backoff for mutations: 1s, 2s, max 10s
      networkMode: 'online',
      // Global mutation error handler
      onError: (error) => {
        console.error('Mutation error:', error);
        // Error handling is done per-mutation with toast notifications
      },
      meta: {
        timestamp: Date.now(),
      },
    },
  },
});

// Create persister for sessionStorage (cleared on browser close, kept during navigation)
const persister = experimental_createQueryPersister({
  storage: window.sessionStorage,
  maxAge: 24 * 60 * 60 * 1000, // 24 hours
  key: 'KINGDOM_COUNSEL_CACHE',
  serialize: JSON.stringify,
  deserialize: JSON.parse,
});

// Enable Workbox logging in development
if (import.meta.env.DEV && 'serviceWorker' in navigator) {
  // @ts-ignore
  if (window.workbox) {
    // @ts-ignore
    window.workbox.setConfig({ debug: true });
  }
}

createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <PersistQueryClientProvider
      client={queryClient}
      persistOptions={{
        persister,
        maxAge: 24 * 60 * 60 * 1000, // 24 hours
        buster: import.meta.env.VITE_APP_VERSION || '1.0.0',
        dehydrateOptions: {
          shouldDehydrateQuery: (query) => {
            // Only persist successful queries, not pending or error states
            return query.state.status === 'success';
          },
        },
      }}
    >
      <App />
    </PersistQueryClientProvider>
  </React.StrictMode>
);