/**
 * Generated by orval v8.8.0 🍺
 * Do not edit manually.
 * OpenAPI spec version: 0.0.0
 */
import { useMutation, useQuery } from "@tanstack/react-query";
import type {
  DataTag,
  DefinedInitialDataOptions,
  DefinedUseQueryResult,
  MutationFunction,
  QueryClient,
  QueryFunction,
  QueryKey,
  UndefinedInitialDataOptions,
  UseMutationOptions,
  UseMutationResult,
  UseQueryOptions,
  UseQueryResult,
} from "@tanstack/react-query";

import type {
  ApiSocialPostsFeedListParams,
  ApiSocialPostsListParams,
  ApiSocialPostsMediaCreateBody,
  ApiSocialPostsSaveCreate200,
  ApiSocialPostsSavedListParams,
  PaginatedPostList,
  PatchedPost,
  Post,
  PostContent,
  PostVote,
  TagAttach,
} from "../models";

import { privateMutator } from "../../../privateClient";

// https://stackoverflow.com/questions/49579094/typescript-conditional-types-filter-out-readonly-properties-pick-only-requir/49579497#49579497
type IfEquals<X, Y, A = X, B = never> =
  (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? A : B;

type WritableKeys<T> = {
  [P in keyof T]-?: IfEquals<
    { [Q in P]: T[P] },
    { -readonly [Q in P]: T[P] },
    P
  >;
}[keyof T];

type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
  k: infer I,
) => void
  ? I
  : never;
type DistributeReadOnlyOverUnions<T> = T extends any ? NonReadonly<T> : never;

type Writable<T> = Pick<T, WritableKeys<T>>;
type NonReadonly<T> = [T] extends [UnionToIntersection<T>]
  ? {
      [P in keyof Writable<T>]: T[P] extends object
        ? NonReadonly<NonNullable<T[P]>>
        : T[P];
    }
  : DistributeReadOnlyOverUnions<T>;

/**
 * Returns posts. Filter by `hub` query param to scope to a hub.
 * @summary List posts
 */
export const apiSocialPostsList = (
  params?: ApiSocialPostsListParams,
  signal?: AbortSignal,
) => {
  return privateMutator<PaginatedPostList>({
    url: `/api/social/posts/`,
    method: "GET",
    params,
    signal,
  });
};

export const getApiSocialPostsListQueryKey = (
  params?: ApiSocialPostsListParams,
) => {
  return [`/api/social/posts/`, ...(params ? [params] : [])] as const;
};

export const getApiSocialPostsListQueryOptions = <
  TData = Awaited<ReturnType<typeof apiSocialPostsList>>,
  TError = unknown,
>(
  params?: ApiSocialPostsListParams,
  options?: {
    query?: Partial<
      UseQueryOptions<
        Awaited<ReturnType<typeof apiSocialPostsList>>,
        TError,
        TData
      >
    >;
  },
) => {
  const { query: queryOptions } = options ?? {};

  const queryKey =
    queryOptions?.queryKey ?? getApiSocialPostsListQueryKey(params);

  const queryFn: QueryFunction<
    Awaited<ReturnType<typeof apiSocialPostsList>>
  > = ({ signal }) => apiSocialPostsList(params, signal);

  return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
    Awaited<ReturnType<typeof apiSocialPostsList>>,
    TError,
    TData
  > & { queryKey: DataTag<QueryKey, TData, TError> };
};

export type ApiSocialPostsListQueryResult = NonNullable<
  Awaited<ReturnType<typeof apiSocialPostsList>>
>;
export type ApiSocialPostsListQueryError = unknown;

export function useApiSocialPostsList<
  TData = Awaited<ReturnType<typeof apiSocialPostsList>>,
  TError = unknown,
>(
  params: undefined | ApiSocialPostsListParams,
  options: {
    query: Partial<
      UseQueryOptions<
        Awaited<ReturnType<typeof apiSocialPostsList>>,
        TError,
        TData
      >
    > &
      Pick<
        DefinedInitialDataOptions<
          Awaited<ReturnType<typeof apiSocialPostsList>>,
          TError,
          Awaited<ReturnType<typeof apiSocialPostsList>>
        >,
        "initialData"
      >;
  },
  queryClient?: QueryClient,
): DefinedUseQueryResult<TData, TError> & {
  queryKey: DataTag<QueryKey, TData, TError>;
};
export function useApiSocialPostsList<
  TData = Awaited<ReturnType<typeof apiSocialPostsList>>,
  TError = unknown,
>(
  params?: ApiSocialPostsListParams,
  options?: {
    query?: Partial<
      UseQueryOptions<
        Awaited<ReturnType<typeof apiSocialPostsList>>,
        TError,
        TData
      >
    > &
      Pick<
        UndefinedInitialDataOptions<
          Awaited<ReturnType<typeof apiSocialPostsList>>,
          TError,
          Awaited<ReturnType<typeof apiSocialPostsList>>
        >,
        "initialData"
      >;
  },
  queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
  queryKey: DataTag<QueryKey, TData, TError>;
};
export function useApiSocialPostsList<
  TData = Awaited<ReturnType<typeof apiSocialPostsList>>,
  TError = unknown,
