"use client";

import { useSyncExternalStore, type ReactNode } from "react";

const emptySubscribe = () => () => {};

/**
 * Renders its children only after hydration on the client. Use this to wrap UI
 * whose initial render is non-deterministic (e.g. seeded with Math.random()),
 * which would otherwise cause a server/client hydration mismatch. The
 * `fallback` is shown during SSR and the first (hydrating) client render.
 *
 * Uses useSyncExternalStore rather than a mount effect so there is no
 * setState-in-effect and the server/client snapshots stay explicit.
 */
export function ClientOnly({
  children,
  fallback = null,
}: {
  children: ReactNode;
  fallback?: ReactNode;
}) {
  const isServer = useSyncExternalStore(
    emptySubscribe,
    () => false,
    () => true,
  );
  return <>{isServer ? fallback : children}</>;
}
