import { httpBatchLink } from "@trpc/client";
import { createTRPCReact } from "@trpc/react-query";
import { useCallback, useRef, useState, type ReactNode } from "react";
import SuperJSON from "superjson";

import { useAuthClient, useSession } from "@/contexts/AuthContext";
import { createAppQueryClient } from "@/lib/query-client";
import type { AppRouter } from "beenvoice/server/api/root";

export const api = createTRPCReact<AppRouter>();

export function TRPCProvider({ apiUrl, children }: { apiUrl: string; children: ReactNode }) {
  const authClient = useAuthClient();
  const { refetch } = useSession();

  const handleUnauthorized = useCallback(async () => {
    const session = await authClient.getSession();
    if (!session.data?.user) {
      await authClient.signOut();
      await refetch();
    }
  }, [authClient, refetch]);

  const onUnauthorizedRef = useRef(handleUnauthorized);
  onUnauthorizedRef.current = handleUnauthorized;

  const [queryClient] = useState(() =>
    createAppQueryClient(() => {
      void onUnauthorizedRef.current();
    }),
  );

  const [trpcClient] = useState(() =>
    api.createClient({
      links: [
        httpBatchLink({
          url: `${apiUrl}/api/trpc`,
          transformer: SuperJSON,
          headers() {
            const cookie = (
              authClient as { getCookie?: () => string | null | undefined }
            ).getCookie?.();
            return cookie ? { cookie } : {};
          },
        }),
      ],
    }),
  );

  return (
    <api.Provider client={trpcClient} queryClient={queryClient}>
      {children}
    </api.Provider>
  );
}
