// This file is auto-generated by @hey-api/openapi-ts

import { type DefaultError, type InfiniteData, infiniteQueryOptions, type MutationOptions, queryOptions } from '@tanstack/solid-query';

import { client } from '../client.gen';
import { cancelBounty, clawbackEarning, createBounty, downloadSubmissionAttachment, fundBounty, getBounty, getBountyLeaderboard, getBountyStats, getBountySubmission, getDailyActivity, getLeaderboard, getMySubmission, getMyUserStats, getOverview, getUserStats, joinBounty, leaveBounty, listBounties, listBountyEarnings, listBountySubmissions, listMyEarnings, listOrganizationBounties, type Options, patchBounty, upsertMySubmission, withdrawMySubmission } from '../sdk.gen';
import type { CancelBountyData, CancelBountyResponse, ClawbackEarningData, ClawbackEarningResponse, CreateBountyData, CreateBountyResponse2, DownloadSubmissionAttachmentData, FundBountyData, FundBountyResponse2, GetBountyData, GetBountyLeaderboardData, GetBountyLeaderboardResponse, GetBountyResponse, GetBountyStatsData, GetBountyStatsResponse, GetBountySubmissionData, GetBountySubmissionResponse, GetDailyActivityData, GetDailyActivityResponse, GetLeaderboardData, GetLeaderboardResponse, GetMySubmissionData, GetMySubmissionResponse, GetMyUserStatsData, GetMyUserStatsResponse, GetOverviewData, GetOverviewResponse, GetUserStatsData, GetUserStatsResponse, JoinBountyData, JoinBountyResponse2, LeaveBountyData, LeaveBountyResponse, ListBountiesData, ListBountiesResponse, ListBountyEarningsData, ListBountyEarningsResponse, ListBountySubmissionsData, ListBountySubmissionsResponse, ListMyEarningsData, ListMyEarningsResponse, ListOrganizationBountiesData, ListOrganizationBountiesResponse, PatchBountyData, PatchBountyResponse, UpsertMySubmissionData, UpsertMySubmissionResponse, WithdrawMySubmissionData, WithdrawMySubmissionResponse } from '../types.gen';

export type QueryKey<TOptions extends Options> = [
    Pick<TOptions, 'baseUrl' | 'body' | 'headers' | 'path' | 'query'> & {
        _id: string;
        _infinite?: boolean;
        tags?: ReadonlyArray<string>;
    }
];

const createQueryKey = <TOptions extends Options>(id: string, options?: TOptions, infinite?: boolean, tags?: ReadonlyArray<string>): [
    QueryKey<TOptions>[0]
] => {
    const params: QueryKey<TOptions>[0] = { _id: id, baseUrl: options?.baseUrl || (options?.client ?? client).getConfig().baseUrl } as QueryKey<TOptions>[0];
    if (infinite) {
        params._infinite = infinite;
    }
    if (tags) {
        params.tags = tags;
    }
    if (options?.body) {
        params.body = options.body;
    }
    if (options?.headers) {
        params.headers = options.headers;
    }
    if (options?.path) {
        params.path = options.path;
    }
    if (options?.query) {
        params.query = options.query;
    }
    return [params];
};

export const listBountiesQueryKey = (options?: Options<ListBountiesData>) => createQueryKey('listBounties', options);

/**
 * `GET /bounties` — public bounty listing.
 *
 * This is unauthenticated and lists bounties across all organizations.
 * Customer-scoped listings (the caller's own org's bounties) live at
 * `GET /organizations/me/bounties` instead, so a single path never flips
 * semantics based on whether auth is present.
 */
export const listBountiesOptions = (options?: Options<ListBountiesData>) => queryOptions<ListBountiesResponse, DefaultError, ListBountiesResponse, ReturnType<typeof listBountiesQueryKey>>({
    queryFn: async ({ queryKey, signal }) => {
        const { data } = await listBounties({
            ...options,
            ...queryKey[0],
            signal,
            throwOnError: true
        });
        return data;
    },
    queryKey: listBountiesQueryKey(options)
});