>(
  params?: ApiSocialPostsListParams,
  options?: {
    query?: Partial<
      UseQueryOptions<
        Awaited<ReturnType<typeof apiSocialPostsList>>,
        TError,
        TData
      >
    >;
  },
  queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
  queryKey: DataTag<QueryKey, TData, TError>;
};
/**
 * @summary List posts
 */

export function useApiSocialPostsList<
  TData = Awaited<ReturnType<typeof apiSocialPostsList>>,
  TError = unknown,
>(
  params?: ApiSocialPostsListParams,
  options?: {
    query?: Partial<
      UseQueryOptions<
        Awaited<ReturnType<typeof apiSocialPostsList>>,
        TError,
        TData
      >
    >;
  },
  queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
  queryKey: DataTag<QueryKey, TData, TError>;
} {
  const queryOptions = getApiSocialPostsListQueryOptions(params, options);

  const query = useQuery(queryOptions, queryClient) as UseQueryResult<
    TData,
    TError
  > & { queryKey: DataTag<QueryKey, TData, TError> };

  return { ...query, queryKey: queryOptions.queryKey };
}

/**
 * Creates a post. The requesting user is set as the author automatically.
 * @summary Create a post
 */
export const apiSocialPostsCreate = (
  post: NonReadonly<Post>,
  signal?: AbortSignal,
) => {
  return privateMutator<Post>({
    url: `/api/social/posts/`,
    method: "POST",
    headers: { "Content-Type": "application/json" },
    data: post,
    signal,
  });
};

export const getApiSocialPostsCreateMutationOptions = <
  TError = unknown,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof apiSocialPostsCreate>>,
    TError,
    { data: NonReadonly<Post> },
    TContext
  >;
}): UseMutationOptions<
  Awaited<ReturnType<typeof apiSocialPostsCreate>>,
  TError,
  { data: NonReadonly<Post> },
  TContext
> => {
  const mutationKey = ["apiSocialPostsCreate"];
  const { mutation: mutationOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey } };

  const mutationFn: MutationFunction<
    Awaited<ReturnType<typeof apiSocialPostsCreate>>,
    { data: NonReadonly<Post> }
  > = (props) => {
    const { data } = props ?? {};

    return apiSocialPostsCreate(data);
  };

  return { mutationFn, ...mutationOptions };
};

export type ApiSocialPostsCreateMutationResult = NonNullable<
  Awaited<ReturnType<typeof apiSocialPostsCreate>>
>;
export type ApiSocialPostsCreateMutationBody = NonReadonly<Post>;
export type ApiSocialPostsCreateMutationError = unknown;

/**
 * @summary Create a post
 */
export const useApiSocialPostsCreate = <TError = unknown, TContext = unknown>(
  options?: {
    mutation?: UseMutationOptions<
      Awaited<ReturnType<typeof apiSocialPostsCreate>>,
      TError,
      { data: NonReadonly<Post> },
      TContext
    >;
  },
  queryClient?: QueryClient,
): UseMutationResult<
  Awaited<ReturnType<typeof apiSocialPostsCreate>>,
  TError,
  { data: NonReadonly<Post> },
  TContext
> => {
  return useMutation(
    getApiSocialPostsCreateMutationOptions(options),
    queryClient,
  );
};
/**
 * @summary Retrieve a post
 */
export const apiSocialPostsRetrieve = (id: number, signal?: AbortSignal) => {
  return privateMutator<Post>({
    url: `/api/social/posts/${id}/`,
    method: "GET",
    signal,
  });
};

export const getApiSocialPostsRetrieveQueryKey = (id: number) => {
  return [`/api/social/posts/${id}/`] as const;
};

export const getApiSocialPostsRetrieveQueryOptions = <
  TData = Awaited<ReturnType<typeof apiSocialPostsRetrieve>>,
  TError = unknown,
>(
  id: number,
  options?: {
    query?: Partial<
      UseQueryOptions<
        Awaited<ReturnType<typeof apiSocialPostsRetrieve>>,
        TError,
        TData
      >
    >;
  },
) => {
  const { query: queryOptions } = options ?? {};

  const queryKey =
    queryOptions?.queryKey ?? getApiSocialPostsRetrieveQueryKey(id);

  const queryFn: QueryFunction<
    Awaited<ReturnType<typeof apiSocialPostsRetrieve>>
  > = ({ signal }) => apiSocialPostsRetrieve(id, signal);

  return {
    queryKey,
    queryFn,
    enabled: !!id,
    ...queryOptions,
  } as UseQueryOptions<
    Awaited<ReturnType<typeof apiSocialPostsRetrieve>>,
    TError,
    TData
  > & { queryKey: DataTag<QueryKey, TData, TError> };
};

export type ApiSocialPostsRetrieveQueryResult = NonNullable<
  Awaited<ReturnType<typeof apiSocialPostsRetrieve>>
>;
export type ApiSocialPostsRetrieveQueryError = unknown;

export function useApiSocialPostsRetrieve<
  TData = Awaited<ReturnType<typeof apiSocialPostsRetrieve>>,
  TError = unknown,
