"use client";

import React, { useEffect, useState } from "react";
import { usePathname } from "next/navigation";
import dynamic from "next/dynamic";
import { ToastProvider } from "@/components/Toast";
import ErrorBoundary from "@/components/ErrorBoundary";
import { ConsentProvider } from "./ConsentProvider";
import { ThemeProvider } from "./ThemeProvider";

const BackgroundBlobs = dynamic(() => import("@/components/BackgroundBlobs").catch(() => ({ default: () => null })), {
  ssr: false,
  loading: () => null,
});

const ShaderGradientBackground = dynamic(
  () => import("./ShaderGradientBackground").catch(() => ({ default: () => null })),
  { ssr: false, loading: () => null }
);

export default function ClientProviders({
  children,
}: {
  children: React.ReactNode;
}) {
  const [mounted, setMounted] = useState(false);
  const pathname = usePathname();

  useEffect(() => {
    setMounted(true);
  }, [pathname]);

  return (
    <ErrorBoundary>
      <ErrorBoundary>
        <ConsentProvider>
          <ThemeProvider attribute="class" defaultTheme="light" enableSystem={false}>
            <GatedProviders mounted={mounted}>
              {children}
            </GatedProviders>
          </ThemeProvider>
        </ConsentProvider>
      </ErrorBoundary>
    </ErrorBoundary>
  );
}

function GatedProviders({
  children,
  mounted,
}: {
  children: React.ReactNode;
  mounted: boolean;
}) {
  // Defer heavy Three.js/WebGL background until after LCP
  const [deferredReady, setDeferredReady] = useState(false);
  useEffect(() => {
    if (!mounted) return;
    // Safari < 16.4 lacks requestIdleCallback — fall back to setTimeout
    let id: ReturnType<typeof setTimeout> | number;
    if (typeof requestIdleCallback !== "undefined") {
      id = requestIdleCallback(() => setDeferredReady(true), { timeout: 5000 });
      return () => cancelIdleCallback(id as number);
    } else {
      id = setTimeout(() => setDeferredReady(true), 1);
      return () => clearTimeout(id);
    }
  }, [mounted]);

  return (
    <ErrorBoundary>
      <ToastProvider>
        {deferredReady && <BackgroundBlobs />}
        {deferredReady && <ShaderGradientBackground />}
        <div className="relative z-10">{children}</div>
      </ToastProvider>
    </ErrorBoundary>
  );
}