const createInfiniteParams = <K extends Pick<QueryKey<Options>[0], 'body' | 'headers' | 'path' | 'query'>>(queryKey: QueryKey<Options>, page: K) => {
    const params = { ...queryKey[0] };
    if (page.body) {
        params.body = {
            ...queryKey[0].body as any,
            ...page.body as any
        };
    }
    if (page.headers) {
        params.headers = {
            ...queryKey[0].headers,
            ...page.headers
        };
    }
    if (page.path) {
        params.path = {
            ...queryKey[0].path as any,
            ...page.path as any
        };
    }
    if (page.query) {
        params.query = {
            ...queryKey[0].query as any,
            ...page.query as any
        };
    }
    return params as unknown as typeof page;
};

export const listBountiesInfiniteQueryKey = (options?: Options<ListBountiesData>): QueryKey<Options<ListBountiesData>> => createQueryKey('listBounties', options, true);

/**
 * `GET /bounties` — public bounty listing.
 *
 * This is unauthenticated and lists bounties across all organizations.
 * Customer-scoped listings (the caller's own org's bounties) live at
 * `GET /organizations/me/bounties` instead, so a single path never flips
 * semantics based on whether auth is present.
 */
export const listBountiesInfiniteOptions = (options?: Options<ListBountiesData>) => infiniteQueryOptions<ListBountiesResponse, DefaultError, InfiniteData<ListBountiesResponse>, QueryKey<Options<ListBountiesData>>, string | null | Pick<QueryKey<Options<ListBountiesData>>[0], 'body' | 'headers' | 'path' | 'query'>>(
// @ts-ignore
{
    queryFn: async ({ pageParam, queryKey, signal }) => {
        // @ts-ignore
        const page: Pick<QueryKey<Options<ListBountiesData>>[0], 'body' | 'headers' | 'path' | 'query'> = typeof pageParam === 'object' ? pageParam : {
            query: {
                cursor: pageParam
            }
        };
        const params = createInfiniteParams(queryKey, page);
        const { data } = await listBounties({
            ...options,
            ...params,
            signal,
            throwOnError: true
        });
        return data;
    },
    queryKey: listBountiesInfiniteQueryKey(options)
});

/**
 * `POST /bounties` — create a bounty + escrow hold.
 */
export const createBountyMutation = (options?: Partial<Options<CreateBountyData>>): MutationOptions<CreateBountyResponse2, DefaultError, Options<CreateBountyData>> => {
    const mutationOptions: MutationOptions<CreateBountyResponse2, DefaultError, Options<CreateBountyData>> = {
        mutationFn: async (fnOptions) => {
            const { data } = await createBounty({
                ...options,
                ...fnOptions,
                throwOnError: true
            });
            return data;
        }
    };
    return mutationOptions;
};

export const getBountyQueryKey = (options: Options<GetBountyData>) => createQueryKey('getBounty', options);

/**
 * `GET /bounties/{id}` — full bounty state.
 */
export const getBountyOptions = (options: Options<GetBountyData>) => queryOptions<GetBountyResponse, DefaultError, GetBountyResponse, ReturnType<typeof getBountyQueryKey>>({
    queryFn: async ({ queryKey, signal }) => {
        const { data } = await getBounty({
            ...options,
            ...queryKey[0],
            signal,
            throwOnError: true
        });
        return data;
    },
    queryKey: getBountyQueryKey(options)
});

/**
 * `PATCH /bounties/{id}` — edit tiers forward-only, extend deadline, top up.
 */
export const patchBountyMutation = (options?: Partial<Options<PatchBountyData>>): MutationOptions<PatchBountyResponse, DefaultError, Options<PatchBountyData>> => {
    const mutationOptions: MutationOptions<PatchBountyResponse, DefaultError, Options<PatchBountyData>> = {
        mutationFn: async (fnOptions) => {
            const { data } = await patchBounty({
                ...options,
                ...fnOptions,
                throwOnError: true
            });
            return data;
        }
    };
    return mutationOptions;
};