>(
  id: number,
  options: {
    query: Partial<
      UseQueryOptions<
        Awaited<ReturnType<typeof apiSocialPostsRetrieve>>,
        TError,
        TData
      >
    > &
      Pick<
        DefinedInitialDataOptions<
          Awaited<ReturnType<typeof apiSocialPostsRetrieve>>,
          TError,
          Awaited<ReturnType<typeof apiSocialPostsRetrieve>>
        >,
        "initialData"
      >;
  },
  queryClient?: QueryClient,
): DefinedUseQueryResult<TData, TError> & {
  queryKey: DataTag<QueryKey, TData, TError>;
};
export function useApiSocialPostsRetrieve<
  TData = Awaited<ReturnType<typeof apiSocialPostsRetrieve>>,
  TError = unknown,
>(
  id: number,
  options?: {
    query?: Partial<
      UseQueryOptions<
        Awaited<ReturnType<typeof apiSocialPostsRetrieve>>,
        TError,
        TData
      >
    > &
      Pick<
        UndefinedInitialDataOptions<
          Awaited<ReturnType<typeof apiSocialPostsRetrieve>>,
          TError,
          Awaited<ReturnType<typeof apiSocialPostsRetrieve>>
        >,
        "initialData"
      >;
  },
  queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
  queryKey: DataTag<QueryKey, TData, TError>;
};
export function useApiSocialPostsRetrieve<
  TData = Awaited<ReturnType<typeof apiSocialPostsRetrieve>>,
  TError = unknown,
>(
  id: number,
  options?: {
    query?: Partial<
      UseQueryOptions<
        Awaited<ReturnType<typeof apiSocialPostsRetrieve>>,
        TError,
        TData
      >
    >;
  },
  queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
  queryKey: DataTag<QueryKey, TData, TError>;
};
/**
 * @summary Retrieve a post
 */

export function useApiSocialPostsRetrieve<
  TData = Awaited<ReturnType<typeof apiSocialPostsRetrieve>>,
  TError = unknown,
>(
  id: number,
  options?: {
    query?: Partial<
      UseQueryOptions<
        Awaited<ReturnType<typeof apiSocialPostsRetrieve>>,
        TError,
        TData
      >
    >;
  },
  queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
  queryKey: DataTag<QueryKey, TData, TError>;
} {
  const queryOptions = getApiSocialPostsRetrieveQueryOptions(id, options);

  const query = useQuery(queryOptions, queryClient) as UseQueryResult<
    TData,
    TError
  > & { queryKey: DataTag<QueryKey, TData, TError> };

  return { ...query, queryKey: queryOptions.queryKey };
}

/**
 * Full update. Author only.
 * @summary Replace a post
 */
export const apiSocialPostsUpdate = (
  id: number,
  post: NonReadonly<Post>,
  signal?: AbortSignal,
) => {
  return privateMutator<Post>({
    url: `/api/social/posts/${id}/`,
    method: "PUT",
    headers: { "Content-Type": "application/json" },
    data: post,
    signal,
  });
};

export const getApiSocialPostsUpdateMutationOptions = <
  TError = unknown,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof apiSocialPostsUpdate>>,
    TError,
    { id: number; data: NonReadonly<Post> },
    TContext
  >;
}): UseMutationOptions<
  Awaited<ReturnType<typeof apiSocialPostsUpdate>>,
  TError,
  { id: number; data: NonReadonly<Post> },
  TContext
> => {
  const mutationKey = ["apiSocialPostsUpdate"];
  const { mutation: mutationOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey } };

  const mutationFn: MutationFunction<
    Awaited<ReturnType<typeof apiSocialPostsUpdate>>,
    { id: number; data: NonReadonly<Post> }
  > = (props) => {
    const { id, data } = props ?? {};

    return apiSocialPostsUpdate(id, data);
  };

  return { mutationFn, ...mutationOptions };
};

export type ApiSocialPostsUpdateMutationResult = NonNullable<
  Awaited<ReturnType<typeof apiSocialPostsUpdate>>
>;
export type ApiSocialPostsUpdateMutationBody = NonReadonly<Post>;
export type ApiSocialPostsUpdateMutationError = unknown;

/**
 * @summary Replace a post
 */
export const useApiSocialPostsUpdate = <TError = unknown, TContext = unknown>(
  options?: {
    mutation?: UseMutationOptions<
      Awaited<ReturnType<typeof apiSocialPostsUpdate>>,
      TError,
      { id: number; data: NonReadonly<Post> },
      TContext
    >;
  },
  queryClient?: QueryClient,
): UseMutationResult<
  Awaited<ReturnType<typeof apiSocialPostsUpdate>>,
  TError,
  { id: number; data: NonReadonly<Post> },
  TContext
> => {
  return useMutation(
    getApiSocialPostsUpdateMutationOptions(options),
    queryClient,
  );
};
/**
 * Partial update. Author only.
 * @summary Update a post
 */
export const apiSocialPostsPartialUpdate = (
  id: number,
  patchedPost: NonReadonly<PatchedPost>,
  signal?: AbortSignal,
) => {
  return privateMutator<Post>({
    url: `/api/social/posts/${id}/`,
    method: "PATCH",
    headers: { "Content-Type": "application/json" },
    data: patchedPost,
    signal,
  });
};

