import { trpc } from "@/lib/trpc";
import { UNAUTHED_ERR_MSG } from '@shared/const';
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { httpBatchLink, TRPCClientError, splitLink, httpLink } from "@trpc/client";
import { createRoot } from "react-dom/client";
import { HelmetProvider } from "react-helmet-async";
import superjson from "superjson";
import App from "./App";
import { getLoginUrl } from "./const";
import "./index.css";

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 60_000,           // 60s - data stays fresh for 60 seconds
      refetchOnWindowFocus: false,  // Don't refetch when user tabs back
      retry: 1,                     // Only retry once on failure
      gcTime: 300_000,              // 5min - keep unused data in cache for 5 minutes
    },
  },
});

const redirectToLoginIfUnauthorized = (error: unknown) => {
  if (!(error instanceof TRPCClientError)) return;
  if (typeof window === "undefined") return;

  const isUnauthorized = error.message === UNAUTHED_ERR_MSG;

  if (!isUnauthorized) return;

  window.location.href = getLoginUrl();
};

queryClient.getQueryCache().subscribe(event => {
  if (event.type === "updated" && event.action.type === "error") {
    const error = event.query.state.error;
    redirectToLoginIfUnauthorized(error);
    console.error("[API Query Error]", error);
  }
});

queryClient.getMutationCache().subscribe(event => {
  if (event.type === "updated" && event.action.type === "error") {
    const error = event.mutation.state.error;
    redirectToLoginIfUnauthorized(error);
    console.error("[API Mutation Error]", error);
  }
});

const trpcClient = trpc.createClient({
  links: [
    splitLink({
      // Use non-batched link for subscriptions/streaming if needed
      condition: (op) => op.type === 'subscription',
      true: httpLink({
        url: "/api/trpc",
        transformer: superjson,
      }),
      false: httpBatchLink({
        url: "/api/trpc",
        transformer: superjson,
        // Request deduplication: batch identical queries within 10ms window
        maxURLLength: 2048,
        headers() {
          const token = localStorage.getItem('hunch_token');
          return token ? { 'x-hunch-token': token } : {};
        },
        fetch(input, init) {
          return globalThis.fetch(input, {
            ...(init ?? {}),
            credentials: "include",
          });
        },
      }),
    }),
  ],
});

// Handle Google OAuth callback - capture token from URL params
(function handleGoogleOAuthCallback() {
  if (typeof window === 'undefined') return;
  const params = new URLSearchParams(window.location.search);
  const token = params.get('hunch_token');
  const authProvider = params.get('auth_provider');
  if (token && authProvider === 'google') {
    localStorage.setItem('hunch_token', token);
    // Clean up URL params
    params.delete('hunch_token');
    params.delete('auth_provider');
    const cleanUrl = params.toString()
      ? `${window.location.pathname}?${params.toString()}`
      : window.location.pathname;
    window.history.replaceState({}, '', cleanUrl);
  }
})();

createRoot(document.getElementById("root")!).render(
  <HelmetProvider>
    <trpc.Provider client={trpcClient} queryClient={queryClient}>
      <QueryClientProvider client={queryClient}>
        <App />
      </QueryClientProvider>
    </trpc.Provider>
  </HelmetProvider>
);

// Register service worker for offline caching of static assets and market data
if ('serviceWorker' in navigator && import.meta.env.PROD) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/sw.js').catch(() => {
      // SW registration failed silently
    });
  });
}

// Web Vitals tracking - report Core Web Vitals to analytics
if (typeof window !== 'undefined') {
  const reportWebVital = (metric: { name: string; value: number; id: string }) => {
    // Send to analytics endpoint if available
    if (navigator.sendBeacon) {
      navigator.sendBeacon('/api/vitals', JSON.stringify({
        name: metric.name,
        value: Math.round(metric.name === 'CLS' ? metric.value * 1000 : metric.value),
        id: metric.id,
        page: window.location.pathname,
        timestamp: Date.now(),
      }));
    }
  };
  // Lazy-load web-vitals library
  import('web-vitals').then(({ onCLS, onINP, onLCP, onFCP, onTTFB }) => {
    onCLS(reportWebVital);
    onINP(reportWebVital);
    onLCP(reportWebVital);
    onFCP(reportWebVital);
    onTTFB(reportWebVital);
  }).catch(() => { /* web-vitals not available */ });
}