/**
 * `POST /bounties/{id}/cancel` — customer cancels and is refunded any
 * remaining escrow balance. Only legal when no earnings are un-released.
 */
export const cancelBountyMutation = (options?: Partial<Options<CancelBountyData>>): MutationOptions<CancelBountyResponse, DefaultError, Options<CancelBountyData>> => {
    const mutationOptions: MutationOptions<CancelBountyResponse, DefaultError, Options<CancelBountyData>> = {
        mutationFn: async (fnOptions) => {
            const { data } = await cancelBounty({
                ...options,
                ...fnOptions,
                throwOnError: true
            });
            return data;
        }
    };
    return mutationOptions;
};

export const listBountyEarningsQueryKey = (options: Options<ListBountyEarningsData>) => createQueryKey('listBountyEarnings', options);

/**
 * `GET /bounties/{id}/earnings` — paginated earnings ledger.
 */
export const listBountyEarningsOptions = (options: Options<ListBountyEarningsData>) => queryOptions<ListBountyEarningsResponse, DefaultError, ListBountyEarningsResponse, ReturnType<typeof listBountyEarningsQueryKey>>({
    queryFn: async ({ queryKey, signal }) => {
        const { data } = await listBountyEarnings({
            ...options,
            ...queryKey[0],
            signal,
            throwOnError: true
        });
        return data;
    },
    queryKey: listBountyEarningsQueryKey(options)
});

export const listBountyEarningsInfiniteQueryKey = (options: Options<ListBountyEarningsData>): QueryKey<Options<ListBountyEarningsData>> => createQueryKey('listBountyEarnings', options, true);

/**
 * `GET /bounties/{id}/earnings` — paginated earnings ledger.
 */
export const listBountyEarningsInfiniteOptions = (options: Options<ListBountyEarningsData>) => infiniteQueryOptions<ListBountyEarningsResponse, DefaultError, InfiniteData<ListBountyEarningsResponse>, QueryKey<Options<ListBountyEarningsData>>, string | null | Pick<QueryKey<Options<ListBountyEarningsData>>[0], 'body' | 'headers' | 'path' | 'query'>>(
// @ts-ignore
{
    queryFn: async ({ pageParam, queryKey, signal }) => {
        // @ts-ignore
        const page: Pick<QueryKey<Options<ListBountyEarningsData>>[0], 'body' | 'headers' | 'path' | 'query'> = typeof pageParam === 'object' ? pageParam : {
            query: {
                cursor: pageParam
            }
        };
        const params = createInfiniteParams(queryKey, page);
        const { data } = await listBountyEarnings({
            ...options,
            ...params,
            signal,
            throwOnError: true
        });
        return data;
    },
    queryKey: listBountyEarningsInfiniteQueryKey(options)
});

/**
 * `POST /bounties/{id}/earnings/{earning_id}/clawback` — customer claws back
 * an earning during the hold window. Earning flip + pool credit are atomic.
 */
export const clawbackEarningMutation = (options?: Partial<Options<ClawbackEarningData>>): MutationOptions<ClawbackEarningResponse, DefaultError, Options<ClawbackEarningData>> => {
    const mutationOptions: MutationOptions<ClawbackEarningResponse, DefaultError, Options<ClawbackEarningData>> = {
        mutationFn: async (fnOptions) => {
            const { data } = await clawbackEarning({
                ...options,
                ...fnOptions,
                throwOnError: true
            });
            return data;
        }
    };
    return mutationOptions;
};

/**
 * `POST /bounties/{id}/fund` — deposit SerenBucks into escrow.
 */
export const fundBountyMutation = (options?: Partial<Options<FundBountyData>>): MutationOptions<FundBountyResponse2, DefaultError, Options<FundBountyData>> => {
    const mutationOptions: MutationOptions<FundBountyResponse2, DefaultError, Options<FundBountyData>> = {
        mutationFn: async (fnOptions) => {
            const { data } = await fundBounty({
                ...options,
                ...fnOptions,
                throwOnError: true
            });
            return data;
        }
    };
    return mutationOptions;
};

