/**
 * Generated by orval v8.5.3 🍺
 * Do not edit manually.
 * Api
 * CDACC Learning Plan AI API specification
 * OpenAPI spec version: 0.1.0
 */
import { useMutation, useQuery } from "@tanstack/react-query";
import type {
  MutationFunction,
  QueryFunction,
  QueryKey,
  UseMutationOptions,
  UseMutationResult,
  UseQueryOptions,
  UseQueryResult,
} from "@tanstack/react-query";

import type {
  Approval,
  ApprovalInput,
  BatchGenerateResult,
  Comment,
  CommentInput,
  DashboardStats,
  Department,
  DepartmentInput,
  DepartmentUpdate,
  Document,
  ExportRequest,
  ExportResult,
  GeneratePlanRequest,
  GeneratePlanResult,
  GenerateSessionPlanRequest,
  HealthStatus,
  Institution,
  InstitutionInput,
  InstitutionUpdate,
  ListDepartmentsParams,
  ListDocumentsParams,
  ListPlansParams,
  ListTemplatesParams,
  Plan,
  PlanDetail,
  PlanInput,
  PlanUpdate,
  RegenerateSectionRequest,
  SessionPlan,
  SessionRow,
  SessionRowInput,
  SessionRowUpdate,
  StatusCount,
  Template,
  TemplateInput,
  TemplateUpdate,
  Timetable,
  TimetableInput,
  TimetableSchedule,
  UpdateSessionPlanRequest,
  UserProfile,
  UserProfileUpdate,
} from "./api.schemas";

import { customFetch } from "../custom-fetch";
import type { ErrorType, BodyType } from "../custom-fetch";

type AwaitedInput<T> = PromiseLike<T> | T;

type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;

type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];

/**
 * @summary Health check
 */
export const getHealthCheckUrl = () => {
  return `/api/healthz`;
};

export const healthCheck = async (
  options?: RequestInit,
): Promise<HealthStatus> => {
  return customFetch<HealthStatus>(getHealthCheckUrl(), {
    ...options,
    method: "GET",
  });
};

export const getHealthCheckQueryKey = () => {
  return [`/api/healthz`] as const;
};

export const getHealthCheckQueryOptions = <
  TData = Awaited<ReturnType<typeof healthCheck>>,
  TError = ErrorType<unknown>,
>(options?: {
  query?: UseQueryOptions<
    Awaited<ReturnType<typeof healthCheck>>,
    TError,
    TData
  >;
  request?: SecondParameter<typeof customFetch>;
}) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

  const queryKey = queryOptions?.queryKey ?? getHealthCheckQueryKey();

  const queryFn: QueryFunction<Awaited<ReturnType<typeof healthCheck>>> = ({
    signal,
  }) => healthCheck({ signal, ...requestOptions });

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

export type HealthCheckQueryResult = NonNullable<
  Awaited<ReturnType<typeof healthCheck>>
>;
export type HealthCheckQueryError = ErrorType<unknown>;

/**
 * @summary Health check
 */

export function useHealthCheck<
  TData = Awaited<ReturnType<typeof healthCheck>>,
  TError = ErrorType<unknown>,
