import { useTRPC, type RouterInputs, type RouterOutputs } from "../trpc";
import { useQueryClient } from "@tanstack/react-query";
import { useMutation, type UseMutationResult } from "@tanstack/react-query";
/**
 * 定义 MutationType 类型，用于提取指定实体类型的特定 mutation 方法名。
 * @template T - 实体类型的键名（如 'post', 'user'）
 * @description 该类型通过遍历 RouterInputs[T] 的键名，筛选出符合条件的 mutation 方法名（如 'create', 'update' 等）。
 */
type MutationType<T extends keyof RouterInputs> = keyof {
	[K in keyof RouterInputs[T]]: K extends
	| "create"
	| "update"
	| "deleteMany"
	| "softDeleteByIds"
	| "restoreByIds"
	| "updateOrder"
	? RouterInputs[T][K]
	: never;
};
/**
 * 定义 MutationOptions 类型，用于配置特定 mutation 方法的回调函数。
 * @template T - 实体类型的键名
 * @template K - mutation 方法名
 * @description 该类型包含一个可选的 onSuccess 回调函数，用于在 mutation 成功时执行。
 */
type MutationOptions<
	T extends keyof RouterInputs,
	K extends MutationType<T>,
> = {
	onSuccess?: (
		data: RouterOutputs[T][K], // mutation 成功后的返回数据
		variables: RouterInputs[T][K], // mutation 的输入参数
		context?: unknown // 可选的上下文信息
	) => void;
};

/**
 * 定义 EntityOptions 类型，用于配置实体类型的所有 mutation 方法的回调函数。
 * @template T - 实体类型的键名
 * @description 该类型是一个对象，键为 mutation 方法名，值为对应的 MutationOptions 配置。
 */
type EntityOptions<T extends keyof RouterInputs> = {
	[K in MutationType<T>]?: MutationOptions<T, K>;
};

/**
 * 工具类型：更新为 TanStack Query 的 UseMutationResult 类型。
 * @template T - 实体类型的键名
 * @template K - mutation 方法名
 * @description 该类型用于定义 mutation 函数的返回类型，适配新版 tRPC。
 */
export type MutationResult<
	T extends keyof RouterInputs,
	K extends MutationType<T>,
> = UseMutationResult<
	RouterOutputs[T][K], // mutation 成功后的返回数据
	Error, // mutation 的错误类型
	RouterInputs[T][K], // mutation 的输入参数
	unknown // mutation 的上下文类型
>;

/**
 * 自定义 Hook：用于处理实体的 mutation 操作，并内置缓存失效机制。
 * @template T - 实体类型的键名（如 'post', 'user'）
 * @param {T} key - 实体键名
 * @param {EntityOptions<T>} [options] - 可选的 mutation 回调函数配置
 * @returns 返回一个包含多个 mutation 函数的对象
 * @description 该 Hook 封装了常见的 mutation 操作（如 create, update, deleteMany 等），并在每次 mutation 成功后自动失效相关缓存。
 */
export function useEntity<T extends keyof RouterInputs>(
	key: T,
	options?: EntityOptions<T>
) {
	const trpc = useTRPC();
	const queryClient = useQueryClient();
	/**
	 * 创建 mutation 处理函数。
	 * @template K - mutation 方法名
	 * @param {K} mutation - mutation 方法名
	 * @returns 返回一个配置好的 mutation 函数
	 * @description 该函数根据传入的 mutation 方法名，生成对应的 mutation 函数，并配置 onSuccess 回调。
	 */

	const createMutationHandler = <K extends MutationType<T>>(mutation: K) => {
		// 获取对应的 tRPC mutation 配置
		const mutationOptions = trpc[key as keyof typeof trpc][mutation as any].mutationOptions();

		// 使用 TanStack Query 的 useMutation 创建 mutation
		return useMutation({
			...mutationOptions,
			onSuccess: (data, variables, context) => {
				// 调用原始配置的 onSuccess 回调（如果有）
				mutationOptions.onSuccess?.(data as any, variables as any, context);

				// 失效指定实体的缓存
				queryClient.invalidateQueries({ queryKey: [key] });

				// 调用用户自定义的 onSuccess 回调
				options?.[mutation]?.onSuccess?.(data as any, variables as any, context);
			},
		}) as MutationResult<T, K>;
	};

	// 返回包含多个 mutation 函数的对象
	return {
		create: createMutationHandler("create"),
		createCourse: createMutationHandler("createCourse"),
		update: createMutationHandler("update"),
		deleteMany: createMutationHandler("deleteMany"),
		softDeleteByIds: createMutationHandler("softDeleteByIds"),
		restoreByIds: createMutationHandler("restoreByIds"),
		updateOrder: createMutationHandler("updateOrder"),
		updateOrderByIds: createMutationHandler("updateOrderByIds"),
	};
}