/**
 * `DELETE /bounties/{id}/join` — leave. Already-accrued earnings still pay.
 */
export const leaveBountyMutation = (options?: Partial<Options<LeaveBountyData>>): MutationOptions<LeaveBountyResponse, DefaultError, Options<LeaveBountyData>> => {
    const mutationOptions: MutationOptions<LeaveBountyResponse, DefaultError, Options<LeaveBountyData>> = {
        mutationFn: async (fnOptions) => {
            const { data } = await leaveBounty({
                ...options,
                ...fnOptions,
                throwOnError: true
            });
            return data;
        }
    };
    return mutationOptions;
};

/**
 * `POST /bounties/{id}/join` — idempotent. Returns a `referral_code` the
 * agent uses to attribute downstream events to themselves.
 */
export const joinBountyMutation = (options?: Partial<Options<JoinBountyData>>): MutationOptions<JoinBountyResponse2, DefaultError, Options<JoinBountyData>> => {
    const mutationOptions: MutationOptions<JoinBountyResponse2, DefaultError, Options<JoinBountyData>> = {
        mutationFn: async (fnOptions) => {
            const { data } = await joinBounty({
                ...options,
                ...fnOptions,
                throwOnError: true
            });
            return data;
        }
    };
    return mutationOptions;
};

export const getBountyLeaderboardQueryKey = (options: Options<GetBountyLeaderboardData>) => createQueryKey('getBountyLeaderboard', options);

/**
 * `GET /bounties/{id}/leaderboard` — top earners in this bounty.
 */
export const getBountyLeaderboardOptions = (options: Options<GetBountyLeaderboardData>) => queryOptions<GetBountyLeaderboardResponse, DefaultError, GetBountyLeaderboardResponse, ReturnType<typeof getBountyLeaderboardQueryKey>>({
    queryFn: async ({ queryKey, signal }) => {
        const { data } = await getBountyLeaderboard({
            ...options,
            ...queryKey[0],
            signal,
            throwOnError: true
        });
        return data;
    },
    queryKey: getBountyLeaderboardQueryKey(options)
});

export const getBountyLeaderboardInfiniteQueryKey = (options: Options<GetBountyLeaderboardData>): QueryKey<Options<GetBountyLeaderboardData>> => createQueryKey('getBountyLeaderboard', options, true);

/**
 * `GET /bounties/{id}/leaderboard` — top earners in this bounty.
 */
export const getBountyLeaderboardInfiniteOptions = (options: Options<GetBountyLeaderboardData>) => infiniteQueryOptions<GetBountyLeaderboardResponse, DefaultError, InfiniteData<GetBountyLeaderboardResponse>, QueryKey<Options<GetBountyLeaderboardData>>, number | null | Pick<QueryKey<Options<GetBountyLeaderboardData>>[0], 'body' | 'headers' | 'path' | 'query'>>(
// @ts-ignore
{
    queryFn: async ({ pageParam, queryKey, signal }) => {
        // @ts-ignore
        const page: Pick<QueryKey<Options<GetBountyLeaderboardData>>[0], 'body' | 'headers' | 'path' | 'query'> = typeof pageParam === 'object' ? pageParam : {
            query: {
                offset: pageParam
            }
        };
        const params = createInfiniteParams(queryKey, page);
        const { data } = await getBountyLeaderboard({
            ...options,
            ...params,
            signal,
            throwOnError: true
        });
        return data;
    },
    queryKey: getBountyLeaderboardInfiniteQueryKey(options)
});

export const getBountyStatsQueryKey = (options: Options<GetBountyStatsData>) => createQueryKey('getBountyStats', options);

/**
 * `GET /bounties/{id}/stats` — public rollup for a single bounty.
 */
export const getBountyStatsOptions = (options: Options<GetBountyStatsData>) => queryOptions<GetBountyStatsResponse, DefaultError, GetBountyStatsResponse, ReturnType<typeof getBountyStatsQueryKey>>({
    queryFn: async ({ queryKey, signal }) => {
        const { data } = await getBountyStats({
            ...options,
            ...queryKey[0],
            signal,
            throwOnError: true
        });
        return data;
    },
    queryKey: getBountyStatsQueryKey(options)
});