export const getApiSocialPostsPartialUpdateMutationOptions = <
  TError = unknown,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof apiSocialPostsPartialUpdate>>,
    TError,
    { id: number; data: NonReadonly<PatchedPost> },
    TContext
  >;
}): UseMutationOptions<
  Awaited<ReturnType<typeof apiSocialPostsPartialUpdate>>,
  TError,
  { id: number; data: NonReadonly<PatchedPost> },
  TContext
> => {
  const mutationKey = ["apiSocialPostsPartialUpdate"];
  const { mutation: mutationOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey } };

  const mutationFn: MutationFunction<
    Awaited<ReturnType<typeof apiSocialPostsPartialUpdate>>,
    { id: number; data: NonReadonly<PatchedPost> }
  > = (props) => {
    const { id, data } = props ?? {};

    return apiSocialPostsPartialUpdate(id, data);
  };

  return { mutationFn, ...mutationOptions };
};

export type ApiSocialPostsPartialUpdateMutationResult = NonNullable<
  Awaited<ReturnType<typeof apiSocialPostsPartialUpdate>>
>;
export type ApiSocialPostsPartialUpdateMutationBody = NonReadonly<PatchedPost>;
export type ApiSocialPostsPartialUpdateMutationError = unknown;

/**
 * @summary Update a post
 */
export const useApiSocialPostsPartialUpdate = <
  TError = unknown,
  TContext = unknown,
>(
  options?: {
    mutation?: UseMutationOptions<
      Awaited<ReturnType<typeof apiSocialPostsPartialUpdate>>,
      TError,
      { id: number; data: NonReadonly<PatchedPost> },
      TContext
    >;
  },
  queryClient?: QueryClient,
): UseMutationResult<
  Awaited<ReturnType<typeof apiSocialPostsPartialUpdate>>,
  TError,
  { id: number; data: NonReadonly<PatchedPost> },
  TContext
> => {
  return useMutation(
    getApiSocialPostsPartialUpdateMutationOptions(options),
    queryClient,
  );
};
/**
 * Soft-deletes the post. Author, superuser, hub owner, or hub moderator with `managing_posts`.
 * @summary Delete a post
 */
export const apiSocialPostsDestroy = (id: number, signal?: AbortSignal) => {
  return privateMutator<void>({
    url: `/api/social/posts/${id}/`,
    method: "DELETE",
    signal,
  });
};

export const getApiSocialPostsDestroyMutationOptions = <
  TError = unknown,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof apiSocialPostsDestroy>>,
    TError,
    { id: number },
    TContext
  >;
}): UseMutationOptions<
  Awaited<ReturnType<typeof apiSocialPostsDestroy>>,
  TError,
  { id: number },
  TContext
> => {
  const mutationKey = ["apiSocialPostsDestroy"];
  const { mutation: mutationOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey } };

  const mutationFn: MutationFunction<
    Awaited<ReturnType<typeof apiSocialPostsDestroy>>,
    { id: number }
  > = (props) => {
    const { id } = props ?? {};

    return apiSocialPostsDestroy(id);
  };

  return { mutationFn, ...mutationOptions };
};

export type ApiSocialPostsDestroyMutationResult = NonNullable<
  Awaited<ReturnType<typeof apiSocialPostsDestroy>>
>;

export type ApiSocialPostsDestroyMutationError = unknown;

/**
 * @summary Delete a post
 */
export const useApiSocialPostsDestroy = <TError = unknown, TContext = unknown>(
  options?: {
    mutation?: UseMutationOptions<
      Awaited<ReturnType<typeof apiSocialPostsDestroy>>,
      TError,
      { id: number },
      TContext
    >;
  },
  queryClient?: QueryClient,
): UseMutationResult<
  Awaited<ReturnType<typeof apiSocialPostsDestroy>>,
  TError,
  { id: number },
  TContext
> => {
  return useMutation(
    getApiSocialPostsDestroyMutationOptions(options),
    queryClient,
  );
};
/**
 * Attach an image or video file to a post. Only the post author can upload.
 * @summary Upload media to a post
 */
export const apiSocialPostsMediaCreate = (
  id: number,
  apiSocialPostsMediaCreateBody: ApiSocialPostsMediaCreateBody,
  signal?: AbortSignal,
) => {
  const formData = new FormData();
  formData.append(`file`, apiSocialPostsMediaCreateBody.file);

  return privateMutator<PostContent>({
    url: `/api/social/posts/${id}/media/`,
    method: "POST",
    data: formData,
    signal,
  });
};

export const getApiSocialPostsMediaCreateMutationOptions = <
  TError = unknown,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof apiSocialPostsMediaCreate>>,
    TError,
    { id: number; data: ApiSocialPostsMediaCreateBody },
    TContext
  >;
}): UseMutationOptions<
  Awaited<ReturnType<typeof apiSocialPostsMediaCreate>>,
  TError,
  { id: number; data: ApiSocialPostsMediaCreateBody },
  TContext
