import { createRoot } from "react-dom/client";
import App, { queryClient } from "./App.tsx";
// Self-hosted fonts — no network round-trip to Google Fonts.
// Only the weights actually used in the design system are imported.
import "@fontsource/inter/300.css";
import "@fontsource/inter/400.css";
import "@fontsource/inter/500.css";
import "@fontsource/inter/600.css";
import "@fontsource/inter/700.css";
import "@fontsource/cormorant-garamond/300.css";
import "@fontsource/cormorant-garamond/400.css";
import "@fontsource/cormorant-garamond/500.css";
import "@fontsource/cormorant-garamond/600.css";
import "@fontsource/cormorant-garamond/700.css";
import "./index.css";
import { supabase } from "@/integrations/supabase/client";
import { resetGridPaginationOnReload } from "@/lib/grid-pagination-reset";
import { fetchAllProductsAndEbooks, fetchFirstProductsSlice, fairShuffle } from "@/hooks/useProducts";
// Side-effect import: forces Footer into the entry graph so it's
// modulepreloaded with the initial HTML instead of being fetched as a
// lazy sibling chunk when a page renders. Prevents the Footer from
// popping in a few hundred ms after first paint on short pages
// (e.g. /ebooks) and causing a large CLS.
import "@/components/Footer";

// Capture PWA install prompt globally
window.addEventListener("beforeinstallprompt", (e) => {
  e.preventDefault();
  (window as any).deferredPrompt = e;
});

// Prefetch critical data before React mounts — fires immediately, in two stages.
//
// Stage 1: a small first slice of the catalogue so the grid can paint without
// waiting for ~1 650 products to download.
// Stage 2: the full catalogue, merged into the SAME ["products"] cache entry.
// Items already shown keep their position — the remainder is appended — so the
// grid never re-orders under the user, and search/filters still see everything.
//
// IMPORTANT: the final cached value must match the shape useProducts()'s queryFn
// produces (products AND approved ebooks, merged, fair-shuffled once). If these
// ever fall out of sync, react-query serves a mismatched cache on first paint.
queryClient.prefetchQuery({
  queryKey: ["products"],
  queryFn: async () => {
    const first = await fetchFirstProductsSlice(300);
    const shuffledFirst = fairShuffle(first);

    // Fill in the rest in the background once the first slice is cached.
    fetchAllProductsAndEbooks()
      .then((all) => {
        const seen = new Set(shuffledFirst.map((p) => p.id));
        const rest = fairShuffle(all.filter((p) => !seen.has(p.id)));
        queryClient.setQueryData(["products"], [...shuffledFirst, ...rest]);
      })
      .catch(() => {
        // Non-fatal: useProducts() will refetch the full list on mount/focus.
      });

    return shuffledFirst;
  },
  staleTime: 5 * 60 * 1000,
});

// Render immediately — don't block on non-critical prefetches
resetGridPaginationOnReload();

createRoot(document.getElementById("root")!).render(<App />);

// Defer non-critical prefetches to idle time
const deferredPrefetch = () => {
  queryClient.prefetchQuery({
    queryKey: ["categories"],
    queryFn: async () => {
      const { data, error } = await supabase
        .from("categories")
        .select("id, slug, name, image_url")
        .order("name", { ascending: true });
      if (error) throw error;
      return data || [];
    },
    staleTime: 10 * 60 * 1000,
  });

  queryClient.prefetchQuery({
    queryKey: ["offer-products"],
    queryFn: async () => {
      const [settingsRes, entriesRes] = await Promise.all([
        supabase.from("offer_settings").select("id, title, sort_order").order("sort_order", { ascending: true }),
        supabase
          .from("offer_products")
          .select("product_id, ebook_id, offer_id, sort_order")
          .order("sort_order", { ascending: true }),
      ]);
      const settings = settingsRes.data || [];
      const entries = entriesRes.data || [];
      return settings.map((s) => ({
        id: s.id,
        title: s.title,
        sort_order: s.sort_order,
        items: entries
          .filter((e: any) => e.offer_id === s.id)
          .map((e: any) =>
            e.ebook_id
              ? { id: e.ebook_id, type: "ebook" as const }
              : e.product_id
                ? { id: e.product_id, type: "product" as const }
                : null,
          )
          .filter((e: any) => e !== null),
      }));
    },
    staleTime: 5 * 60 * 1000,
  });
};

if ("requestIdleCallback" in window) {
  (window as any).requestIdleCallback(deferredPrefetch);
} else {
  setTimeout(deferredPrefetch, 100);
}