/**
 * `DELETE /bounties/{id}/submission` — withdraw the caller's submission.
 */
export const withdrawMySubmissionMutation = (options?: Partial<Options<WithdrawMySubmissionData>>): MutationOptions<WithdrawMySubmissionResponse, DefaultError, Options<WithdrawMySubmissionData>> => {
    const mutationOptions: MutationOptions<WithdrawMySubmissionResponse, DefaultError, Options<WithdrawMySubmissionData>> = {
        mutationFn: async (fnOptions) => {
            const { data } = await withdrawMySubmission({
                ...options,
                ...fnOptions,
                throwOnError: true
            });
            return data;
        }
    };
    return mutationOptions;
};

export const getMySubmissionQueryKey = (options: Options<GetMySubmissionData>) => createQueryKey('getMySubmission', options);

/**
 * `GET /bounties/{id}/submission` — fetch the caller's submission.
 */
export const getMySubmissionOptions = (options: Options<GetMySubmissionData>) => queryOptions<GetMySubmissionResponse, DefaultError, GetMySubmissionResponse, ReturnType<typeof getMySubmissionQueryKey>>({
    queryFn: async ({ queryKey, signal }) => {
        const { data } = await getMySubmission({
            ...options,
            ...queryKey[0],
            signal,
            throwOnError: true
        });
        return data;
    },
    queryKey: getMySubmissionQueryKey(options)
});

/**
 * `POST /bounties/{id}/submission` — create or replace the caller's submission.
 */
export const upsertMySubmissionMutation = (options?: Partial<Options<UpsertMySubmissionData>>): MutationOptions<UpsertMySubmissionResponse, DefaultError, Options<UpsertMySubmissionData>> => {
    const mutationOptions: MutationOptions<UpsertMySubmissionResponse, DefaultError, Options<UpsertMySubmissionData>> = {
        mutationFn: async (fnOptions) => {
            const { data } = await upsertMySubmission({
                ...options,
                ...fnOptions,
                throwOnError: true
            });
            return data;
        }
    };
    return mutationOptions;
};

export const listBountySubmissionsQueryKey = (options: Options<ListBountySubmissionsData>) => createQueryKey('listBountySubmissions', options);

/**
 * `GET /bounties/{id}/submissions` — owner/operator list view for a bounty.
 */
export const listBountySubmissionsOptions = (options: Options<ListBountySubmissionsData>) => queryOptions<ListBountySubmissionsResponse, DefaultError, ListBountySubmissionsResponse, ReturnType<typeof listBountySubmissionsQueryKey>>({
    queryFn: async ({ queryKey, signal }) => {
        const { data } = await listBountySubmissions({
            ...options,
            ...queryKey[0],
            signal,
            throwOnError: true
        });
        return data;
    },
    queryKey: listBountySubmissionsQueryKey(options)
});

export const getBountySubmissionQueryKey = (options: Options<GetBountySubmissionData>) => createQueryKey('getBountySubmission', options);

/**
 * `GET /bounties/{id}/submissions/{submission_id}` — detail for owner/operator or submitter.
 */
export const getBountySubmissionOptions = (options: Options<GetBountySubmissionData>) => queryOptions<GetBountySubmissionResponse, DefaultError, GetBountySubmissionResponse, ReturnType<typeof getBountySubmissionQueryKey>>({
    queryFn: async ({ queryKey, signal }) => {
        const { data } = await getBountySubmission({
            ...options,
            ...queryKey[0],
            signal,
            throwOnError: true
        });
        return data;
    },
    queryKey: getBountySubmissionQueryKey(options)
});

export const downloadSubmissionAttachmentQueryKey = (options: Options<DownloadSubmissionAttachmentData>) => createQueryKey('downloadSubmissionAttachment', options);

/**
 * `GET /bounties/{id}/submissions/{submission_id}/attachment` — download the submission attachment.
 */
