import { FC, useEffect, useRef, useState } from 'react';
import { useAppDispatch, useAppSelector } from '../../../../redux/hooks';
import { setMenuActiveGroupPage } from '../../../../redux/slices/store';
import {
    fetchGroupMessages,
    sendGroupMessage,
    setGroupChatStatus,
} from '../../../../redux/slices/groupChat';
import { MessageItem } from './MessageItem';
import { Send } from '../../../../assets/icons/input';

interface GroupChatProps {
    groupId: number;
}

const CHUNK_SIZE = 10;

export const Chat: FC<GroupChatProps> = ({ groupId }) => {
    const dispatch = useAppDispatch();
    const messages = useAppSelector((s) => s.groupchat.messages[groupId] || []);
    const messagesState = useAppSelector(
        (state) => state.groupchat.fetchMessages.status,
    );
    const lastMessageId = useAppSelector(
        (state) => state.groupchat.lastMessage[groupId] || 0,
    );
    const user = useAppSelector((state) => state.auth);

    const [text, setText] = useState<string>('');
    const [firstMessagesFetch, setFirctMessagesFetch] = useState<boolean>(true);

    const scrollRef = useRef<HTMLDivElement>(null);

    // добавлено: ref для хранения предыдущей высоты
    const prevHeightRef = useRef(0);

    // активируем таб
    useEffect(() => {
        dispatch(setMenuActiveGroupPage('chat'));
    }, []);

    // первичная загрузка
    useEffect(() => {
        dispatch(
            fetchGroupMessages({
                groupId,
                limit: CHUNK_SIZE,
            }),
        );
    }, [groupId]);

    // автоскролл вниз после начальной загрузки (но не при догрузке)
    useEffect(() => {
        const div = scrollRef.current;
        if (!div) return;

        // если prevHeightRef == 0 — значит это не догрузка, а обычная загрузка
        if (prevHeightRef.current === 0) {
            div.scrollTop = div.scrollHeight;
        }
    }, [messages.length]);

    // добавлено: компенсирование скролла при догрузке
    useEffect(() => {
        const div = scrollRef.current;
        if (!div) return;

        if (prevHeightRef.current > 0) {
            const diff = div.scrollHeight - prevHeightRef.current;
            div.scrollTop = diff; // компенсируем смещение

            prevHeightRef.current = 0; // сбрасываем
        }
    }, [messages]);

    useEffect(() => {
        if (messagesState == 'successful') {
            dispatch(
                setGroupChatStatus({ key: 'fetchMessages', status: 'idle' }),
            );
        }
        if (messagesState == 'failed') {
            dispatch(
                setGroupChatStatus({ key: 'fetchMessages', status: 'idle' }),
            );
        }
    }, [messagesState]);

    const lastMessageIdRef = useRef<number | null>(null);

    useEffect(() => {
        lastMessageIdRef.current = lastMessageId;
        if (lastMessageId && firstMessagesFetch) {
            setFirctMessagesFetch(false);
            dispatch(
                fetchGroupMessages({
                    groupId,
                    afterMessageId: lastMessageIdRef.current,
                    timeoutSeconds: 10,
                }),
            );
        }
    }, [messages]);

    useEffect(() => {
        const interval = setInterval(() => {
            if (lastMessageIdRef.current === null) return;

            dispatch(
                fetchGroupMessages({
                    groupId,
                    afterMessageId: lastMessageIdRef.current,
                    timeoutSeconds: 10,
                }),
            );
        }, 10000);

        return () => clearInterval(interval);
    }, [groupId]);

    const handleSend = () => {
        if (!text.trim()) return;

        dispatch(
            sendGroupMessage({
                groupId,
                content: text.trim(),
            }),
        ).then(() => {
            setText('');
            setTimeout(() => {
                const div = scrollRef.current;
                if (div) div.scrollTop = div.scrollHeight;
            }, 0);
        });
    };

    const handleEnter = (e: React.KeyboardEvent<HTMLInputElement>) => {
        if (e.key === 'Enter') {
            e.preventDefault();
            handleSend();
        }
    };

    // догрузка старых сообщений при скролле вверх
    const handleScroll = () => {
        const div = scrollRef.current;
        if (!div) return;

        // если скролл в верхней точке
        if (div.scrollTop === 0) {
            prevHeightRef.current = div.scrollHeight; // запоминаем высоту до загрузки

            const first = messages[0];
            if (!first || first.id == 1) return;

            const beforeId = first.id - CHUNK_SIZE;

            dispatch(
                fetchGroupMessages({
                    groupId,
                    limit: CHUNK_SIZE,
                    afterMessageId: beforeId,
                }),
            );
        }
    };

    return (
        <div className="h-full relative">
            <div className="grid grid-rows-[1fr,40px] h-full relative min-h-0 gap-[20px]">
                <div
                    className="min-h-0 overflow-y-scroll thin-dark-scrollbar"
                    ref={scrollRef}
                    onScroll={handleScroll}
                >
                    <div className="flex flex-col gap-[20px] min-h-0 h-0 px-[16px]">
                        {messages.map((msg, i) => (
                            <MessageItem
                                key={i}
                                message={msg.content}
                                createdAt={msg.createdAt}
                                id={msg.id}
                                groupId={msg.groupId}
                                authorId={msg.authorId}
                                authorUsername={msg.authorUsername}
                                myMessage={msg.authorId == Number(user.id)}
                            />
                        ))}
                    </div>
                </div>

                <label className="bg-liquid-lighter rounded-[10px] cursor-text flex items-center px-[16px]">
                    <input
                        className="w-[calc(100%-50px)] outline-none bg-transparent   placeholder:text-[16px] placeholder:text-liquid-light placeholder:font-medium"
                        value={text}
                        onChange={(e) => setText(e.target.value)}
                        onKeyDown={handleEnter}
                        placeholder="Введите сообщение"
                    />
                    <img
                        src={Send}
                        className=" absolute cursor-pointer right-[16px] active:scale-90 transition-all duration-300"
                        onClick={() => {
                            handleSend();
                        }}
                    />
                </label>
            </div>
        </div>
    );
};