>(options?: {
  query?: UseQueryOptions<
    Awaited<ReturnType<typeof healthCheck>>,
    TError,
    TData
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
  const queryOptions = getHealthCheckQueryOptions(options);

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

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

/**
 * @summary Get current user profile
 */
export const getGetProfileUrl = () => {
  return `/api/profile`;
};

export const getProfile = async (
  options?: RequestInit,
): Promise<UserProfile> => {
  return customFetch<UserProfile>(getGetProfileUrl(), {
    ...options,
    method: "GET",
  });
};

export const getGetProfileQueryKey = () => {
  return [`/api/profile`] as const;
};

export const getGetProfileQueryOptions = <
  TData = Awaited<ReturnType<typeof getProfile>>,
  TError = ErrorType<void>,
>(options?: {
  query?: UseQueryOptions<
    Awaited<ReturnType<typeof getProfile>>,
    TError,
    TData
  >;
  request?: SecondParameter<typeof customFetch>;
}) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

  const queryKey = queryOptions?.queryKey ?? getGetProfileQueryKey();

  const queryFn: QueryFunction<Awaited<ReturnType<typeof getProfile>>> = ({
    signal,
  }) => getProfile({ signal, ...requestOptions });

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

export type GetProfileQueryResult = NonNullable<
  Awaited<ReturnType<typeof getProfile>>
>;
export type GetProfileQueryError = ErrorType<void>;

/**
 * @summary Get current user profile
 */

export function useGetProfile<
  TData = Awaited<ReturnType<typeof getProfile>>,
  TError = ErrorType<void>,
>(options?: {
  query?: UseQueryOptions<
    Awaited<ReturnType<typeof getProfile>>,
    TError,
    TData
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
  const queryOptions = getGetProfileQueryOptions(options);

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

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

/**
 * @summary Update current user profile
 */
export const getUpdateProfileUrl = () => {
  return `/api/profile`;
};

export const updateProfile = async (
  userProfileUpdate: UserProfileUpdate,
  options?: RequestInit,
): Promise<UserProfile> => {
  return customFetch<UserProfile>(getUpdateProfileUrl(), {
    ...options,
    method: "PATCH",
    headers: { "Content-Type": "application/json", ...options?.headers },
    body: JSON.stringify(userProfileUpdate),
  });
};

export const getUpdateProfileMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof updateProfile>>,
    TError,
    { data: BodyType<UserProfileUpdate> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof updateProfile>>,
  TError,
  { data: BodyType<UserProfileUpdate> },
  TContext
> => {
  const mutationKey = ["updateProfile"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

  const mutationFn: MutationFunction<
    Awaited<ReturnType<typeof updateProfile>>,
    { data: BodyType<UserProfileUpdate> }
  > = (props) => {
    const { data } = props ?? {};

    return updateProfile(data, requestOptions);
  };

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

export type UpdateProfileMutationResult = NonNullable<
  Awaited<ReturnType<typeof updateProfile>>
>;
export type UpdateProfileMutationBody = BodyType<UserProfileUpdate>;
export type UpdateProfileMutationError = ErrorType<unknown>;

/**
 * @summary Update current user profile
 */
export const useUpdateProfile = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof updateProfile>>,
    TError,
    { data: BodyType<UserProfileUpdate> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof updateProfile>>,
  TError,
  { data: BodyType<UserProfileUpdate> },
  TContext
> => {
  return useMutation(getUpdateProfileMutationOptions(options));
};

/**
 * @summary List institutions
 */
export const getListInstitutionsUrl = () => {
  return `/api/institutions`;
};

export const listInstitutions = async (
  options?: RequestInit,
): Promise<Institution[]> => {
  return customFetch<Institution[]>(getListInstitutionsUrl(), {
    ...options,
    method: "GET",
  });
};

export const getListInstitutionsQueryKey = () => {
  return [`/api/institutions`] as const;
};

export const getListInstitutionsQueryOptions = <
  TData = Awaited<ReturnType<typeof listInstitutions>>,
  TError = ErrorType<unknown>,
>(options?: {
  query?: UseQueryOptions<
    Awaited<ReturnType<typeof listInstitutions>>,
    TError,
    TData
  >;
  request?: SecondParameter<typeof customFetch>;
}) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

  const queryKey = queryOptions?.queryKey ?? getListInstitutionsQueryKey();

  const queryFn: QueryFunction<
    Awaited<ReturnType<typeof listInstitutions>>
  > = ({ signal }) => listInstitutions({ signal, ...requestOptions });

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

export type ListInstitutionsQueryResult = NonNullable<
  Awaited<ReturnType<typeof listInstitutions>>
>;
export type ListInstitutionsQueryError = ErrorType<unknown>;

/**
 * @summary List institutions
 */

export function useListInstitutions<
  TData = Awaited<ReturnType<typeof listInstitutions>>,
  TError = ErrorType<unknown>,
>(options?: {
  query?: UseQueryOptions<
    Awaited<ReturnType<typeof listInstitutions>>,
    TError,
    TData
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
  const queryOptions = getListInstitutionsQueryOptions(options);

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

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

/**
 * @summary Create institution
 */
export const getCreateInstitutionUrl = () => {
  return `/api/institutions`;
};

export const createInstitution = async (
  institutionInput: InstitutionInput,
  options?: RequestInit,
): Promise<Institution> => {
  return customFetch<Institution>(getCreateInstitutionUrl(), {
    ...options,
    method: "POST",
    headers: { "Content-Type": "application/json", ...options?.headers },
    body: JSON.stringify(institutionInput),
  });
};

export const getCreateInstitutionMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof createInstitution>>,
    TError,
    { data: BodyType<InstitutionInput> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof createInstitution>>,
  TError,
  { data: BodyType<InstitutionInput> },
  TContext
> => {
  const mutationKey = ["createInstitution"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

  const mutationFn: MutationFunction<
    Awaited<ReturnType<typeof createInstitution>>,
    { data: BodyType<InstitutionInput> }
  > = (props) => {
    const { data } = props ?? {};

    return createInstitution(data, requestOptions);
  };

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

export type CreateInstitutionMutationResult = NonNullable<
  Awaited<ReturnType<typeof createInstitution>>
>;
export type CreateInstitutionMutationBody = BodyType<InstitutionInput>;
export type CreateInstitutionMutationError = ErrorType<unknown>;

/**
 * @summary Create institution
 */
export const useCreateInstitution = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof createInstitution>>,
    TError,
    { data: BodyType<InstitutionInput> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof createInstitution>>,
  TError,
  { data: BodyType<InstitutionInput> },
  TContext
> => {
  return useMutation(getCreateInstitutionMutationOptions(options));
};

/**
 * @summary Get institution
 */
export const getGetInstitutionUrl = (id: number) => {
  return `/api/institutions/${id}`;
};

export const getInstitution = async (
  id: number,
  options?: RequestInit,
): Promise<Institution> => {
  return customFetch<Institution>(getGetInstitutionUrl(id), {
    ...options,
    method: "GET",
  });
};

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

export const getGetInstitutionQueryOptions = <
  TData = Awaited<ReturnType<typeof getInstitution>>,
  TError = ErrorType<void>,
>(
  id: number,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof getInstitution>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

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

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

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

export type GetInstitutionQueryResult = NonNullable<
  Awaited<ReturnType<typeof getInstitution>>
>;
export type GetInstitutionQueryError = ErrorType<void>;

/**
 * @summary Get institution
 */

export function useGetInstitution<
  TData = Awaited<ReturnType<typeof getInstitution>>,
  TError = ErrorType<void>,
>(
  id: number,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof getInstitution>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
  const queryOptions = getGetInstitutionQueryOptions(id, options);

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

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

/**
 * @summary Update institution
 */
export const getUpdateInstitutionUrl = (id: number) => {
  return `/api/institutions/${id}`;
};

export const updateInstitution = async (
  id: number,
  institutionUpdate: InstitutionUpdate,
  options?: RequestInit,
): Promise<Institution> => {
  return customFetch<Institution>(getUpdateInstitutionUrl(id), {
    ...options,
    method: "PATCH",
    headers: { "Content-Type": "application/json", ...options?.headers },
    body: JSON.stringify(institutionUpdate),
  });
};

export const getUpdateInstitutionMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof updateInstitution>>,
    TError,
    { id: number; data: BodyType<InstitutionUpdate> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof updateInstitution>>,
  TError,
  { id: number; data: BodyType<InstitutionUpdate> },
  TContext
> => {
  const mutationKey = ["updateInstitution"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

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

    return updateInstitution(id, data, requestOptions);
  };

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

export type UpdateInstitutionMutationResult = NonNullable<
  Awaited<ReturnType<typeof updateInstitution>>
>;
export type UpdateInstitutionMutationBody = BodyType<InstitutionUpdate>;
export type UpdateInstitutionMutationError = ErrorType<unknown>;

/**
 * @summary Update institution
 */
export const useUpdateInstitution = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof updateInstitution>>,
    TError,
    { id: number; data: BodyType<InstitutionUpdate> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof updateInstitution>>,
  TError,
  { id: number; data: BodyType<InstitutionUpdate> },
  TContext
> => {
  return useMutation(getUpdateInstitutionMutationOptions(options));
};

/**
 * @summary List departments
 */
export const getListDepartmentsUrl = (params?: ListDepartmentsParams) => {
  const normalizedParams = new URLSearchParams();

  Object.entries(params || {}).forEach(([key, value]) => {
    if (value !== undefined) {
      normalizedParams.append(key, value === null ? "null" : value.toString());
    }
  });

  const stringifiedParams = normalizedParams.toString();

  return stringifiedParams.length > 0
    ? `/api/departments?${stringifiedParams}`
    : `/api/departments`;
};

export const listDepartments = async (
  params?: ListDepartmentsParams,
  options?: RequestInit,
): Promise<Department[]> => {
  return customFetch<Department[]>(getListDepartmentsUrl(params), {
    ...options,
    method: "GET",
  });
};

export const getListDepartmentsQueryKey = (params?: ListDepartmentsParams) => {
  return [`/api/departments`, ...(params ? [params] : [])] as const;
};

export const getListDepartmentsQueryOptions = <
  TData = Awaited<ReturnType<typeof listDepartments>>,
  TError = ErrorType<unknown>,
>(
  params?: ListDepartmentsParams,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof listDepartments>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

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

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

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

export type ListDepartmentsQueryResult = NonNullable<
  Awaited<ReturnType<typeof listDepartments>>
>;
export type ListDepartmentsQueryError = ErrorType<unknown>;

/**
 * @summary List departments
 */

export function useListDepartments<
  TData = Awaited<ReturnType<typeof listDepartments>>,
  TError = ErrorType<unknown>,
>(
  params?: ListDepartmentsParams,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof listDepartments>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
  const queryOptions = getListDepartmentsQueryOptions(params, options);

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

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

/**
 * @summary Create department
 */
export const getCreateDepartmentUrl = () => {
  return `/api/departments`;
};

export const createDepartment = async (
  departmentInput: DepartmentInput,
  options?: RequestInit,
): Promise<Department> => {
  return customFetch<Department>(getCreateDepartmentUrl(), {
    ...options,
    method: "POST",
    headers: { "Content-Type": "application/json", ...options?.headers },
    body: JSON.stringify(departmentInput),
  });
};

export const getCreateDepartmentMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof createDepartment>>,
    TError,
    { data: BodyType<DepartmentInput> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof createDepartment>>,
  TError,
  { data: BodyType<DepartmentInput> },
  TContext
> => {
  const mutationKey = ["createDepartment"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

  const mutationFn: MutationFunction<
    Awaited<ReturnType<typeof createDepartment>>,
    { data: BodyType<DepartmentInput> }
  > = (props) => {
    const { data } = props ?? {};

    return createDepartment(data, requestOptions);
  };

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

export type CreateDepartmentMutationResult = NonNullable<
  Awaited<ReturnType<typeof createDepartment>>
>;
export type CreateDepartmentMutationBody = BodyType<DepartmentInput>;
export type CreateDepartmentMutationError = ErrorType<unknown>;

/**
 * @summary Create department
 */
export const useCreateDepartment = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof createDepartment>>,
    TError,
    { data: BodyType<DepartmentInput> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof createDepartment>>,
  TError,
  { data: BodyType<DepartmentInput> },
  TContext
> => {
  return useMutation(getCreateDepartmentMutationOptions(options));
};

/**
 * @summary Update department
 */
export const getUpdateDepartmentUrl = (id: number) => {
  return `/api/departments/${id}`;
};

export const updateDepartment = async (
  id: number,
  departmentUpdate: DepartmentUpdate,
  options?: RequestInit,
): Promise<Department> => {
  return customFetch<Department>(getUpdateDepartmentUrl(id), {
    ...options,
    method: "PATCH",
    headers: { "Content-Type": "application/json", ...options?.headers },
    body: JSON.stringify(departmentUpdate),
  });
};

export const getUpdateDepartmentMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof updateDepartment>>,
    TError,
    { id: number; data: BodyType<DepartmentUpdate> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof updateDepartment>>,
  TError,
  { id: number; data: BodyType<DepartmentUpdate> },
  TContext
> => {
  const mutationKey = ["updateDepartment"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

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

    return updateDepartment(id, data, requestOptions);
  };

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

export type UpdateDepartmentMutationResult = NonNullable<
  Awaited<ReturnType<typeof updateDepartment>>
>;
export type UpdateDepartmentMutationBody = BodyType<DepartmentUpdate>;
export type UpdateDepartmentMutationError = ErrorType<unknown>;

/**
 * @summary Update department
 */
export const useUpdateDepartment = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof updateDepartment>>,
    TError,
    { id: number; data: BodyType<DepartmentUpdate> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof updateDepartment>>,
  TError,
  { id: number; data: BodyType<DepartmentUpdate> },
  TContext
> => {
  return useMutation(getUpdateDepartmentMutationOptions(options));
};

/**
 * @summary Delete department
 */
export const getDeleteDepartmentUrl = (id: number) => {
  return `/api/departments/${id}`;
};

export const deleteDepartment = async (
  id: number,
  options?: RequestInit,
): Promise<void> => {
  return customFetch<void>(getDeleteDepartmentUrl(id), {
    ...options,
    method: "DELETE",
  });
};

export const getDeleteDepartmentMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof deleteDepartment>>,
    TError,
    { id: number },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof deleteDepartment>>,
  TError,
  { id: number },
  TContext
> => {
  const mutationKey = ["deleteDepartment"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

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

    return deleteDepartment(id, requestOptions);
  };

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

export type DeleteDepartmentMutationResult = NonNullable<
  Awaited<ReturnType<typeof deleteDepartment>>
>;

export type DeleteDepartmentMutationError = ErrorType<unknown>;

/**
 * @summary Delete department
 */
export const useDeleteDepartment = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof deleteDepartment>>,
    TError,
    { id: number },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof deleteDepartment>>,
  TError,
  { id: number },
  TContext
> => {
  return useMutation(getDeleteDepartmentMutationOptions(options));
};

/**
 * @summary List documents in knowledge base
 */
export const getListDocumentsUrl = (params?: ListDocumentsParams) => {
  const normalizedParams = new URLSearchParams();

  Object.entries(params || {}).forEach(([key, value]) => {
    if (value !== undefined) {
      normalizedParams.append(key, value === null ? "null" : value.toString());
    }
  });

  const stringifiedParams = normalizedParams.toString();

  return stringifiedParams.length > 0
    ? `/api/documents?${stringifiedParams}`
    : `/api/documents`;
};

export const listDocuments = async (
  params?: ListDocumentsParams,
  options?: RequestInit,
): Promise<Document[]> => {
  return customFetch<Document[]>(getListDocumentsUrl(params), {
    ...options,
    method: "GET",
  });
};

export const getListDocumentsQueryKey = (params?: ListDocumentsParams) => {
  return [`/api/documents`, ...(params ? [params] : [])] as const;
};

export const getListDocumentsQueryOptions = <
  TData = Awaited<ReturnType<typeof listDocuments>>,
  TError = ErrorType<unknown>,
>(
  params?: ListDocumentsParams,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof listDocuments>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

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

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

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

export type ListDocumentsQueryResult = NonNullable<
  Awaited<ReturnType<typeof listDocuments>>
>;
export type ListDocumentsQueryError = ErrorType<unknown>;

/**
 * @summary List documents in knowledge base
 */

export function useListDocuments<
  TData = Awaited<ReturnType<typeof listDocuments>>,
  TError = ErrorType<unknown>,
>(
  params?: ListDocumentsParams,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof listDocuments>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
  const queryOptions = getListDocumentsQueryOptions(params, options);

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

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

/**
 * @summary Get document
 */
export const getGetDocumentUrl = (id: number) => {
  return `/api/documents/${id}`;
};

export const getDocument = async (
  id: number,
  options?: RequestInit,
): Promise<Document> => {
  return customFetch<Document>(getGetDocumentUrl(id), {
    ...options,
    method: "GET",
  });
};

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

export const getGetDocumentQueryOptions = <
  TData = Awaited<ReturnType<typeof getDocument>>,
  TError = ErrorType<void>,
>(
  id: number,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof getDocument>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

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

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

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

export type GetDocumentQueryResult = NonNullable<
  Awaited<ReturnType<typeof getDocument>>
>;
export type GetDocumentQueryError = ErrorType<void>;

/**
 * @summary Get document
 */

export function useGetDocument<
  TData = Awaited<ReturnType<typeof getDocument>>,
  TError = ErrorType<void>,
>(
  id: number,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof getDocument>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
  const queryOptions = getGetDocumentQueryOptions(id, options);

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

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

/**
 * @summary Delete document
 */
export const getDeleteDocumentUrl = (id: number) => {
  return `/api/documents/${id}`;
};

export const deleteDocument = async (
  id: number,
  options?: RequestInit,
): Promise<void> => {
  return customFetch<void>(getDeleteDocumentUrl(id), {
    ...options,
    method: "DELETE",
  });
};

export const getDeleteDocumentMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof deleteDocument>>,
    TError,
    { id: number },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof deleteDocument>>,
  TError,
  { id: number },
  TContext
> => {
  const mutationKey = ["deleteDocument"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

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

    return deleteDocument(id, requestOptions);
  };

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

export type DeleteDocumentMutationResult = NonNullable<
  Awaited<ReturnType<typeof deleteDocument>>
>;

export type DeleteDocumentMutationError = ErrorType<unknown>;

/**
 * @summary Delete document
 */
export const useDeleteDocument = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof deleteDocument>>,
    TError,
    { id: number },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof deleteDocument>>,
  TError,
  { id: number },
  TContext
> => {
  return useMutation(getDeleteDocumentMutationOptions(options));
};

/**
 * @summary List templates
 */
export const getListTemplatesUrl = (params?: ListTemplatesParams) => {
  const normalizedParams = new URLSearchParams();

  Object.entries(params || {}).forEach(([key, value]) => {
    if (value !== undefined) {
      normalizedParams.append(key, value === null ? "null" : value.toString());
    }
  });

  const stringifiedParams = normalizedParams.toString();

  return stringifiedParams.length > 0
    ? `/api/templates?${stringifiedParams}`
    : `/api/templates`;
};

export const listTemplates = async (
  params?: ListTemplatesParams,
  options?: RequestInit,
): Promise<Template[]> => {
  return customFetch<Template[]>(getListTemplatesUrl(params), {
    ...options,
    method: "GET",
  });
};

export const getListTemplatesQueryKey = (params?: ListTemplatesParams) => {
  return [`/api/templates`, ...(params ? [params] : [])] as const;
};

export const getListTemplatesQueryOptions = <
  TData = Awaited<ReturnType<typeof listTemplates>>,
  TError = ErrorType<unknown>,
>(
  params?: ListTemplatesParams,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof listTemplates>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

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

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

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

export type ListTemplatesQueryResult = NonNullable<
  Awaited<ReturnType<typeof listTemplates>>
>;
export type ListTemplatesQueryError = ErrorType<unknown>;

/**
 * @summary List templates
 */

export function useListTemplates<
  TData = Awaited<ReturnType<typeof listTemplates>>,
  TError = ErrorType<unknown>,
>(
  params?: ListTemplatesParams,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof listTemplates>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
  const queryOptions = getListTemplatesQueryOptions(params, options);

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

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

/**
 * @summary Create template
 */
export const getCreateTemplateUrl = () => {
  return `/api/templates`;
};

export const createTemplate = async (
  templateInput: TemplateInput,
  options?: RequestInit,
): Promise<Template> => {
  return customFetch<Template>(getCreateTemplateUrl(), {
    ...options,
    method: "POST",
    headers: { "Content-Type": "application/json", ...options?.headers },
    body: JSON.stringify(templateInput),
  });
};

export const getCreateTemplateMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof createTemplate>>,
    TError,
    { data: BodyType<TemplateInput> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof createTemplate>>,
  TError,
  { data: BodyType<TemplateInput> },
  TContext
> => {
  const mutationKey = ["createTemplate"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

  const mutationFn: MutationFunction<
    Awaited<ReturnType<typeof createTemplate>>,
    { data: BodyType<TemplateInput> }
  > = (props) => {
    const { data } = props ?? {};

    return createTemplate(data, requestOptions);
  };

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

export type CreateTemplateMutationResult = NonNullable<
  Awaited<ReturnType<typeof createTemplate>>
>;
export type CreateTemplateMutationBody = BodyType<TemplateInput>;
export type CreateTemplateMutationError = ErrorType<unknown>;

/**
 * @summary Create template
 */
export const useCreateTemplate = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof createTemplate>>,
    TError,
    { data: BodyType<TemplateInput> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof createTemplate>>,
  TError,
  { data: BodyType<TemplateInput> },
  TContext
> => {
  return useMutation(getCreateTemplateMutationOptions(options));
};

/**
 * @summary Get template
 */
export const getGetTemplateUrl = (id: number) => {
  return `/api/templates/${id}`;
};

export const getTemplate = async (
  id: number,
  options?: RequestInit,
): Promise<Template> => {
  return customFetch<Template>(getGetTemplateUrl(id), {
    ...options,
    method: "GET",
  });
};

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

export const getGetTemplateQueryOptions = <
  TData = Awaited<ReturnType<typeof getTemplate>>,
  TError = ErrorType<unknown>,
>(
  id: number,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof getTemplate>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

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

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

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

export type GetTemplateQueryResult = NonNullable<
  Awaited<ReturnType<typeof getTemplate>>
>;
export type GetTemplateQueryError = ErrorType<unknown>;

/**
 * @summary Get template
 */

export function useGetTemplate<
  TData = Awaited<ReturnType<typeof getTemplate>>,
  TError = ErrorType<unknown>,
>(
  id: number,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof getTemplate>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
  const queryOptions = getGetTemplateQueryOptions(id, options);

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

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

/**
 * @summary Update template
 */
export const getUpdateTemplateUrl = (id: number) => {
  return `/api/templates/${id}`;
};

export const updateTemplate = async (
  id: number,
  templateUpdate: TemplateUpdate,
  options?: RequestInit,
): Promise<Template> => {
  return customFetch<Template>(getUpdateTemplateUrl(id), {
    ...options,
    method: "PATCH",
    headers: { "Content-Type": "application/json", ...options?.headers },
    body: JSON.stringify(templateUpdate),
  });
};

export const getUpdateTemplateMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof updateTemplate>>,
    TError,
    { id: number; data: BodyType<TemplateUpdate> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof updateTemplate>>,
  TError,
  { id: number; data: BodyType<TemplateUpdate> },
  TContext
> => {
  const mutationKey = ["updateTemplate"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

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

    return updateTemplate(id, data, requestOptions);
  };

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

export type UpdateTemplateMutationResult = NonNullable<
  Awaited<ReturnType<typeof updateTemplate>>
>;
export type UpdateTemplateMutationBody = BodyType<TemplateUpdate>;
export type UpdateTemplateMutationError = ErrorType<unknown>;

/**
 * @summary Update template
 */
export const useUpdateTemplate = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof updateTemplate>>,
    TError,
    { id: number; data: BodyType<TemplateUpdate> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof updateTemplate>>,
  TError,
  { id: number; data: BodyType<TemplateUpdate> },
  TContext
> => {
  return useMutation(getUpdateTemplateMutationOptions(options));
};

/**
 * @summary Delete template
 */
export const getDeleteTemplateUrl = (id: number) => {
  return `/api/templates/${id}`;
};

export const deleteTemplate = async (
  id: number,
  options?: RequestInit,
): Promise<void> => {
  return customFetch<void>(getDeleteTemplateUrl(id), {
    ...options,
    method: "DELETE",
  });
};

export const getDeleteTemplateMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof deleteTemplate>>,
    TError,
    { id: number },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof deleteTemplate>>,
  TError,
  { id: number },
  TContext
> => {
  const mutationKey = ["deleteTemplate"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

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

    return deleteTemplate(id, requestOptions);
  };

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

export type DeleteTemplateMutationResult = NonNullable<
  Awaited<ReturnType<typeof deleteTemplate>>
>;

export type DeleteTemplateMutationError = ErrorType<unknown>;

/**
 * @summary Delete template
 */
export const useDeleteTemplate = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof deleteTemplate>>,
    TError,
    { id: number },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof deleteTemplate>>,
  TError,
  { id: number },
  TContext
> => {
  return useMutation(getDeleteTemplateMutationOptions(options));
};

/**
 * @summary List plans
 */
export const getListPlansUrl = (params?: ListPlansParams) => {
  const normalizedParams = new URLSearchParams();

  Object.entries(params || {}).forEach(([key, value]) => {
    if (value !== undefined) {
      normalizedParams.append(key, value === null ? "null" : value.toString());
    }
  });

  const stringifiedParams = normalizedParams.toString();

  return stringifiedParams.length > 0
    ? `/api/plans?${stringifiedParams}`
    : `/api/plans`;
};

export const listPlans = async (
  params?: ListPlansParams,
  options?: RequestInit,
): Promise<Plan[]> => {
  return customFetch<Plan[]>(getListPlansUrl(params), {
    ...options,
    method: "GET",
  });
};

export const getListPlansQueryKey = (params?: ListPlansParams) => {
  return [`/api/plans`, ...(params ? [params] : [])] as const;
};

export const getListPlansQueryOptions = <
  TData = Awaited<ReturnType<typeof listPlans>>,
  TError = ErrorType<unknown>,
>(
  params?: ListPlansParams,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof listPlans>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

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

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

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

export type ListPlansQueryResult = NonNullable<
  Awaited<ReturnType<typeof listPlans>>
>;
export type ListPlansQueryError = ErrorType<unknown>;

/**
 * @summary List plans
 */

export function useListPlans<
  TData = Awaited<ReturnType<typeof listPlans>>,
  TError = ErrorType<unknown>,
>(
  params?: ListPlansParams,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof listPlans>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
  const queryOptions = getListPlansQueryOptions(params, options);

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

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

/**
 * @summary Create a new plan
 */
export const getCreatePlanUrl = () => {
  return `/api/plans`;
};

export const createPlan = async (
  planInput: PlanInput,
  options?: RequestInit,
): Promise<Plan> => {
  return customFetch<Plan>(getCreatePlanUrl(), {
    ...options,
    method: "POST",
    headers: { "Content-Type": "application/json", ...options?.headers },
    body: JSON.stringify(planInput),
  });
};

export const getCreatePlanMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof createPlan>>,
    TError,
    { data: BodyType<PlanInput> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof createPlan>>,
  TError,
  { data: BodyType<PlanInput> },
  TContext
> => {
  const mutationKey = ["createPlan"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

  const mutationFn: MutationFunction<
    Awaited<ReturnType<typeof createPlan>>,
    { data: BodyType<PlanInput> }
  > = (props) => {
    const { data } = props ?? {};

    return createPlan(data, requestOptions);
  };

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

export type CreatePlanMutationResult = NonNullable<
  Awaited<ReturnType<typeof createPlan>>
>;
export type CreatePlanMutationBody = BodyType<PlanInput>;
export type CreatePlanMutationError = ErrorType<unknown>;

/**
 * @summary Create a new plan
 */
export const useCreatePlan = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof createPlan>>,
    TError,
    { data: BodyType<PlanInput> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof createPlan>>,
  TError,
  { data: BodyType<PlanInput> },
  TContext
> => {
  return useMutation(getCreatePlanMutationOptions(options));
};

/**
 * @summary Get plan with all details
 */
export const getGetPlanUrl = (id: number) => {
  return `/api/plans/${id}`;
};

export const getPlan = async (
  id: number,
  options?: RequestInit,
): Promise<PlanDetail> => {
  return customFetch<PlanDetail>(getGetPlanUrl(id), {
    ...options,
    method: "GET",
  });
};

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

export const getGetPlanQueryOptions = <
  TData = Awaited<ReturnType<typeof getPlan>>,
  TError = ErrorType<void>,
>(
  id: number,
  options?: {
    query?: UseQueryOptions<Awaited<ReturnType<typeof getPlan>>, TError, TData>;
    request?: SecondParameter<typeof customFetch>;
  },
) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

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

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

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

export type GetPlanQueryResult = NonNullable<
  Awaited<ReturnType<typeof getPlan>>
>;
export type GetPlanQueryError = ErrorType<void>;

/**
 * @summary Get plan with all details
 */

export function useGetPlan<
  TData = Awaited<ReturnType<typeof getPlan>>,
  TError = ErrorType<void>,
>(
  id: number,
  options?: {
    query?: UseQueryOptions<Awaited<ReturnType<typeof getPlan>>, TError, TData>;
    request?: SecondParameter<typeof customFetch>;
  },
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
  const queryOptions = getGetPlanQueryOptions(id, options);

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

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

/**
 * @summary Update plan
 */
export const getUpdatePlanUrl = (id: number) => {
  return `/api/plans/${id}`;
};

export const updatePlan = async (
  id: number,
  planUpdate: PlanUpdate,
  options?: RequestInit,
): Promise<Plan> => {
  return customFetch<Plan>(getUpdatePlanUrl(id), {
    ...options,
    method: "PATCH",
    headers: { "Content-Type": "application/json", ...options?.headers },
    body: JSON.stringify(planUpdate),
  });
};

export const getUpdatePlanMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof updatePlan>>,
    TError,
    { id: number; data: BodyType<PlanUpdate> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof updatePlan>>,
  TError,
  { id: number; data: BodyType<PlanUpdate> },
  TContext
> => {
  const mutationKey = ["updatePlan"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

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

    return updatePlan(id, data, requestOptions);
  };

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

export type UpdatePlanMutationResult = NonNullable<
  Awaited<ReturnType<typeof updatePlan>>
>;
export type UpdatePlanMutationBody = BodyType<PlanUpdate>;
export type UpdatePlanMutationError = ErrorType<unknown>;

/**
 * @summary Update plan
 */
export const useUpdatePlan = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof updatePlan>>,
    TError,
    { id: number; data: BodyType<PlanUpdate> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof updatePlan>>,
  TError,
  { id: number; data: BodyType<PlanUpdate> },
  TContext
> => {
  return useMutation(getUpdatePlanMutationOptions(options));
};

/**
 * @summary Delete plan
 */
export const getDeletePlanUrl = (id: number) => {
  return `/api/plans/${id}`;
};

export const deletePlan = async (
  id: number,
  options?: RequestInit,
): Promise<void> => {
  return customFetch<void>(getDeletePlanUrl(id), {
    ...options,
    method: "DELETE",
  });
};

export const getDeletePlanMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof deletePlan>>,
    TError,
    { id: number },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof deletePlan>>,
  TError,
  { id: number },
  TContext
> => {
  const mutationKey = ["deletePlan"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

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

    return deletePlan(id, requestOptions);
  };

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

export type DeletePlanMutationResult = NonNullable<
  Awaited<ReturnType<typeof deletePlan>>
>;

export type DeletePlanMutationError = ErrorType<unknown>;

/**
 * @summary Delete plan
 */
export const useDeletePlan = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof deletePlan>>,
    TError,
    { id: number },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof deletePlan>>,
  TError,
  { id: number },
  TContext
> => {
  return useMutation(getDeletePlanMutationOptions(options));
};

/**
 * @summary Generate AI plan content
 */
export const getGeneratePlanUrl = (id: number) => {
  return `/api/plans/${id}/generate`;
};

export const generatePlan = async (
  id: number,
  generatePlanRequest: GeneratePlanRequest,
  options?: RequestInit,
): Promise<GeneratePlanResult> => {
  return customFetch<GeneratePlanResult>(getGeneratePlanUrl(id), {
    ...options,
    method: "POST",
    headers: { "Content-Type": "application/json", ...options?.headers },
    body: JSON.stringify(generatePlanRequest),
  });
};

export const getGeneratePlanMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof generatePlan>>,
    TError,
    { id: number; data: BodyType<GeneratePlanRequest> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof generatePlan>>,
  TError,
  { id: number; data: BodyType<GeneratePlanRequest> },
  TContext
> => {
  const mutationKey = ["generatePlan"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

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

    return generatePlan(id, data, requestOptions);
  };

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

export type GeneratePlanMutationResult = NonNullable<
  Awaited<ReturnType<typeof generatePlan>>
>;
export type GeneratePlanMutationBody = BodyType<GeneratePlanRequest>;
export type GeneratePlanMutationError = ErrorType<unknown>;

/**
 * @summary Generate AI plan content
 */
export const useGeneratePlan = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof generatePlan>>,
    TError,
    { id: number; data: BodyType<GeneratePlanRequest> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof generatePlan>>,
  TError,
  { id: number; data: BodyType<GeneratePlanRequest> },
  TContext
> => {
  return useMutation(getGeneratePlanMutationOptions(options));
};

/**
 * @summary Duplicate a plan
 */
export const getDuplicatePlanUrl = (id: number) => {
  return `/api/plans/${id}/duplicate`;
};

export const duplicatePlan = async (
  id: number,
  options?: RequestInit,
): Promise<Plan> => {
  return customFetch<Plan>(getDuplicatePlanUrl(id), {
    ...options,
    method: "POST",
  });
};

export const getDuplicatePlanMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof duplicatePlan>>,
    TError,
    { id: number },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof duplicatePlan>>,
  TError,
  { id: number },
  TContext
> => {
  const mutationKey = ["duplicatePlan"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

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

    return duplicatePlan(id, requestOptions);
  };

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

export type DuplicatePlanMutationResult = NonNullable<
  Awaited<ReturnType<typeof duplicatePlan>>
>;

export type DuplicatePlanMutationError = ErrorType<unknown>;

/**
 * @summary Duplicate a plan
 */
export const useDuplicatePlan = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof duplicatePlan>>,
    TError,
    { id: number },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof duplicatePlan>>,
  TError,
  { id: number },
  TContext
> => {
  return useMutation(getDuplicatePlanMutationOptions(options));
};

/**
 * @summary Export plan to PDF or DOCX
 */
export const getExportPlanUrl = (id: number) => {
  return `/api/plans/${id}/export`;
};

export const exportPlan = async (
  id: number,
  exportRequest: ExportRequest,
  options?: RequestInit,
): Promise<ExportResult> => {
  return customFetch<ExportResult>(getExportPlanUrl(id), {
    ...options,
    method: "POST",
    headers: { "Content-Type": "application/json", ...options?.headers },
    body: JSON.stringify(exportRequest),
  });
};

export const getExportPlanMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof exportPlan>>,
    TError,
    { id: number; data: BodyType<ExportRequest> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof exportPlan>>,
  TError,
  { id: number; data: BodyType<ExportRequest> },
  TContext
> => {
  const mutationKey = ["exportPlan"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

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

    return exportPlan(id, data, requestOptions);
  };

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

export type ExportPlanMutationResult = NonNullable<
  Awaited<ReturnType<typeof exportPlan>>
>;
export type ExportPlanMutationBody = BodyType<ExportRequest>;
export type ExportPlanMutationError = ErrorType<unknown>;

/**
 * @summary Export plan to PDF or DOCX
 */
export const useExportPlan = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof exportPlan>>,
    TError,
    { id: number; data: BodyType<ExportRequest> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof exportPlan>>,
  TError,
  { id: number; data: BodyType<ExportRequest> },
  TContext
> => {
  return useMutation(getExportPlanMutationOptions(options));
};

/**
 * @summary List session rows for a plan
 */
export const getListSessionRowsUrl = (id: number) => {
  return `/api/plans/${id}/sessions`;
};

export const listSessionRows = async (
  id: number,
  options?: RequestInit,
): Promise<SessionRow[]> => {
  return customFetch<SessionRow[]>(getListSessionRowsUrl(id), {
    ...options,
    method: "GET",
  });
};

export const getListSessionRowsQueryKey = (id: number) => {
  return [`/api/plans/${id}/sessions`] as const;
};

export const getListSessionRowsQueryOptions = <
  TData = Awaited<ReturnType<typeof listSessionRows>>,
  TError = ErrorType<unknown>,
>(
  id: number,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof listSessionRows>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

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

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

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

export type ListSessionRowsQueryResult = NonNullable<
  Awaited<ReturnType<typeof listSessionRows>>
>;
export type ListSessionRowsQueryError = ErrorType<unknown>;

/**
 * @summary List session rows for a plan
 */

export function useListSessionRows<
  TData = Awaited<ReturnType<typeof listSessionRows>>,
  TError = ErrorType<unknown>,
>(
  id: number,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof listSessionRows>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
  const queryOptions = getListSessionRowsQueryOptions(id, options);

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

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

/**
 * @summary Create a session row
 */
export const getCreateSessionRowUrl = (id: number) => {
  return `/api/plans/${id}/sessions`;
};

export const createSessionRow = async (
  id: number,
  sessionRowInput: SessionRowInput,
  options?: RequestInit,
): Promise<SessionRow> => {
  return customFetch<SessionRow>(getCreateSessionRowUrl(id), {
    ...options,
    method: "POST",
    headers: { "Content-Type": "application/json", ...options?.headers },
    body: JSON.stringify(sessionRowInput),
  });
};

export const getCreateSessionRowMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof createSessionRow>>,
    TError,
    { id: number; data: BodyType<SessionRowInput> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof createSessionRow>>,
  TError,
  { id: number; data: BodyType<SessionRowInput> },
  TContext
> => {
  const mutationKey = ["createSessionRow"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

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

    return createSessionRow(id, data, requestOptions);
  };

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

export type CreateSessionRowMutationResult = NonNullable<
  Awaited<ReturnType<typeof createSessionRow>>
>;
export type CreateSessionRowMutationBody = BodyType<SessionRowInput>;
export type CreateSessionRowMutationError = ErrorType<unknown>;

/**
 * @summary Create a session row
 */
export const useCreateSessionRow = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof createSessionRow>>,
    TError,
    { id: number; data: BodyType<SessionRowInput> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof createSessionRow>>,
  TError,
  { id: number; data: BodyType<SessionRowInput> },
  TContext
> => {
  return useMutation(getCreateSessionRowMutationOptions(options));
};

/**
 * @summary Update a session row
 */
export const getUpdateSessionRowUrl = (id: number, sessionId: number) => {
  return `/api/plans/${id}/sessions/${sessionId}`;
};

export const updateSessionRow = async (
  id: number,
  sessionId: number,
  sessionRowUpdate: SessionRowUpdate,
  options?: RequestInit,
): Promise<SessionRow> => {
  return customFetch<SessionRow>(getUpdateSessionRowUrl(id, sessionId), {
    ...options,
    method: "PATCH",
    headers: { "Content-Type": "application/json", ...options?.headers },
    body: JSON.stringify(sessionRowUpdate),
  });
};

export const getUpdateSessionRowMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof updateSessionRow>>,
    TError,
    { id: number; sessionId: number; data: BodyType<SessionRowUpdate> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof updateSessionRow>>,
  TError,
  { id: number; sessionId: number; data: BodyType<SessionRowUpdate> },
  TContext
> => {
  const mutationKey = ["updateSessionRow"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

  const mutationFn: MutationFunction<
    Awaited<ReturnType<typeof updateSessionRow>>,
    { id: number; sessionId: number; data: BodyType<SessionRowUpdate> }
  > = (props) => {
    const { id, sessionId, data } = props ?? {};

    return updateSessionRow(id, sessionId, data, requestOptions);
  };

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

export type UpdateSessionRowMutationResult = NonNullable<
  Awaited<ReturnType<typeof updateSessionRow>>
>;
export type UpdateSessionRowMutationBody = BodyType<SessionRowUpdate>;
export type UpdateSessionRowMutationError = ErrorType<unknown>;

/**
 * @summary Update a session row
 */
export const useUpdateSessionRow = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof updateSessionRow>>,
    TError,
    { id: number; sessionId: number; data: BodyType<SessionRowUpdate> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof updateSessionRow>>,
  TError,
  { id: number; sessionId: number; data: BodyType<SessionRowUpdate> },
  TContext
> => {
  return useMutation(getUpdateSessionRowMutationOptions(options));
};

/**
 * @summary Delete a session row
 */
export const getDeleteSessionRowUrl = (id: number, sessionId: number) => {
  return `/api/plans/${id}/sessions/${sessionId}`;
};

export const deleteSessionRow = async (
  id: number,
  sessionId: number,
  options?: RequestInit,
): Promise<void> => {
  return customFetch<void>(getDeleteSessionRowUrl(id, sessionId), {
    ...options,
    method: "DELETE",
  });
};

export const getDeleteSessionRowMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof deleteSessionRow>>,
    TError,
    { id: number; sessionId: number },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof deleteSessionRow>>,
  TError,
  { id: number; sessionId: number },
  TContext
> => {
  const mutationKey = ["deleteSessionRow"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

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

    return deleteSessionRow(id, sessionId, requestOptions);
  };

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

export type DeleteSessionRowMutationResult = NonNullable<
  Awaited<ReturnType<typeof deleteSessionRow>>
>;

export type DeleteSessionRowMutationError = ErrorType<unknown>;

/**
 * @summary Delete a session row
 */
export const useDeleteSessionRow = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof deleteSessionRow>>,
    TError,
    { id: number; sessionId: number },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof deleteSessionRow>>,
  TError,
  { id: number; sessionId: number },
  TContext
> => {
  return useMutation(getDeleteSessionRowMutationOptions(options));
};

/**
 * @summary Regenerate a single session using AI
 */
export const getRegenerateSessionUrl = (id: number, sessionId: number) => {
  return `/api/plans/${id}/sessions/${sessionId}/regenerate`;
};

export const regenerateSession = async (
  id: number,
  sessionId: number,
  options?: RequestInit,
): Promise<SessionRow> => {
  return customFetch<SessionRow>(getRegenerateSessionUrl(id, sessionId), {
    ...options,
    method: "POST",
  });
};

export const getRegenerateSessionMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof regenerateSession>>,
    TError,
    { id: number; sessionId: number },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof regenerateSession>>,
  TError,
  { id: number; sessionId: number },
  TContext
> => {
  const mutationKey = ["regenerateSession"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

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

    return regenerateSession(id, sessionId, requestOptions);
  };

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

export type RegenerateSessionMutationResult = NonNullable<
  Awaited<ReturnType<typeof regenerateSession>>
>;

export type RegenerateSessionMutationError = ErrorType<unknown>;

/**
 * @summary Regenerate a single session using AI
 */
export const useRegenerateSession = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof regenerateSession>>,
    TError,
    { id: number; sessionId: number },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof regenerateSession>>,
  TError,
  { id: number; sessionId: number },
  TContext
> => {
  return useMutation(getRegenerateSessionMutationOptions(options));
};

/**
 * @summary Get timetable for a plan
 */
export const getGetTimetableUrl = (id: number) => {
  return `/api/plans/${id}/timetable`;
};

export const getTimetable = async (
  id: number,
  options?: RequestInit,
): Promise<Timetable> => {
  return customFetch<Timetable>(getGetTimetableUrl(id), {
    ...options,
    method: "GET",
  });
};

export const getGetTimetableQueryKey = (id: number) => {
  return [`/api/plans/${id}/timetable`] as const;
};

export const getGetTimetableQueryOptions = <
  TData = Awaited<ReturnType<typeof getTimetable>>,
  TError = ErrorType<void>,
>(
  id: number,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof getTimetable>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

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

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

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

export type GetTimetableQueryResult = NonNullable<
  Awaited<ReturnType<typeof getTimetable>>
>;
export type GetTimetableQueryError = ErrorType<void>;

/**
 * @summary Get timetable for a plan
 */

export function useGetTimetable<
  TData = Awaited<ReturnType<typeof getTimetable>>,
  TError = ErrorType<void>,
>(
  id: number,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof getTimetable>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
  const queryOptions = getGetTimetableQueryOptions(id, options);

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

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

/**
 * @summary Create or update timetable for a plan
 */
export const getUpsertTimetableUrl = (id: number) => {
  return `/api/plans/${id}/timetable`;
};

export const upsertTimetable = async (
  id: number,
  timetableInput: TimetableInput,
  options?: RequestInit,
): Promise<Timetable> => {
  return customFetch<Timetable>(getUpsertTimetableUrl(id), {
    ...options,
    method: "PUT",
    headers: { "Content-Type": "application/json", ...options?.headers },
    body: JSON.stringify(timetableInput),
  });
};

export const getUpsertTimetableMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof upsertTimetable>>,
    TError,
    { id: number; data: BodyType<TimetableInput> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof upsertTimetable>>,
  TError,
  { id: number; data: BodyType<TimetableInput> },
  TContext
> => {
  const mutationKey = ["upsertTimetable"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

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

    return upsertTimetable(id, data, requestOptions);
  };

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

export type UpsertTimetableMutationResult = NonNullable<
  Awaited<ReturnType<typeof upsertTimetable>>
>;
export type UpsertTimetableMutationBody = BodyType<TimetableInput>;
export type UpsertTimetableMutationError = ErrorType<unknown>;

/**
 * @summary Create or update timetable for a plan
 */
export const useUpsertTimetable = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof upsertTimetable>>,
    TError,
    { id: number; data: BodyType<TimetableInput> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof upsertTimetable>>,
  TError,
  { id: number; data: BodyType<TimetableInput> },
  TContext
> => {
  return useMutation(getUpsertTimetableMutationOptions(options));
};

/**
 * @summary Get auto-calculated session schedule for a plan
 */
export const getGetTimetableScheduleUrl = (id: number) => {
  return `/api/plans/${id}/timetable/schedule`;
};

export const getTimetableSchedule = async (
  id: number,
  options?: RequestInit,
): Promise<TimetableSchedule> => {
  return customFetch<TimetableSchedule>(getGetTimetableScheduleUrl(id), {
    ...options,
    method: "GET",
  });
};

export const getGetTimetableScheduleQueryKey = (id: number) => {
  return [`/api/plans/${id}/timetable/schedule`] as const;
};

export const getGetTimetableScheduleQueryOptions = <
  TData = Awaited<ReturnType<typeof getTimetableSchedule>>,
  TError = ErrorType<unknown>,
>(
  id: number,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof getTimetableSchedule>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

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

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

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

export type GetTimetableScheduleQueryResult = NonNullable<
  Awaited<ReturnType<typeof getTimetableSchedule>>
>;
export type GetTimetableScheduleQueryError = ErrorType<unknown>;

/**
 * @summary Get auto-calculated session schedule for a plan
 */

export function useGetTimetableSchedule<
  TData = Awaited<ReturnType<typeof getTimetableSchedule>>,
  TError = ErrorType<unknown>,
>(
  id: number,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof getTimetableSchedule>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
  const queryOptions = getGetTimetableScheduleQueryOptions(id, options);

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

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

/**
 * @summary Get detailed session plan for a session row
 */
export const getGetSessionPlanUrl = (id: number, sessionId: number) => {
  return `/api/plans/${id}/sessions/${sessionId}/session-plan`;
};

export const getSessionPlan = async (
  id: number,
  sessionId: number,
  options?: RequestInit,
): Promise<SessionPlan> => {
  return customFetch<SessionPlan>(getGetSessionPlanUrl(id, sessionId), {
    ...options,
    method: "GET",
  });
};

export const getGetSessionPlanQueryKey = (id: number, sessionId: number) => {
  return [`/api/plans/${id}/sessions/${sessionId}/session-plan`] as const;
};

export const getGetSessionPlanQueryOptions = <
  TData = Awaited<ReturnType<typeof getSessionPlan>>,
  TError = ErrorType<void>,
>(
  id: number,
  sessionId: number,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof getSessionPlan>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

  const queryKey =
    queryOptions?.queryKey ?? getGetSessionPlanQueryKey(id, sessionId);

  const queryFn: QueryFunction<Awaited<ReturnType<typeof getSessionPlan>>> = ({
    signal,
  }) => getSessionPlan(id, sessionId, { signal, ...requestOptions });

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

export type GetSessionPlanQueryResult = NonNullable<
  Awaited<ReturnType<typeof getSessionPlan>>
>;
export type GetSessionPlanQueryError = ErrorType<void>;

/**
 * @summary Get detailed session plan for a session row
 */

export function useGetSessionPlan<
  TData = Awaited<ReturnType<typeof getSessionPlan>>,
  TError = ErrorType<void>,
>(
  id: number,
  sessionId: number,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof getSessionPlan>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
  const queryOptions = getGetSessionPlanQueryOptions(id, sessionId, options);

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

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

/**
 * @summary AI-generate a detailed session plan for a session row
 */
export const getGenerateSessionPlanUrl = (id: number, sessionId: number) => {
  return `/api/plans/${id}/sessions/${sessionId}/session-plan`;
};

export const generateSessionPlan = async (
  id: number,
  sessionId: number,
  generateSessionPlanRequest: GenerateSessionPlanRequest,
  options?: RequestInit,
): Promise<SessionPlan> => {
  return customFetch<SessionPlan>(getGenerateSessionPlanUrl(id, sessionId), {
    ...options,
    method: "POST",
    headers: { "Content-Type": "application/json", ...options?.headers },
    body: JSON.stringify(generateSessionPlanRequest),
  });
};

export const getGenerateSessionPlanMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof generateSessionPlan>>,
    TError,
    {
      id: number;
      sessionId: number;
      data: BodyType<GenerateSessionPlanRequest>;
    },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof generateSessionPlan>>,
  TError,
  { id: number; sessionId: number; data: BodyType<GenerateSessionPlanRequest> },
  TContext
> => {
  const mutationKey = ["generateSessionPlan"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

  const mutationFn: MutationFunction<
    Awaited<ReturnType<typeof generateSessionPlan>>,
    {
      id: number;
      sessionId: number;
      data: BodyType<GenerateSessionPlanRequest>;
    }
  > = (props) => {
    const { id, sessionId, data } = props ?? {};

    return generateSessionPlan(id, sessionId, data, requestOptions);
  };

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

export type GenerateSessionPlanMutationResult = NonNullable<
  Awaited<ReturnType<typeof generateSessionPlan>>
>;
export type GenerateSessionPlanMutationBody =
  BodyType<GenerateSessionPlanRequest>;
export type GenerateSessionPlanMutationError = ErrorType<unknown>;

/**
 * @summary AI-generate a detailed session plan for a session row
 */
export const useGenerateSessionPlan = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof generateSessionPlan>>,
    TError,
    {
      id: number;
      sessionId: number;
      data: BodyType<GenerateSessionPlanRequest>;
    },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof generateSessionPlan>>,
  TError,
  { id: number; sessionId: number; data: BodyType<GenerateSessionPlanRequest> },
  TContext
> => {
  return useMutation(getGenerateSessionPlanMutationOptions(options));
};

/**
 * @summary Get session plan by ID
 */
export const getGetSessionPlanByIdUrl = (id: number) => {
  return `/api/session-plans/${id}`;
};

export const getSessionPlanById = async (
  id: number,
  options?: RequestInit,
): Promise<SessionPlan> => {
  return customFetch<SessionPlan>(getGetSessionPlanByIdUrl(id), {
    ...options,
    method: "GET",
  });
};

export const getGetSessionPlanByIdQueryKey = (id: number) => {
  return [`/api/session-plans/${id}`] as const;
};

export const getGetSessionPlanByIdQueryOptions = <
  TData = Awaited<ReturnType<typeof getSessionPlanById>>,
  TError = ErrorType<unknown>,
>(
  id: number,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof getSessionPlanById>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

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

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

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

export type GetSessionPlanByIdQueryResult = NonNullable<
  Awaited<ReturnType<typeof getSessionPlanById>>
>;
export type GetSessionPlanByIdQueryError = ErrorType<unknown>;

/**
 * @summary Get session plan by ID
 */

export function useGetSessionPlanById<
  TData = Awaited<ReturnType<typeof getSessionPlanById>>,
  TError = ErrorType<unknown>,
>(
  id: number,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof getSessionPlanById>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
  const queryOptions = getGetSessionPlanByIdQueryOptions(id, options);

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

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

/**
 * @summary Update session plan metadata or content
 */
export const getUpdateSessionPlanUrl = (id: number) => {
  return `/api/session-plans/${id}`;
};

export const updateSessionPlan = async (
  id: number,
  updateSessionPlanRequest: UpdateSessionPlanRequest,
  options?: RequestInit,
): Promise<SessionPlan> => {
  return customFetch<SessionPlan>(getUpdateSessionPlanUrl(id), {
    ...options,
    method: "PATCH",
    headers: { "Content-Type": "application/json", ...options?.headers },
    body: JSON.stringify(updateSessionPlanRequest),
  });
};

export const getUpdateSessionPlanMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof updateSessionPlan>>,
    TError,
    { id: number; data: BodyType<UpdateSessionPlanRequest> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof updateSessionPlan>>,
  TError,
  { id: number; data: BodyType<UpdateSessionPlanRequest> },
  TContext
> => {
  const mutationKey = ["updateSessionPlan"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

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

    return updateSessionPlan(id, data, requestOptions);
  };

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

export type UpdateSessionPlanMutationResult = NonNullable<
  Awaited<ReturnType<typeof updateSessionPlan>>
>;
export type UpdateSessionPlanMutationBody = BodyType<UpdateSessionPlanRequest>;
export type UpdateSessionPlanMutationError = ErrorType<unknown>;

/**
 * @summary Update session plan metadata or content
 */
export const useUpdateSessionPlan = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof updateSessionPlan>>,
    TError,
    { id: number; data: BodyType<UpdateSessionPlanRequest> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof updateSessionPlan>>,
  TError,
  { id: number; data: BodyType<UpdateSessionPlanRequest> },
  TContext
> => {
  return useMutation(getUpdateSessionPlanMutationOptions(options));
};

/**
 * @summary Regenerate a single section of a session plan using AI
 */
export const getRegenerateSessionPlanSectionUrl = (id: number) => {
  return `/api/session-plans/${id}/regenerate-section`;
};

export const regenerateSessionPlanSection = async (
  id: number,
  regenerateSectionRequest: RegenerateSectionRequest,
  options?: RequestInit,
): Promise<SessionPlan> => {
  return customFetch<SessionPlan>(getRegenerateSessionPlanSectionUrl(id), {
    ...options,
    method: "POST",
    headers: { "Content-Type": "application/json", ...options?.headers },
    body: JSON.stringify(regenerateSectionRequest),
  });
};

export const getRegenerateSessionPlanSectionMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof regenerateSessionPlanSection>>,
    TError,
    { id: number; data: BodyType<RegenerateSectionRequest> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof regenerateSessionPlanSection>>,
  TError,
  { id: number; data: BodyType<RegenerateSectionRequest> },
  TContext
> => {
  const mutationKey = ["regenerateSessionPlanSection"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

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

    return regenerateSessionPlanSection(id, data, requestOptions);
  };

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

export type RegenerateSessionPlanSectionMutationResult = NonNullable<
  Awaited<ReturnType<typeof regenerateSessionPlanSection>>
>;
export type RegenerateSessionPlanSectionMutationBody =
  BodyType<RegenerateSectionRequest>;
export type RegenerateSessionPlanSectionMutationError = ErrorType<unknown>;

/**
 * @summary Regenerate a single section of a session plan using AI
 */
export const useRegenerateSessionPlanSection = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof regenerateSessionPlanSection>>,
    TError,
    { id: number; data: BodyType<RegenerateSectionRequest> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof regenerateSessionPlanSection>>,
  TError,
  { id: number; data: BodyType<RegenerateSectionRequest> },
  TContext
> => {
  return useMutation(getRegenerateSessionPlanSectionMutationOptions(options));
};

/**
 * @summary Batch generate detailed session plans for all session rows
 */
export const getGenerateAllSessionPlansUrl = (id: number) => {
  return `/api/plans/${id}/generate-all-session-plans`;
};

export const generateAllSessionPlans = async (
  id: number,
  generateSessionPlanRequest: GenerateSessionPlanRequest,
  options?: RequestInit,
): Promise<BatchGenerateResult> => {
  return customFetch<BatchGenerateResult>(getGenerateAllSessionPlansUrl(id), {
    ...options,
    method: "POST",
    headers: { "Content-Type": "application/json", ...options?.headers },
    body: JSON.stringify(generateSessionPlanRequest),
  });
};

export const getGenerateAllSessionPlansMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof generateAllSessionPlans>>,
    TError,
    { id: number; data: BodyType<GenerateSessionPlanRequest> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof generateAllSessionPlans>>,
  TError,
  { id: number; data: BodyType<GenerateSessionPlanRequest> },
  TContext
> => {
  const mutationKey = ["generateAllSessionPlans"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

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

    return generateAllSessionPlans(id, data, requestOptions);
  };

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

export type GenerateAllSessionPlansMutationResult = NonNullable<
  Awaited<ReturnType<typeof generateAllSessionPlans>>
>;
export type GenerateAllSessionPlansMutationBody =
  BodyType<GenerateSessionPlanRequest>;
export type GenerateAllSessionPlansMutationError = ErrorType<unknown>;

/**
 * @summary Batch generate detailed session plans for all session rows
 */
export const useGenerateAllSessionPlans = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof generateAllSessionPlans>>,
    TError,
    { id: number; data: BodyType<GenerateSessionPlanRequest> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof generateAllSessionPlans>>,
  TError,
  { id: number; data: BodyType<GenerateSessionPlanRequest> },
  TContext
> => {
  return useMutation(getGenerateAllSessionPlansMutationOptions(options));
};

/**
 * @summary List approvals for a plan
 */
export const getListApprovalsUrl = (id: number) => {
  return `/api/plans/${id}/approvals`;
};

export const listApprovals = async (
  id: number,
  options?: RequestInit,
): Promise<Approval[]> => {
  return customFetch<Approval[]>(getListApprovalsUrl(id), {
    ...options,
    method: "GET",
  });
};

export const getListApprovalsQueryKey = (id: number) => {
  return [`/api/plans/${id}/approvals`] as const;
};

export const getListApprovalsQueryOptions = <
  TData = Awaited<ReturnType<typeof listApprovals>>,
  TError = ErrorType<unknown>,
>(
  id: number,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof listApprovals>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

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

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

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

export type ListApprovalsQueryResult = NonNullable<
  Awaited<ReturnType<typeof listApprovals>>
>;
export type ListApprovalsQueryError = ErrorType<unknown>;

/**
 * @summary List approvals for a plan
 */

export function useListApprovals<
  TData = Awaited<ReturnType<typeof listApprovals>>,
  TError = ErrorType<unknown>,
>(
  id: number,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof listApprovals>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
  const queryOptions = getListApprovalsQueryOptions(id, options);

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

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

/**
 * @summary Submit an approval action
 */
export const getCreateApprovalUrl = (id: number) => {
  return `/api/plans/${id}/approvals`;
};

export const createApproval = async (
  id: number,
  approvalInput: ApprovalInput,
  options?: RequestInit,
): Promise<Approval> => {
  return customFetch<Approval>(getCreateApprovalUrl(id), {
    ...options,
    method: "POST",
    headers: { "Content-Type": "application/json", ...options?.headers },
    body: JSON.stringify(approvalInput),
  });
};

export const getCreateApprovalMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof createApproval>>,
    TError,
    { id: number; data: BodyType<ApprovalInput> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof createApproval>>,
  TError,
  { id: number; data: BodyType<ApprovalInput> },
  TContext
> => {
  const mutationKey = ["createApproval"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

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

    return createApproval(id, data, requestOptions);
  };

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

export type CreateApprovalMutationResult = NonNullable<
  Awaited<ReturnType<typeof createApproval>>
>;
export type CreateApprovalMutationBody = BodyType<ApprovalInput>;
export type CreateApprovalMutationError = ErrorType<unknown>;

/**
 * @summary Submit an approval action
 */
export const useCreateApproval = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof createApproval>>,
    TError,
    { id: number; data: BodyType<ApprovalInput> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof createApproval>>,
  TError,
  { id: number; data: BodyType<ApprovalInput> },
  TContext
> => {
  return useMutation(getCreateApprovalMutationOptions(options));
};

/**
 * @summary List comments for a plan
 */
export const getListCommentsUrl = (id: number) => {
  return `/api/plans/${id}/comments`;
};

export const listComments = async (
  id: number,
  options?: RequestInit,
): Promise<Comment[]> => {
  return customFetch<Comment[]>(getListCommentsUrl(id), {
    ...options,
    method: "GET",
  });
};

export const getListCommentsQueryKey = (id: number) => {
  return [`/api/plans/${id}/comments`] as const;
};

export const getListCommentsQueryOptions = <
  TData = Awaited<ReturnType<typeof listComments>>,
  TError = ErrorType<unknown>,
>(
  id: number,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof listComments>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

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

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

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

export type ListCommentsQueryResult = NonNullable<
  Awaited<ReturnType<typeof listComments>>
>;
export type ListCommentsQueryError = ErrorType<unknown>;

/**
 * @summary List comments for a plan
 */

export function useListComments<
  TData = Awaited<ReturnType<typeof listComments>>,
  TError = ErrorType<unknown>,
>(
  id: number,
  options?: {
    query?: UseQueryOptions<
      Awaited<ReturnType<typeof listComments>>,
      TError,
      TData
    >;
    request?: SecondParameter<typeof customFetch>;
  },
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
  const queryOptions = getListCommentsQueryOptions(id, options);

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

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

/**
 * @summary Add a comment to a plan
 */
export const getCreateCommentUrl = (id: number) => {
  return `/api/plans/${id}/comments`;
};

export const createComment = async (
  id: number,
  commentInput: CommentInput,
  options?: RequestInit,
): Promise<Comment> => {
  return customFetch<Comment>(getCreateCommentUrl(id), {
    ...options,
    method: "POST",
    headers: { "Content-Type": "application/json", ...options?.headers },
    body: JSON.stringify(commentInput),
  });
};

export const getCreateCommentMutationOptions = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof createComment>>,
    TError,
    { id: number; data: BodyType<CommentInput> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
  Awaited<ReturnType<typeof createComment>>,
  TError,
  { id: number; data: BodyType<CommentInput> },
  TContext
> => {
  const mutationKey = ["createComment"];
  const { mutation: mutationOptions, request: requestOptions } = options
    ? options.mutation &&
      "mutationKey" in options.mutation &&
      options.mutation.mutationKey
      ? options
      : { ...options, mutation: { ...options.mutation, mutationKey } }
    : { mutation: { mutationKey }, request: undefined };

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

    return createComment(id, data, requestOptions);
  };

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

export type CreateCommentMutationResult = NonNullable<
  Awaited<ReturnType<typeof createComment>>
>;
export type CreateCommentMutationBody = BodyType<CommentInput>;
export type CreateCommentMutationError = ErrorType<unknown>;

/**
 * @summary Add a comment to a plan
 */
export const useCreateComment = <
  TError = ErrorType<unknown>,
  TContext = unknown,
>(options?: {
  mutation?: UseMutationOptions<
    Awaited<ReturnType<typeof createComment>>,
    TError,
    { id: number; data: BodyType<CommentInput> },
    TContext
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseMutationResult<
  Awaited<ReturnType<typeof createComment>>,
  TError,
  { id: number; data: BodyType<CommentInput> },
  TContext
> => {
  return useMutation(getCreateCommentMutationOptions(options));
};

/**
 * @summary Get dashboard statistics
 */
export const getGetDashboardStatsUrl = () => {
  return `/api/dashboard/stats`;
};

export const getDashboardStats = async (
  options?: RequestInit,
): Promise<DashboardStats> => {
  return customFetch<DashboardStats>(getGetDashboardStatsUrl(), {
    ...options,
    method: "GET",
  });
};

export const getGetDashboardStatsQueryKey = () => {
  return [`/api/dashboard/stats`] as const;
};

export const getGetDashboardStatsQueryOptions = <
  TData = Awaited<ReturnType<typeof getDashboardStats>>,
  TError = ErrorType<unknown>,
>(options?: {
  query?: UseQueryOptions<
    Awaited<ReturnType<typeof getDashboardStats>>,
    TError,
    TData
  >;
  request?: SecondParameter<typeof customFetch>;
}) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

  const queryKey = queryOptions?.queryKey ?? getGetDashboardStatsQueryKey();

  const queryFn: QueryFunction<
    Awaited<ReturnType<typeof getDashboardStats>>
  > = ({ signal }) => getDashboardStats({ signal, ...requestOptions });

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

export type GetDashboardStatsQueryResult = NonNullable<
  Awaited<ReturnType<typeof getDashboardStats>>
>;
export type GetDashboardStatsQueryError = ErrorType<unknown>;

/**
 * @summary Get dashboard statistics
 */

export function useGetDashboardStats<
  TData = Awaited<ReturnType<typeof getDashboardStats>>,
  TError = ErrorType<unknown>,
>(options?: {
  query?: UseQueryOptions<
    Awaited<ReturnType<typeof getDashboardStats>>,
    TError,
    TData
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
  const queryOptions = getGetDashboardStatsQueryOptions(options);

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

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

/**
 * @summary Get recent plans
 */
export const getGetRecentPlansUrl = () => {
  return `/api/dashboard/recent-plans`;
};

export const getRecentPlans = async (
  options?: RequestInit,
): Promise<Plan[]> => {
  return customFetch<Plan[]>(getGetRecentPlansUrl(), {
    ...options,
    method: "GET",
  });
};

export const getGetRecentPlansQueryKey = () => {
  return [`/api/dashboard/recent-plans`] as const;
};

export const getGetRecentPlansQueryOptions = <
  TData = Awaited<ReturnType<typeof getRecentPlans>>,
  TError = ErrorType<unknown>,
>(options?: {
  query?: UseQueryOptions<
    Awaited<ReturnType<typeof getRecentPlans>>,
    TError,
    TData
  >;
  request?: SecondParameter<typeof customFetch>;
}) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

  const queryKey = queryOptions?.queryKey ?? getGetRecentPlansQueryKey();

  const queryFn: QueryFunction<Awaited<ReturnType<typeof getRecentPlans>>> = ({
    signal,
  }) => getRecentPlans({ signal, ...requestOptions });

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

export type GetRecentPlansQueryResult = NonNullable<
  Awaited<ReturnType<typeof getRecentPlans>>
>;
export type GetRecentPlansQueryError = ErrorType<unknown>;

/**
 * @summary Get recent plans
 */

export function useGetRecentPlans<
  TData = Awaited<ReturnType<typeof getRecentPlans>>,
  TError = ErrorType<unknown>,
>(options?: {
  query?: UseQueryOptions<
    Awaited<ReturnType<typeof getRecentPlans>>,
    TError,
    TData
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
  const queryOptions = getGetRecentPlansQueryOptions(options);

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

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

/**
 * @summary Get plans grouped by status
 */
export const getGetPlansByStatusUrl = () => {
  return `/api/dashboard/plans-by-status`;
};

export const getPlansByStatus = async (
  options?: RequestInit,
): Promise<StatusCount[]> => {
  return customFetch<StatusCount[]>(getGetPlansByStatusUrl(), {
    ...options,
    method: "GET",
  });
};

export const getGetPlansByStatusQueryKey = () => {
  return [`/api/dashboard/plans-by-status`] as const;
};

export const getGetPlansByStatusQueryOptions = <
  TData = Awaited<ReturnType<typeof getPlansByStatus>>,
  TError = ErrorType<unknown>,
>(options?: {
  query?: UseQueryOptions<
    Awaited<ReturnType<typeof getPlansByStatus>>,
    TError,
    TData
  >;
  request?: SecondParameter<typeof customFetch>;
}) => {
  const { query: queryOptions, request: requestOptions } = options ?? {};

  const queryKey = queryOptions?.queryKey ?? getGetPlansByStatusQueryKey();

  const queryFn: QueryFunction<
    Awaited<ReturnType<typeof getPlansByStatus>>
  > = ({ signal }) => getPlansByStatus({ signal, ...requestOptions });

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

export type GetPlansByStatusQueryResult = NonNullable<
  Awaited<ReturnType<typeof getPlansByStatus>>
>;
export type GetPlansByStatusQueryError = ErrorType<unknown>;

/**
 * @summary Get plans grouped by status
 */

export function useGetPlansByStatus<
  TData = Awaited<ReturnType<typeof getPlansByStatus>>,
  TError = ErrorType<unknown>,
>(options?: {
  query?: UseQueryOptions<
    Awaited<ReturnType<typeof getPlansByStatus>>,
    TError,
    TData
  >;
  request?: SecondParameter<typeof customFetch>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
  const queryOptions = getGetPlansByStatusQueryOptions(options);

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

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