export const downloadSubmissionAttachmentOptions = (options: Options<DownloadSubmissionAttachmentData>) => queryOptions<unknown, DefaultError, unknown, ReturnType<typeof downloadSubmissionAttachmentQueryKey>>({
    queryFn: async ({ queryKey, signal }) => {
        const { data } = await downloadSubmissionAttachment({
            ...options,
            ...queryKey[0],
            signal,
            throwOnError: true
        });
        return data;
    },
    queryKey: downloadSubmissionAttachmentQueryKey(options)
});

export const getLeaderboardQueryKey = (options?: Options<GetLeaderboardData>) => createQueryKey('getLeaderboard', options);

/**
 * `GET /leaderboard` — top earners across all bounties.
 */
export const getLeaderboardOptions = (options?: Options<GetLeaderboardData>) => queryOptions<GetLeaderboardResponse, DefaultError, GetLeaderboardResponse, ReturnType<typeof getLeaderboardQueryKey>>({
    queryFn: async ({ queryKey, signal }) => {
        const { data } = await getLeaderboard({
            ...options,
            ...queryKey[0],
            signal,
            throwOnError: true
        });
        return data;
    },
    queryKey: getLeaderboardQueryKey(options)
});

export const getLeaderboardInfiniteQueryKey = (options?: Options<GetLeaderboardData>): QueryKey<Options<GetLeaderboardData>> => createQueryKey('getLeaderboard', options, true);

/**
 * `GET /leaderboard` — top earners across all bounties.
 */
export const getLeaderboardInfiniteOptions = (options?: Options<GetLeaderboardData>) => infiniteQueryOptions<GetLeaderboardResponse, DefaultError, InfiniteData<GetLeaderboardResponse>, QueryKey<Options<GetLeaderboardData>>, number | null | Pick<QueryKey<Options<GetLeaderboardData>>[0], 'body' | 'headers' | 'path' | 'query'>>(
// @ts-ignore
{
    queryFn: async ({ pageParam, queryKey, signal }) => {
        // @ts-ignore
        const page: Pick<QueryKey<Options<GetLeaderboardData>>[0], 'body' | 'headers' | 'path' | 'query'> = typeof pageParam === 'object' ? pageParam : {
            query: {
                offset: pageParam
            }
        };
        const params = createInfiniteParams(queryKey, page);
        const { data } = await getLeaderboard({
            ...options,
            ...params,
            signal,
            throwOnError: true
        });
        return data;
    },
    queryKey: getLeaderboardInfiniteQueryKey(options)
});

export const listOrganizationBountiesQueryKey = (options?: Options<ListOrganizationBountiesData>) => createQueryKey('listOrganizationBounties', options);

/**
 * `GET /bounties` — list bounties in the caller's organization.
 */
export const listOrganizationBountiesOptions = (options?: Options<ListOrganizationBountiesData>) => queryOptions<ListOrganizationBountiesResponse, DefaultError, ListOrganizationBountiesResponse, ReturnType<typeof listOrganizationBountiesQueryKey>>({
    queryFn: async ({ queryKey, signal }) => {
        const { data } = await listOrganizationBounties({
            ...options,
            ...queryKey[0],
            signal,
            throwOnError: true
        });
        return data;
    },
    queryKey: listOrganizationBountiesQueryKey(options)
});

export const listOrganizationBountiesInfiniteQueryKey = (options?: Options<ListOrganizationBountiesData>): QueryKey<Options<ListOrganizationBountiesData>> => createQueryKey('listOrganizationBounties', options, true);

/**
 * `GET /bounties` — list bounties in the caller's organization.
 */
