import { api } from "../trpc";
import { PostParams } from "../../singleton/DataHolder";

export function useVisitor() {
	const utils = api.useUtils();
	const postParams = PostParams.getInstance();

	const create = api.visitor.create.useMutation({
		onSuccess() {
			utils.visitor.invalidate();

			// utils.post.invalidate();
		},
	});
	/**
	 * 通用的乐观更新mutation工厂函数
	 * @param updateFn 更新数据的具体逻辑函数
	 * @returns 封装后的mutation配置对象
	 */
	const createOptimisticMutation = (
		updateFn: (item: any, variables: any) => any
	) => ({
		//在请求发送前执行本地数据预更新
		onMutate: async (variables: any) => {
			const previousDataList: any[] = [];
			const previousDetailDataList: any[] = [];

			// 处理列表数据
			const paramsList = postParams.getItems();
			for (const params of paramsList) {
				await utils.post.findManyWithCursor.cancel();
				const previousData =
					utils.post.findManyWithCursor.getInfiniteData({
						...params,
					});
				previousDataList.push(previousData);
				utils.post.findManyWithCursor.setInfiniteData(
					{
						...params,
					},
					(oldData) => {
						if (!oldData) return oldData;
						return {
							...oldData,
							pages: oldData.pages.map((page) => ({
								...page,
								items: (page.items as any).map((item) =>
									item.id === variables?.postId
										? updateFn(item, variables)
										: item
								),
							})),
						};
					}
				);
			}

			// 处理详情数据
			const detailParamsList = postParams.getDetailItems();
			for (const params of detailParamsList) {
				await utils.post.findFirst.cancel();
				const previousDetailData = utils.post.findFirst.getData(params);
				previousDetailDataList.push(previousDetailData);
				utils.post.findFirst.setData(params, (oldData) => {
					if (!oldData) return oldData;
					return oldData.id === variables?.postId
						? updateFn(oldData, variables)
						: oldData;
				});
			}

			return { previousDataList, previousDetailDataList };
		},
		// 错误处理：数据回滚
		onError: (_err: any, _variables: any, context: any) => {
			const paramsList = postParams.getItems();
			paramsList.forEach((params, index) => {
				if (context?.previousDataList?.[index]) {
					utils.post.findManyWithCursor.setInfiniteData(
						{ ...params },
						context.previousDataList[index]
					);
				}
			});
		},
		// 成功后的缓存失效
		onSuccess: async (_: any, variables: any) => {
			await Promise.all([
				utils.visitor.invalidate(),
				utils.post.findFirst.invalidate({
					where: {
						id: (variables as any)?.postId,
					},
				}),
				utils.post.findManyWithCursor.invalidate(),
			]);
		},
	});
	// 定义具体的mutation
	const read = api.visitor.create.useMutation(
		createOptimisticMutation((item) => ({
			...item,
			views: (item.views || 0) + 1,
			readed: true,
		}))
	);
	const like = api.visitor.create.useMutation(
		createOptimisticMutation((item) => ({
			...item,
			likes: (item.likes || 0) + 1,
			liked: true,
		}))
	);
	const unLike = api.visitor.deleteMany.useMutation(
		createOptimisticMutation((item) => ({
			...item,
			likes: item.likes - 1 || 0,
			liked: false,
		}))
	);

	const hate = api.visitor.create.useMutation(
		createOptimisticMutation((item) => ({
			...item,
			hates: (item.hates || 0) + 1,
			hated: true,
		}))
	);
	const unHate = api.visitor.deleteMany.useMutation(
		createOptimisticMutation((item) => ({
			...item,
			hates: item.hates - 1 || 0,
			hated: false,
		}))
	);

	const addStar = api.visitor.create.useMutation(
		createOptimisticMutation((item) => ({
			...item,
			star: true,
		}))
	);

	const deleteStar = api.visitor.deleteMany.useMutation(
		createOptimisticMutation((item) => ({
			...item,
			star: false,
		}))
	);

	const deleteMany = api.visitor.deleteMany.useMutation({
		onSuccess() {
			utils.visitor.invalidate();
		},
	});

	const createMany = api.visitor.createMany.useMutation({
		onSuccess() {
			utils.visitor.invalidate();
			utils.message.invalidate();
			utils.post.invalidate();
		},
	});

	return {
		postParams,
		create,
		createMany,
		deleteMany,
		read,
		addStar,
		deleteStar,
		like,
		unLike,
		hate,
		unHate,
	};
}
