import {
  MutationCache,
  QueryCache,
  QueryClient,
} from "@tanstack/react-query";
import { toast } from "sonner";
import { ApiError, logError, reportError, toUserMessage } from "@/lib/errors";

declare module "@tanstack/react-query" {
  interface Register {
    queryMeta: { toastOnError?: boolean };
    mutationMeta: { suppressToast?: boolean };
  }
}

function shouldRetryQuery(failureCount: number, err: unknown): boolean {
  if (err instanceof ApiError) {
    // Retry only on transient status codes; 4xx generally won't succeed on retry.
    if (err.status === 408 || err.status === 429) return failureCount < 2;
    if (err.status >= 400 && err.status < 500) return false;
  }
  return failureCount < 2;
}

export function createQueryClient(): QueryClient {
  return new QueryClient({
    defaultOptions: {
      queries: {
        retry: shouldRetryQuery,
        refetchOnWindowFocus: false,
      },
      mutations: {
        // Mutations have side effects — never auto-retry.
        retry: 0,
      },
    },
    queryCache: new QueryCache({
      onError: (err, query) => {
        logError(err, { scope: "query", queryKey: query.queryKey });
        if (query.meta?.toastOnError) {
          toast.error(toUserMessage(err));
        }
      },
    }),
    mutationCache: new MutationCache({
      onError: (err, _variables, _context, mutation) => {
        reportError(err, {
          scope: "mutation",
          mutationKey: mutation.options.mutationKey,
        });
        if (mutation.meta?.suppressToast) return;
        toast.error(toUserMessage(err));
      },
    }),
  });
}