export const listOrganizationBountiesInfiniteOptions = (options?: Options<ListOrganizationBountiesData>) => infiniteQueryOptions<ListOrganizationBountiesResponse, DefaultError, InfiniteData<ListOrganizationBountiesResponse>, QueryKey<Options<ListOrganizationBountiesData>>, string | null | Pick<QueryKey<Options<ListOrganizationBountiesData>>[0], 'body' | 'headers' | 'path' | 'query'>>(
// @ts-ignore
{
    queryFn: async ({ pageParam, queryKey, signal }) => {
        // @ts-ignore
        const page: Pick<QueryKey<Options<ListOrganizationBountiesData>>[0], 'body' | 'headers' | 'path' | 'query'> = typeof pageParam === 'object' ? pageParam : {
            query: {
                cursor: pageParam
            }
        };
        const params = createInfiniteParams(queryKey, page);
        const { data } = await listOrganizationBounties({
            ...options,
            ...params,
            signal,
            throwOnError: true
        });
        return data;
    },
    queryKey: listOrganizationBountiesInfiniteQueryKey(options)
});

export const getOverviewQueryKey = (options?: Options<GetOverviewData>) => createQueryKey('getOverview', options);

/**
 * `GET /overview` — platform-wide rollup.
 */
export const getOverviewOptions = (options?: Options<GetOverviewData>) => queryOptions<GetOverviewResponse, DefaultError, GetOverviewResponse, ReturnType<typeof getOverviewQueryKey>>({
    queryFn: async ({ queryKey, signal }) => {
        const { data } = await getOverview({
            ...options,
            ...queryKey[0],
            signal,
            throwOnError: true
        });
        return data;
    },
    queryKey: getOverviewQueryKey(options)
});

export const getDailyActivityQueryKey = (options?: Options<GetDailyActivityData>) => createQueryKey('getDailyActivity', options);

/**
 * `GET /stats/daily` — daily accrual and payout activity.
 */
export const getDailyActivityOptions = (options?: Options<GetDailyActivityData>) => queryOptions<GetDailyActivityResponse, DefaultError, GetDailyActivityResponse, ReturnType<typeof getDailyActivityQueryKey>>({
    queryFn: async ({ queryKey, signal }) => {
        const { data } = await getDailyActivity({
            ...options,
            ...queryKey[0],
            signal,
            throwOnError: true
        });
        return data;
    },
    queryKey: getDailyActivityQueryKey(options)
});

export const listMyEarningsQueryKey = (options?: Options<ListMyEarningsData>) => createQueryKey('listMyEarnings', options);

/**
 * `GET /users/me/earnings` — cross-bounty earnings ledger for the caller.
 */
export const listMyEarningsOptions = (options?: Options<ListMyEarningsData>) => queryOptions<ListMyEarningsResponse, DefaultError, ListMyEarningsResponse, ReturnType<typeof listMyEarningsQueryKey>>({
    queryFn: async ({ queryKey, signal }) => {
        const { data } = await listMyEarnings({
            ...options,
            ...queryKey[0],
            signal,
            throwOnError: true
        });
        return data;
    },
    queryKey: listMyEarningsQueryKey(options)
});

export const getMyUserStatsQueryKey = (options?: Options<GetMyUserStatsData>) => createQueryKey('getMyUserStats', options);

/**
 * `GET /users/me/stats` — rollup for the authenticated caller.
 */
export const getMyUserStatsOptions = (options?: Options<GetMyUserStatsData>) => queryOptions<GetMyUserStatsResponse, DefaultError, GetMyUserStatsResponse, ReturnType<typeof getMyUserStatsQueryKey>>({
    queryFn: async ({ queryKey, signal }) => {
        const { data } = await getMyUserStats({
            ...options,
            ...queryKey[0],
            signal,
            throwOnError: true
        });
        return data;
    },
    queryKey: getMyUserStatsQueryKey(options)
});

export const getUserStatsQueryKey = (options: Options<GetUserStatsData>) => createQueryKey('getUserStats', options);

/**
 * `GET /users/{user_id}/stats` — public rollup for any user.
 */
export const getUserStatsOptions = (options: Options<GetUserStatsData>) => queryOptions<GetUserStatsResponse, DefaultError, GetUserStatsResponse, ReturnType<typeof getUserStatsQueryKey>>({
    queryFn: async ({ queryKey, signal }) => {
        const { data } = await getUserStats({
            ...options,
            ...queryKey[0],
            signal,
            throwOnError: true
        });
        return data;
    },
    queryKey: getUserStatsQueryKey(options)
});
