import { useContext, useMemo, useEffect } from "react";
import { PostDetailContext } from "./context/PostDetailContext";
import { api, useVisitor } from "@nice/client";
import { postDetailSelect, PostDto, PostType, Prisma } from "@nice/common";
import { motion, AnimatePresence } from "framer-motion";
import PostCommentCard from "./PostCommentCard";
import { useInView } from "react-intersection-observer";
import { LoadingCard } from "@web/src/components/models/post/detail/LoadingCard";
import { Spin } from "antd";
export default function PostCommentList() {
	const { post } = useContext(PostDetailContext);
	const { ref: loadMoreRef, inView } = useInView();
	const { postParams } = useVisitor();
	const receiverIds = useMemo(() => {
		return (
			post?.receivers?.map((receiver) => receiver.id).filter(Boolean) ||
			[]
		);
	}, [post]);
	const officialParams: Prisma.PostFindManyArgs = useMemo(
		() => ({
			where: {
				parentId: post?.id,
				type: PostType.POST_COMMENT,
				authorId: { in: receiverIds },
			},
			select: postDetailSelect,
			orderBy: [{ createdAt: "desc" }],
			take: 5,
		}),
		[post, receiverIds]
	);

	const nonOfficialParams: Prisma.PostFindManyArgs = useMemo(
		() => ({
			where: {
				parentId: post?.id,
				type: PostType.POST_COMMENT,
				OR: [
					{ authorId: null }, // 允许 authorId 为 null
					{ authorId: { notIn: receiverIds } }, // 排除 receiverIds 中的 authorId
				],
			},
			select: postDetailSelect,
			orderBy: [{ createdAt: "desc" }],
			take: 5,
		}),
		[post, receiverIds]
	);

	const {
		data: officialData,
		fetchNextPage: fetchNextOfficialPage,
		isFetchingNextPage: isFetchingNextOfficialPage,
		hasNextPage: hasNextOfficialPage,
		isLoading: isOfficialLoading,
	} = api.post.findManyWithCursor.useInfiniteQuery(officialParams, {
		enabled: !!post?.id,
		getNextPageParam: (lastPage) => lastPage.nextCursor,
	});

	const {
		data: nonOfficialData,
		fetchNextPage: fetchNextNonOfficialPage,
		isFetchingNextPage: isFetchingNextNonOfficialPage,
		hasNextPage: hasNextNonOfficialPage,
		isLoading: isNonOfficialLoading,
	} = api.post.findManyWithCursor.useInfiniteQuery(nonOfficialParams, {
		enabled: !!post?.id,
		getNextPageParam: (lastPage) => lastPage.nextCursor,
	});

	const officialItems = useMemo(
		() =>
			((officialData?.pages as any)?.flatMap(
				(page) => page.items
			) as any) || [],
		[officialData]
	);

	const nonOfficialItems = useMemo(
		() =>
			(nonOfficialData?.pages as any)?.flatMap((page) => page.items) ||
			[],
		[nonOfficialData]
	);

	const isLoading = isOfficialLoading || isNonOfficialLoading;
	useEffect(() => {
		if (post?.id) {
			postParams.addItem(officialParams);
			postParams.addItem(nonOfficialParams);
			return () => {
				postParams.removeItem(officialParams);
				postParams.removeItem(nonOfficialParams);
			};
		}
	}, [post, officialParams, nonOfficialParams]);

	const convertToPostDto = (item: any): PostDto => ({
		...item,
		createdAt: new Date(item.createdAt),
		updatedAt: new Date(item.updatedAt),
		deletedAt: item.deletedAt ? new Date(item.deletedAt) : new Date(0),
	});

	const items = useMemo(() => {
		return [
			...officialItems.map(convertToPostDto),
			...nonOfficialItems.map(convertToPostDto),
		];
	}, [officialItems, nonOfficialItems]);

	useEffect(() => {
		if (inView) {
			if (hasNextOfficialPage && !isFetchingNextOfficialPage) {
				fetchNextOfficialPage();
			} else if (
				hasNextNonOfficialPage &&
				!isFetchingNextNonOfficialPage
			) {
				fetchNextNonOfficialPage();
			}
		}
	}, [
		inView,
		hasNextOfficialPage,
		hasNextNonOfficialPage,
		isFetchingNextOfficialPage,
		isFetchingNextNonOfficialPage,
		fetchNextOfficialPage,
		fetchNextNonOfficialPage,
	]);

	if (isLoading) {
		return <LoadingCard />;
	}

	if (!items.length) {
		return null;
	}

	return (
		<div className="   flex flex-col gap-4 p-6">
			<AnimatePresence mode="popLayout">
				{items.map((comment, index) => (
					<motion.div
						key={comment.id}
						initial={{ opacity: 0, y: 20 }}
						animate={{ opacity: 1, y: 0 }}
						exit={{ opacity: 0, scale: 0.95 }}
						transition={{
							duration: 0.2,
							delay: index * 0.05,
						}}>
						<PostCommentCard
							post={comment}
							index={index}
							isReceiverComment={receiverIds.includes(
								comment.authorId
							)}
						/>
					</motion.div>
				))}
			</AnimatePresence>

			{/* 加载更多触发器 */}
			<div ref={loadMoreRef} className="h-20">
				{isFetchingNextOfficialPage || isFetchingNextNonOfficialPage ? (
					<Spin></Spin>
				) : (
					items.length > 0 &&
					!hasNextOfficialPage &&
					!hasNextNonOfficialPage && (
						<motion.div
							initial={{ opacity: 0, y: 10 }}
							animate={{ opacity: 1, y: 0 }}
							transition={{ duration: 0.5 }}
							className="flex flex-col items-center py-4 space-y-2">
							<span className="text-sm text-gray-500 font-medium">
								已加载全部回复
							</span>
						</motion.div>
					)
				)}
			</div>
		</div>
	);
}
