import { AxiosError, CancelTokenSource } from "axios";
import { createContext, PropsWithChildren, useContext } from "react";
import {
  MutationConfig,
  MutationResultPair,
  QueryConfig as ReactQueryConfig,
  QueryResult,
  useMutation,
  useQuery,
} from "react-query";
import { newApiClient } from "./apiClient";
import * as T from "./types";
((newline))

interface CancellablePromise<T> extends Promise<T> {
  cancel?: () => void;
}
((newline))

const ApiContext = createContext<ReturnType<typeof newApiClient> | undefined>(undefined);
((newline))

export function ApiProvider<T extends ReturnType<typeof newApiClient>>({
  instance, children,
}: PropsWithChildren<{
  instance: T;
}>) {
  return <ApiContext.Provider value={instance}>{children}</ApiContext.Provider>;
}
((newline))

export const useApi = () => {
  const context = useContext(ApiContext);

  if (!context) {
    throw Error("Be sure to wrap your application with <ApiProvider>.");
  }

  return context;
};
((newline))

type AppErrorResponse = AxiosError<{
  key?: string;
  message?: string;
  info?: {
    _error?: {
      name?: string;
      message?: string;
      stack?: string[];
    };
    [key: string]: any;
  };
}>;
((newline))

type QueryConfig<Response, Error> = ReactQueryConfig<Response, Error> & { cancelToken?: CancelTokenSource };
((newline))

{{ for (const groupName of Object.keys(structure)) { }}
  {{ for (const itemName of Object.keys(structure[groupName])) { }}
    {{ const item = structure[groupName][itemName]; }}

    {{ if (item.type !== "route") { }}
    {{ continue; }}
    {{ } }}

    {{= reactQueryFn({ options, item, structure }) }}
((newline))

  {{ } }}
{{ } }}
