import React, { useState, useRef } from 'react';

import { Avatar, TextField, IconButton } from '@mui/material';
import CancelIcon from '@mui/icons-material/Cancel';

import { Comment } from '../types/comment';
import { useUser } from '../contexts/UserContext';
import api from '../utils/api';

interface CommentSectionProps {
    articleId: number;
    comments: Comment[];
}

const CommentSection = (props: CommentSectionProps) => {
    const [comments, setComments] = useState<Comment[]>(props.comments);
    const [commentText, setCommentText] = useState('');
    const [replyingTo, setReplyingTo] = useState<{ path: number[]; author: string } | null>(null);
    const mainInputRef = useRef<HTMLInputElement>(null);
    const { user } = useUser();



    const formatDate = (isoString: string) => {
        return new Date(isoString).toLocaleString();
    };

    const postComment = async (payload: { article_id: number; parent_comment_id: number | null; text: string }) => {
        try {
            const response = await api.post('/comments/add', payload);
            if (response.data.success) {
                // Create a comment object locally since the server only returns success.
                return {
                    // TODO: replace with an actual unique id from the server.
                    id: Date.now(),
                    author: user ? user.username : 'Anonymous',
                    text: payload.text,
                    created_at: new Date().toISOString(),
                    child_comments: []
                } as unknown as Comment;
            } else {
                console.error('Error posting comment: success flag false');
                return null;
            }
        } catch (error) {
            console.error('Error posting comment:', error);
            return null;
        }
    };

    const handleAddComment = async () => {
        if (!user || !commentText.trim()) return;

        // Build the payload for a new comment.
        const payload = {
            article_id: props.articleId,
            parent_comment_id: null,
            text: commentText.trim()
        };

        const newComment = await postComment(payload);
        if (newComment) {
            // Append the new comment.
            setComments([...comments, newComment]);
            setCommentText('');
        }
    };

    const handleReply = (commentInfo: { path: number[]; author: string }) => {
        if (!user) return;
        setReplyingTo(commentInfo);
        setCommentText('');
        if (mainInputRef.current) {
            mainInputRef.current.focus();
        }
    };

    const cancelReply = () => {
        setReplyingTo(null);
        setCommentText('');
    };

    const submitReply = async () => {
        if (!user || !commentText.trim() || !replyingTo) return;

        const parent_comment_id = replyingTo.path[replyingTo.path.length - 1];
        const payload = {
            article_id: props.articleId,
            parent_comment_id,
            text: commentText.trim()
        };

        const replyFromServer = await postComment(payload);
        if (!replyFromServer) return;

        // Ensure the reply has a child_comments array.
        const reply: Comment = { ...replyFromServer, child_comments: [] };

        let updatedComments = [...comments];

        function updateNestedComments(comments: Comment[], path: number[], index = 0): Comment[] {
            if (index >= path.length - 1) {
                const targetId = path[index];
                return comments.map(comment => {
                    if (comment.id === targetId) {
                        return {
                            ...comment,
                            child_comments: [...comment.child_comments, reply]
                        };
                    }
                    return comment;
                });
            }

            const currentId = path[index];
            return comments.map(comment => {
                if (comment.id === currentId) {
                    return {
                        ...comment,
                        child_comments: updateNestedComments(comment.child_comments, path, index + 1)
                    };
                }
                return comment;
            });
        }

        updatedComments = updateNestedComments(updatedComments, replyingTo.path);

        setComments(updatedComments);
        setReplyingTo(null);
        setCommentText('');
    };

    // Added handler to trigger handleAddComment on Enter key.
    const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
        if (e.key === 'Enter' && !e.shiftKey) {
            e.preventDefault();
            if (replyingTo) {
                submitReply();
            } else {
                handleAddComment();
            }
        }
    };

    const NestedReply = ({ reply, path = [] }: { reply: Comment; path?: number[] }) => {
        const replyPath = [...path, reply.id];
        return (
            <div className="pl-8 py-2 border-l-2 border-gray-200">
                <div className="flex items-center space-x-2">
                    <Avatar className="w-6 h-6 text-xs">
                        {reply.author.charAt(0)}
                    </Avatar>
                    <div className="font-medium text-sm">{reply.author}</div>
                    <div className="text-xs text-gray-500">{formatDate(reply.created_at)}</div>
                </div>
                <div className="py-2 text-sm">{reply.text}</div>
                {user && (
                    <div className="flex items-center space-x-4">
                        <button
                            className="text-xs text-green-950 hover:text-green-800"
                            onClick={() => handleReply({ path: replyPath, author: reply.author })}
                        >
                            Reply
                        </button>
                    </div>
                )}
                {reply.child_comments && reply.child_comments.length > 0 && (
                    <div className="mt-2">
                        {reply.child_comments.map(nestedReply => (
                            <NestedReply
                                key={nestedReply.id}
                                reply={nestedReply}
                                path={replyPath}
                            />
                        ))}
                    </div>
                )}
            </div>
        );
    };

    const Reply = ({ reply, parentId }: { reply: Comment; parentId: number }) => {
        const replyPath = [parentId, reply.id];
        return (
            <div className="ml-12 mt-2 pb-2">
                <div className="flex items-center space-x-2">
                    <Avatar className="w-6 h-6 text-xs bg-green-600">
                        {reply.author.charAt(0)}
                    </Avatar>
                    <div className="font-medium text-sm">{reply.author}</div>
                    <div className="text-xs text-gray-500">{formatDate(reply.created_at)}</div>
                </div>
                <div className="py-2 text-sm">{reply.text}</div>
                {user && (
                    <div className="flex items-center space-x-4">
                        <button
                            className="text-xs text-green-950 hover:text-green-800"
                            onClick={() => handleReply({ path: replyPath, author: reply.author })}
                        >
                            Reply
                        </button>
                    </div>
                )}
                {reply.child_comments && reply.child_comments.length > 0 && (
                    <div className="ml-8 mt-2 border-l-2 border-gray-200">
                        {reply.child_comments.map(nestedReply => (
                            <NestedReply
                                key={nestedReply.id}
                                reply={nestedReply}
                                path={replyPath}
                            />
                        ))}
                    </div>
                )}
            </div>
        );
    };

    const CommentComponent = ({ comment }: { comment: Comment }) => {
        const commentPath = [comment.id];
        return (
            <div className="py-4 border-b border-gray-200">
                <div className="flex">
                    <div className="mr-3">
                        <Avatar className="bg-blue-600">
                            {comment.author.charAt(0)}
                        </Avatar>
                    </div>
                    <div className="flex-1">
                        <div className="flex items-center space-x-2">
                            <div className="font-medium">{comment.author}</div>
                            <div className="text-sm text-gray-500">{formatDate(comment.created_at)}</div>
                        </div>
                        <div className="py-2">{comment.text}</div>
                        {user && (
                            <div className="flex items-center space-x-4">
                                <button
                                    className="text-sm text-green-950 hover:text-green-700"
                                    onClick={() => handleReply({ path: commentPath, author: comment.author })}
                                >
                                    Reply
                                </button>
                            </div>
                        )}
                        {comment.child_comments.length > 0 && (
                            <div className="mt-3">
                                {comment.child_comments.map(reply => (
                                    <Reply
                                        key={reply.id}
                                        reply={reply}
                                        parentId={comment.id}
                                    />
                                ))}
                            </div>
                        )}
                    </div>
                </div>
            </div>
        );
    };

    return (
        <>
            <div className="flex justify-center w-full py-2 bg-yellow-50">
                <div className="w-full max-w-6xl rounded-lg">
                    <div className="px-6 py-4 border-b border-gray-200">
                        <h2 className="text-xl font-semibold text-gray-800">
                            Komentáře:
                        </h2>
                    </div>

                    <div className="px-6">
                        {comments.length > 0 ? (
                            comments.map(comment => (
                                <CommentComponent key={comment.id} comment={comment} />
                            ))
                        ) : (
                            <div className="py-8 text-center text-gray-500">
                                Zatím žádné komentáře
                            </div>
                        )}
                    </div>

                    {user ? (
                        <div className="p-6 bg-yellow-50 border-t border-gray-200">
                            {replyingTo && (
                                <div className="flex items-center justify-between mb-2 p-2 rounded">
                                    <span className="text-base text-green-950">
                                        Odpovídáte {replyingTo.author}
                                    </span>
                                    <IconButton size="small" onClick={cancelReply}>
                                        <p className="text-red-600 text-sm">Zrušit odpověď </p>
                                        <CancelIcon fontSize="small" />
                                    </IconButton>
                                </div>
                            )}
                            <TextField
                                fullWidth
                                multiline
                                rows={6}
                                value={commentText}
                                onChange={(e) => setCommentText(e.target.value)}
                                variant="outlined"
                                inputRef={mainInputRef}
                                onKeyDown={handleKeyDown}
                                className="bg-white"
                            />
                            <div className="mt-3 flex justify-end">
                                <button
                                    className="px-4 py-2 bg-green-950 text-white rounded hover:bg-green-800 transition duration-200"
                                    onClick={() => {
                                        if (replyingTo) {
                                            submitReply();
                                        } else {
                                            handleAddComment();
                                        }
                                    }}
                                >
                                    Odeslat
                                </button>
                            </div>
                        </div>
                    ) : (
                        <div className="p-6 bg-yellow-50 border-t border-gray-200 text-center text-gray-500">
                            Přihlaste se, abyste mohli psát komentáře.
                        </div>
                    )}
                </div>
            </div>
        </>
    );
};

export default CommentSection;