> => {
  const mutationKey = ["apiSocialPostsMediaCreate"];
  const { mutation: mutationOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey } };

  const mutationFn: MutationFunction<
    Awaited<ReturnType<typeof apiSocialPostsMediaCreate>>,
    { id: number; data: ApiSocialPostsMediaCreateBody }
  > = (props) => {
    const { id, data } = props ?? {};

    return apiSocialPostsMediaCreate(id, data);
  };

  return { mutationFn, ...mutationOptions };
};

export type ApiSocialPostsMediaCreateMutationResult = NonNullable<
  Awaited<ReturnType<typeof apiSocialPostsMediaCreate>>
>;
export type ApiSocialPostsMediaCreateMutationBody =
  ApiSocialPostsMediaCreateBody;
export type ApiSocialPostsMediaCreateMutationError = unknown;

/**
 * @summary Upload media to a post
 */
export const useApiSocialPostsMediaCreate = <
  TError = unknown,
  TContext = unknown,
>(
  options?: {
    mutation?: UseMutationOptions<
      Awaited<ReturnType<typeof apiSocialPostsMediaCreate>>,
      TError,
      { id: number; data: ApiSocialPostsMediaCreateBody },
      TContext
    >;
  },
  queryClient?: QueryClient,
): UseMutationResult<
  Awaited<ReturnType<typeof apiSocialPostsMediaCreate>>,
  TError,
  { id: number; data: ApiSocialPostsMediaCreateBody },
  TContext
> => {
  return useMutation(
    getApiSocialPostsMediaCreateMutationOptions(options),
    queryClient,
  );
};
/**
 * Saves the post for the current user, or unsaves it if already saved. Returns `{saved: true/false}`.
 * @summary Toggle save on a post
 */
export const apiSocialPostsSaveCreate = (
  id: number,
  post: NonReadonly<Post>,
  signal?: AbortSignal,
) => {
  return privateMutator<ApiSocialPostsSaveCreate200>({
    url: `/api/social/posts/${id}/save/`,
    method: "POST",
    headers: { "Content-Type": "application/json" },
    data: post,
    signal,
  });
};

export const getApiSocialPostsSaveCreateMutationOptions = <
  TError = unknown,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof apiSocialPostsSaveCreate>>,
    TError,
    { id: number; data: NonReadonly<Post> },
    TContext
  >;
}): UseMutationOptions<
  Awaited<ReturnType<typeof apiSocialPostsSaveCreate>>,
  TError,
  { id: number; data: NonReadonly<Post> },
  TContext
> => {
  const mutationKey = ["apiSocialPostsSaveCreate"];
  const { mutation: mutationOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey } };

  const mutationFn: MutationFunction<
    Awaited<ReturnType<typeof apiSocialPostsSaveCreate>>,
    { id: number; data: NonReadonly<Post> }
  > = (props) => {
    const { id, data } = props ?? {};

    return apiSocialPostsSaveCreate(id, data);
  };

  return { mutationFn, ...mutationOptions };
};

export type ApiSocialPostsSaveCreateMutationResult = NonNullable<
  Awaited<ReturnType<typeof apiSocialPostsSaveCreate>>
>;
export type ApiSocialPostsSaveCreateMutationBody = NonReadonly<Post>;
export type ApiSocialPostsSaveCreateMutationError = unknown;

/**
 * @summary Toggle save on a post
 */
export const useApiSocialPostsSaveCreate = <
  TError = unknown,
  TContext = unknown,
>(
  options?: {
    mutation?: UseMutationOptions<
      Awaited<ReturnType<typeof apiSocialPostsSaveCreate>>,
      TError,
      { id: number; data: NonReadonly<Post> },
      TContext
    >;
  },
  queryClient?: QueryClient,
): UseMutationResult<
  Awaited<ReturnType<typeof apiSocialPostsSaveCreate>>,
  TError,
  { id: number; data: NonReadonly<Post> },
  TContext
> => {
  return useMutation(
    getApiSocialPostsSaveCreateMutationOptions(options),
    queryClient,
  );
};
/**
 * Attaches an existing hub tag to the post. The tag must belong to the same hub as the post. Any authenticated hub member can attach tags.
 * @summary Attach a tag to a post
 */
export const apiSocialPostsTagsAttachCreate = (
  id: number,
  tagAttach: TagAttach,
  signal?: AbortSignal,
) => {
  return privateMutator<Post>({
    url: `/api/social/posts/${id}/tags/attach/`,
    method: "POST",
    headers: { "Content-Type": "application/json" },
    data: tagAttach,
    signal,
  });
};

export const getApiSocialPostsTagsAttachCreateMutationOptions = <
  TError = unknown,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof apiSocialPostsTagsAttachCreate>>,
    TError,
    { id: number; data: TagAttach },
    TContext
  >;
}): UseMutationOptions<
  Awaited<ReturnType<typeof apiSocialPostsTagsAttachCreate>>,
  TError,
  { id: number; data: TagAttach },
  TContext
> => {
  const mutationKey = ["apiSocialPostsTagsAttachCreate"];
  const { mutation: mutationOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey } };

  const mutationFn: MutationFunction<
    Awaited<ReturnType<typeof apiSocialPostsTagsAttachCreate>>,
    { id: number; data: TagAttach }
  > = (props) => {
    const { id, data } = props ?? {};

    return apiSocialPostsTagsAttachCreate(id, data);
  };

  return { mutationFn, ...mutationOptions };
};

