"use client";

import React, { useState } from "react";
import superjson from "superjson";
import { httpBatchLink } from "@trpc/client";
import { createTRPCReact } from "@trpc/react-query";
import { getCurrentUrl } from "@/lib/current-url";
import { makeQueryClient } from "./query-client";

import { QueryClientProvider, type QueryClient } from "@tanstack/react-query";
import type { appRouter } from "./routers/_app";

export const trpc = createTRPCReact<typeof appRouter>();

let clientQueryClientSingleton: QueryClient;

function getQueryClient(): QueryClient {
  if (typeof window === "undefined") {
    // Server: always make a new query client
    return makeQueryClient();
  }
  // Browser: use singleton pattern to keep the same query client
  return (clientQueryClientSingleton ??= makeQueryClient());
}
function getUrl(): string {
  const base = ((): string => {
    if (typeof window !== "undefined") return "";
    return getCurrentUrl();
  })();
  return `${base}/api/trpc`;
}
export function TRPCProvider(
  props: Readonly<{
    children: React.ReactNode;
  }>
): React.JSX.Element {
  // NOTE: Avoid useState when initializing the query client if you don't
  //       have a suspense boundary between this and the code that may
  //       suspend because React will throw away the client on the initial
  //       render if it suspends and there is no boundary
  const queryClient = getQueryClient();
  const [trpcClient] = useState(() =>
    trpc.createClient({
      links: [
        httpBatchLink({
          transformer: superjson,
          url: getUrl(),
        }),
      ]
    })
  );

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