import { AxiosErrorResponse, CommentLike, Replies, StudyGroupTaskComment } from '@/types';
import { errorMessageFormatter, stringAvatar, stringToColor } from '@/utils';
import { dateTimeTransformer } from '@/utils/timeTransformer';
import { Avatar, Button, Divider, Empty, Tooltip } from 'antd';
import HtmlParser from '../HtmlParser';
import { useTranslation } from 'react-i18next';
import { useMutation, useQuery } from '@tanstack/react-query';
import { getReplies, getTaskCommentLikes, likeComment } from '@/services/study-group';
import { toast } from 'react-toastify';
import { CommentOutlined, LikeFilled, LikeOutlined } from '@ant-design/icons';
import { useState } from 'react';
import { useMemberContext } from '@/providers/MemberContext';
import ReplyModal from './modals/Reply';

interface RenderReplyProps {
    studyGroupTaskId: string;
    commentId: string;
}

const RenderReply: React.FC<RenderReplyProps> = ({ studyGroupTaskId, commentId }) => {
    const { t } = useTranslation(['study-group-task', 'common']);
    const { member } = useMemberContext();

    const [expandedCommentId, setExpandedCommentId] = useState<string | null>();
    const [expandedCommentIdArray, setExpandedCommentIdArray] = useState<string[]>([]);

    const [action, setAction] = useState<string>();

    const replyQuery = useQuery({
        queryKey: ['replies', studyGroupTaskId, commentId],
        enabled: !!commentId,
        queryFn: async () => {
            const res = await getReplies(studyGroupTaskId, commentId);
            return res.data;
        },
        onError: (error: AxiosErrorResponse & Error) => {
            toast.error(t(errorMessageFormatter(error)));
        },
    });
    const replyList = replyQuery.data;

    // Own reply always first followed by others
    replyList?.sort((a: Replies, b: Replies) => {
        if (a.member?.id === member?.id) {
            return -1;
        }
        return 1;
    });

    const commentLikesQuery = useQuery({
        queryKey: ['comment-likes', studyGroupTaskId],
        enabled: !!studyGroupTaskId,
        queryFn: async () => {
            const res = await getTaskCommentLikes(studyGroupTaskId);

            return res.data;
        },
        onError: (error: AxiosErrorResponse & Error) => {
            toast.error(t(errorMessageFormatter(error)));
        },
    });
    const commentLikesData = commentLikesQuery.data;

    const likeCommentMutation = useMutation({
        mutationFn: async (studyGroupTaskCommentId: string) => {
            const response = await likeComment(studyGroupTaskCommentId, member?.id as string, studyGroupTaskId);

            return response.data;
        },
        onSuccess: () => {
            commentLikesQuery.refetch();
        },
    });

    const onResetHandler = () => {
        setAction('');
    };

    const handleSetExpandedCommentId = (commentId: string) => {
        setExpandedCommentId(commentId === expandedCommentId ? null : commentId);
        setExpandedCommentIdArray(
            expandedCommentIdArray.includes(commentId)
                ? expandedCommentIdArray.filter((id) => id !== commentId)
                : [...expandedCommentIdArray, commentId],
        );
    };

    const handleLike = async (studyGroupTaskCommentId: string) => {
        // Check if the comment is already liked by the user
        const alreadyLiked = commentLikesData?.some(
            (like: CommentLike) => like.studyGroupTaskCommentId === studyGroupTaskCommentId && like.memberId === member?.id,
        );

        // Perform like/unlike action based on the current state
        if (alreadyLiked) {
            // Unlike the comment
            await toast.promise(likeCommentMutation.mutateAsync(studyGroupTaskCommentId), {
                pending: t('common:unliking-comment'),
                success: t('common:comment-unliked'),
                error: {
                    render({ data }) {
                        return t(errorMessageFormatter(data as AxiosErrorResponse));
                    },
                },
            });
        } else {
            // Like the comment
            await toast.promise(likeCommentMutation.mutateAsync(studyGroupTaskCommentId), {
                pending: t('common:liking-comment'),
                success: t('common:comment-liked'),
                error: {
                    render({ data }) {
                        return t(errorMessageFormatter(data as AxiosErrorResponse));
                    },
                },
            });
        }
    };

    const renderLikeButton = (likes: Replies) => {
        const liked = commentLikesData?.some((like: CommentLike) => like.studyGroupTaskCommentId === likes.id && like.memberId === member?.id);
        const likesCount = commentLikesData?.filter((like: CommentLike) => like.studyGroupTaskCommentId === likes.id).length;

        return (
            <div className="flex flex-row gap-1 items-center">
                <Tooltip title={liked ? t('common:unlike') : t('common:like')}>
                    <Button
                        type="text"
                        shape="circle"
                        size="middle"
                        icon={liked ? <LikeFilled style={{ color: '#597ef7' }} /> : <LikeOutlined />}
                        onClick={() => handleLike(likes.id)}
                        loading={likeCommentMutation.isLoading}
                    />
                </Tooltip>
                <span className="text-xs sm:text-sm ml-1">{likesCount}</span>
            </div>
        );
    };

    if (!replyList || replyList.length === 0) return <Empty description={t('no-replies-available')} className="mb-2" />;

    return (
        <>
            {replyList.map((reply: Replies) => (
                <div key={reply.id} className="flex flex-col gap-2 mb-6 border-solid rounded-xl border-gray-200 hover:shadow-md">
                    <div className="p-4 pb-0">
                        <div className="flex flex-row gap-4">
                            <div className="flex flex-col w-full mb-2">
                                <div className="flex flex-row justify-between gap-2">
                                    <div className="flex flex-row gap-2 mb-2">
                                        {reply.member?.preferredName || reply.staff.fullName ? (
                                            <div className="font-semibold flex flex-row items-center gap-2">
                                                <Avatar
                                                    style={{
                                                        backgroundColor: stringToColor(
                                                            reply.member?.preferredName ? reply.member?.preferredName : reply.staff?.fullName,
                                                        ),
                                                    }}
                                                    size={30}
                                                    className="flex items-center flex-row gap-2"
                                                >
                                                    {stringAvatar(reply.member?.preferredName ? reply.member?.preferredName : reply.staff?.fullName)}
                                                </Avatar>
                                                <span className="text-xs sm:text-sm">
                                                    {reply.member?.preferredName ? reply.member?.preferredName : reply.staff?.fullName}
                                                </span>
                                            </div>
                                        ) : (
                                            <div className="font-semibold flex flex-row items-center gap-2">
                                                <Avatar
                                                    style={{
                                                        backgroundColor: stringToColor(
                                                            reply.member?.fullName ? reply.member?.fullName : reply.staff?.fullName,
                                                        ),
                                                    }}
                                                    size={30}
                                                    className="flex items-center flex-row gap-2"
                                                >
                                                    {stringAvatar(reply.member?.fullName ? reply.member?.fullName : reply.staff?.fullName)}
                                                </Avatar>
                                                <span className="text-xs sm:text-sm">
                                                    {reply.member?.fullName ? reply.member?.fullName : reply.staff?.fullName}
                                                </span>
                                            </div>
                                        )}
                                        <div className="text-gray-400 flex items-center text-xs">{dateTimeTransformer(reply.commentDate)}</div>
                                    </div>
                                </div>
                                <div className="text-xs sm:text-sm ml-[38px]">
                                    <HtmlParser html={reply.comment} />
                                </div>
                            </div>
                        </div>
                        <Divider className="my-0" />
                        <div className="flex flex-row items-center gap-x-8">
                            <div className="flex flex-row gap-1 align-middle items-center py-1">{renderLikeButton(reply)}</div>
                            <div className="flex flex-row gap-2">
                                <Button type="text" icon={<CommentOutlined />} onClick={() => handleSetExpandedCommentId(reply.id)}>
                                    {t('replies') + ' (' + reply.Children.length + ')'}
                                </Button>
                            </div>
                        </div>
                        <Divider className="my-0 mb-2" />
                    </div>
                    {expandedCommentIdArray.find((commentId: string) => {
                        return commentId === reply.id;
                    }) && (
                        <div className="p-4 pb-0 bg-gray-50 rounded-lg rounded-t-none">
                            <div className="flex flex-col sm:flex-row sm:justify-between gap-4 sm:gap-0 mb-4">
                                <div className="text-[#343434] text-lg flex items-center">
                                    <b>{t('replies') + ' (' + reply.Children.length + ')'}</b>
                                </div>
                                <ReplyModal onReset={onResetHandler} studyGroupTaskId={studyGroupTaskId} parentId={reply.id} />
                            </div>
                            <RenderReply studyGroupTaskId={studyGroupTaskId} commentId={reply.id} />
                        </div>
                    )}
                </div>
            ))}
        </>
    );
};

export default RenderReply;