export type ApiSocialPostsTagsAttachCreateMutationResult = NonNullable<
  Awaited<ReturnType<typeof apiSocialPostsTagsAttachCreate>>
>;
export type ApiSocialPostsTagsAttachCreateMutationBody = TagAttach;
export type ApiSocialPostsTagsAttachCreateMutationError = unknown;

/**
 * @summary Attach a tag to a post
 */
export const useApiSocialPostsTagsAttachCreate = <
  TError = unknown,
  TContext = unknown,
>(
  options?: {
    mutation?: UseMutationOptions<
      Awaited<ReturnType<typeof apiSocialPostsTagsAttachCreate>>,
      TError,
      { id: number; data: TagAttach },
      TContext
    >;
  },
  queryClient?: QueryClient,
): UseMutationResult<
  Awaited<ReturnType<typeof apiSocialPostsTagsAttachCreate>>,
  TError,
  { id: number; data: TagAttach },
  TContext
> => {
  return useMutation(
    getApiSocialPostsTagsAttachCreateMutationOptions(options),
    queryClient,
  );
};
/**
 * Removes a tag from the post. Post author, hub owner, site admin, or moderator with `managing_posts` can detach.
 * @summary Detach a tag from a post
 */
export const apiSocialPostsTagsDetachCreate = (
  id: number,
  tagAttach: TagAttach,
  signal?: AbortSignal,
) => {
  return privateMutator<Post>({
    url: `/api/social/posts/${id}/tags/detach/`,
    method: "POST",
    headers: { "Content-Type": "application/json" },
    data: tagAttach,
    signal,
  });
};

export const getApiSocialPostsTagsDetachCreateMutationOptions = <
  TError = unknown,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof apiSocialPostsTagsDetachCreate>>,
    TError,
    { id: number; data: TagAttach },
    TContext
  >;
}): UseMutationOptions<
  Awaited<ReturnType<typeof apiSocialPostsTagsDetachCreate>>,
  TError,
  { id: number; data: TagAttach },
  TContext
> => {
  const mutationKey = ["apiSocialPostsTagsDetachCreate"];
  const { mutation: mutationOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey } };

  const mutationFn: MutationFunction<
    Awaited<ReturnType<typeof apiSocialPostsTagsDetachCreate>>,
    { id: number; data: TagAttach }
  > = (props) => {
    const { id, data } = props ?? {};

    return apiSocialPostsTagsDetachCreate(id, data);
  };

  return { mutationFn, ...mutationOptions };
};

export type ApiSocialPostsTagsDetachCreateMutationResult = NonNullable<
  Awaited<ReturnType<typeof apiSocialPostsTagsDetachCreate>>
>;
export type ApiSocialPostsTagsDetachCreateMutationBody = TagAttach;
export type ApiSocialPostsTagsDetachCreateMutationError = unknown;

/**
 * @summary Detach a tag from a post
 */
export const useApiSocialPostsTagsDetachCreate = <
  TError = unknown,
  TContext = unknown,
>(
  options?: {
    mutation?: UseMutationOptions<
      Awaited<ReturnType<typeof apiSocialPostsTagsDetachCreate>>,
      TError,
      { id: number; data: TagAttach },
      TContext
    >;
  },
  queryClient?: QueryClient,
): UseMutationResult<
  Awaited<ReturnType<typeof apiSocialPostsTagsDetachCreate>>,
  TError,
  { id: number; data: TagAttach },
  TContext
> => {
  return useMutation(
    getApiSocialPostsTagsDetachCreateMutationOptions(options),
    queryClient,
  );
};
/**
 * Cast or update a vote (`1` = upvote, `-1` = downvote) on a post.
 * @summary Vote on a post
 */
export const apiSocialPostsVoteCreate = (
  id: number,
  postVote: NonReadonly<PostVote>,
  signal?: AbortSignal,
) => {
  return privateMutator<PostVote>({
    url: `/api/social/posts/${id}/vote/`,
    method: "POST",
    headers: { "Content-Type": "application/json" },
    data: postVote,
    signal,
  });
};

export const getApiSocialPostsVoteCreateMutationOptions = <
  TError = unknown,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof apiSocialPostsVoteCreate>>,
    TError,
    { id: number; data: NonReadonly<PostVote> },
    TContext
  >;
}): UseMutationOptions<
  Awaited<ReturnType<typeof apiSocialPostsVoteCreate>>,
  TError,
  { id: number; data: NonReadonly<PostVote> },
  TContext
> => {
  const mutationKey = ["apiSocialPostsVoteCreate"];
  const { mutation: mutationOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey } };

  const mutationFn: MutationFunction<
    Awaited<ReturnType<typeof apiSocialPostsVoteCreate>>,
    { id: number; data: NonReadonly<PostVote> }
  > = (props) => {
    const { id, data } = props ?? {};

    return apiSocialPostsVoteCreate(id, data);
  };

  return { mutationFn, ...mutationOptions };
};

export type ApiSocialPostsVoteCreateMutationResult = NonNullable<
  Awaited<ReturnType<typeof apiSocialPostsVoteCreate>>
>;
export type ApiSocialPostsVoteCreateMutationBody = NonReadonly<PostVote>;
export type ApiSocialPostsVoteCreateMutationError = unknown;

/**
 * @summary Vote on a post
 */
export const useApiSocialPostsVoteCreate = <
  TError = unknown,
  TContext = unknown,
>(
  options?: {
    mutation?: UseMutationOptions<
      Awaited<ReturnType<typeof apiSocialPostsVoteCreate>>,
      TError,
      { id: number; data: NonReadonly<PostVote> },
      TContext
    >;
  },
  queryClient?: QueryClient,
): UseMutationResult<
  Awaited<ReturnType<typeof apiSocialPostsVoteCreate>>,
  TError,
  { id: number; data: NonReadonly<PostVote> },
  TContext
> => {
  return useMutation(
    getApiSocialPostsVoteCreateMutationOptions(options),
    queryClient,
  );
};
/**
 * Returns a cursor-paginated stream of top-level posts (excluding replies) aggregated from the user's joined hubs, public hubs, and hub-less posts. Pass `feed_strategy` to switch between ranking algorithms (currently only `recent` is implemented; reserved for future custom algorithms).
 * @summary Get the user's post feed
 */
export const apiSocialPostsFeedList = (
  params?: ApiSocialPostsFeedListParams,
  signal?: AbortSignal,
) => {
  return privateMutator<PaginatedPostList>({
    url: `/api/social/posts/feed/`,
    method: "GET",
    params,
    signal,
  });
};

export const getApiSocialPostsFeedListQueryKey = (
  params?: ApiSocialPostsFeedListParams,
) => {
  return [`/api/social/posts/feed/`, ...(params ? [params] : [])] as const;
};

export const getApiSocialPostsFeedListQueryOptions = <
  TData = Awaited<ReturnType<typeof apiSocialPostsFeedList>>,
  TError = unknown,
>(
  params?: ApiSocialPostsFeedListParams,
  options?: {
    query?: Partial<
      UseQueryOptions<
        Awaited<ReturnType<typeof apiSocialPostsFeedList>>,
        TError,
        TData
      >
    >;
  },
) => {
  const { query: queryOptions } = options ?? {};

  const queryKey =
    queryOptions?.queryKey ?? getApiSocialPostsFeedListQueryKey(params);

  const queryFn: QueryFunction<
    Awaited<ReturnType<typeof apiSocialPostsFeedList>>
  > = ({ signal }) => apiSocialPostsFeedList(params, signal);

  return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
    Awaited<ReturnType<typeof apiSocialPostsFeedList>>,
    TError,
    TData
  > & { queryKey: DataTag<QueryKey, TData, TError> };
};

export type ApiSocialPostsFeedListQueryResult = NonNullable<
  Awaited<ReturnType<typeof apiSocialPostsFeedList>>
>;
export type ApiSocialPostsFeedListQueryError = unknown;

export function useApiSocialPostsFeedList<
  TData = Awaited<ReturnType<typeof apiSocialPostsFeedList>>,
  TError = unknown,
>(
  params: undefined | ApiSocialPostsFeedListParams,
  options: {
    query: Partial<
      UseQueryOptions<
        Awaited<ReturnType<typeof apiSocialPostsFeedList>>,
        TError,
        TData
      >
    > &
      Pick<
        DefinedInitialDataOptions<
          Awaited<ReturnType<typeof apiSocialPostsFeedList>>,
          TError,
          Awaited<ReturnType<typeof apiSocialPostsFeedList>>
        >,
        "initialData"
      >;
  },
  queryClient?: QueryClient,
): DefinedUseQueryResult<TData, TError> & {
  queryKey: DataTag<QueryKey, TData, TError>;
};
export function useApiSocialPostsFeedList<
  TData = Awaited<ReturnType<typeof apiSocialPostsFeedList>>,
  TError = unknown,
>(
  params?: ApiSocialPostsFeedListParams,
  options?: {
    query?: Partial<
      UseQueryOptions<
        Awaited<ReturnType<typeof apiSocialPostsFeedList>>,
        TError,
        TData
      >
    > &
      Pick<
        UndefinedInitialDataOptions<
          Awaited<ReturnType<typeof apiSocialPostsFeedList>>,
          TError,
          Awaited<ReturnType<typeof apiSocialPostsFeedList>>
        >,
        "initialData"
      >;
  },
  queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
  queryKey: DataTag<QueryKey, TData, TError>;
};
export function useApiSocialPostsFeedList<
  TData = Awaited<ReturnType<typeof apiSocialPostsFeedList>>,
  TError = unknown,
>(
  params?: ApiSocialPostsFeedListParams,
  options?: {
    query?: Partial<
      UseQueryOptions<
        Awaited<ReturnType<typeof apiSocialPostsFeedList>>,
        TError,
        TData
      >
    >;
  },
  queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
  queryKey: DataTag<QueryKey, TData, TError>;
};
/**
 * @summary Get the user's post feed
 */

export function useApiSocialPostsFeedList<
  TData = Awaited<ReturnType<typeof apiSocialPostsFeedList>>,
  TError = unknown,
>(
  params?: ApiSocialPostsFeedListParams,
  options?: {
    query?: Partial<
      UseQueryOptions<
        Awaited<ReturnType<typeof apiSocialPostsFeedList>>,
        TError,
        TData
      >
    >;
  },
  queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
  queryKey: DataTag<QueryKey, TData, TError>;
} {
  const queryOptions = getApiSocialPostsFeedListQueryOptions(params, options);

  const query = useQuery(queryOptions, queryClient) as UseQueryResult<
    TData,
    TError
  > & { queryKey: DataTag<QueryKey, TData, TError> };

  return { ...query, queryKey: queryOptions.queryKey };
}

/**
 * @summary List posts saved by the current user
 */
export const apiSocialPostsSavedList = (
  params?: ApiSocialPostsSavedListParams,
  signal?: AbortSignal,
) => {
  return privateMutator<PaginatedPostList>({
    url: `/api/social/posts/saved/`,
    method: "GET",
    params,
    signal,
  });
};

export const getApiSocialPostsSavedListQueryKey = (
  params?: ApiSocialPostsSavedListParams,
) => {
  return [`/api/social/posts/saved/`, ...(params ? [params] : [])] as const;
};

export const getApiSocialPostsSavedListQueryOptions = <
  TData = Awaited<ReturnType<typeof apiSocialPostsSavedList>>,
  TError = unknown,
>(
  params?: ApiSocialPostsSavedListParams,
  options?: {
    query?: Partial<
      UseQueryOptions<
        Awaited<ReturnType<typeof apiSocialPostsSavedList>>,
        TError,
        TData
      >
    >;
  },
) => {
  const { query: queryOptions } = options ?? {};

  const queryKey =
    queryOptions?.queryKey ?? getApiSocialPostsSavedListQueryKey(params);

  const queryFn: QueryFunction<
    Awaited<ReturnType<typeof apiSocialPostsSavedList>>
  > = ({ signal }) => apiSocialPostsSavedList(params, signal);

  return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
    Awaited<ReturnType<typeof apiSocialPostsSavedList>>,
    TError,
    TData
  > & { queryKey: DataTag<QueryKey, TData, TError> };
};

export type ApiSocialPostsSavedListQueryResult = NonNullable<
  Awaited<ReturnType<typeof apiSocialPostsSavedList>>
>;
export type ApiSocialPostsSavedListQueryError = unknown;

export function useApiSocialPostsSavedList<
  TData = Awaited<ReturnType<typeof apiSocialPostsSavedList>>,
  TError = unknown,
>(
  params: undefined | ApiSocialPostsSavedListParams,
  options: {
    query: Partial<
      UseQueryOptions<
        Awaited<ReturnType<typeof apiSocialPostsSavedList>>,
        TError,
        TData
      >
    > &
      Pick<
        DefinedInitialDataOptions<
          Awaited<ReturnType<typeof apiSocialPostsSavedList>>,
          TError,
          Awaited<ReturnType<typeof apiSocialPostsSavedList>>
        >,
        "initialData"
      >;
  },
  queryClient?: QueryClient,
): DefinedUseQueryResult<TData, TError> & {
  queryKey: DataTag<QueryKey, TData, TError>;
};
export function useApiSocialPostsSavedList<
  TData = Awaited<ReturnType<typeof apiSocialPostsSavedList>>,
  TError = unknown,
>(
  params?: ApiSocialPostsSavedListParams,
  options?: {
    query?: Partial<
      UseQueryOptions<
        Awaited<ReturnType<typeof apiSocialPostsSavedList>>,
        TError,
        TData
      >
    > &
      Pick<
        UndefinedInitialDataOptions<
          Awaited<ReturnType<typeof apiSocialPostsSavedList>>,
          TError,
          Awaited<ReturnType<typeof apiSocialPostsSavedList>>
        >,
        "initialData"
      >;
  },
  queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
  queryKey: DataTag<QueryKey, TData, TError>;
};
export function useApiSocialPostsSavedList<
  TData = Awaited<ReturnType<typeof apiSocialPostsSavedList>>,
  TError = unknown,
>(
  params?: ApiSocialPostsSavedListParams,
  options?: {
    query?: Partial<
      UseQueryOptions<
        Awaited<ReturnType<typeof apiSocialPostsSavedList>>,
        TError,
        TData
      >
    >;
  },
  queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
  queryKey: DataTag<QueryKey, TData, TError>;
};
/**
 * @summary List posts saved by the current user
 */

export function useApiSocialPostsSavedList<
  TData = Awaited<ReturnType<typeof apiSocialPostsSavedList>>,
  TError = unknown,
>(
  params?: ApiSocialPostsSavedListParams,
  options?: {
    query?: Partial<
      UseQueryOptions<
        Awaited<ReturnType<typeof apiSocialPostsSavedList>>,
        TError,
        TData
      >
    >;
  },
  queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
  queryKey: DataTag<QueryKey, TData, TError>;
} {
  const queryOptions = getApiSocialPostsSavedListQueryOptions(params, options);

  const query = useQuery(queryOptions, queryClient) as UseQueryResult<
    TData,
    TError
  > & { queryKey: DataTag<QueryKey, TData, TError> };

  return { ...query, queryKey: queryOptions.queryKey };
}
