import React, { useContext, useEffect, useState, useRef } from 'react';
import "./Chat.css";
import ChatHeader from '../ChatHeader';
import ChatMain from '../ChatMain';
import ChatFooter from '../ChatFooter';
import { SocketContext } from '../../contexts/SocketProvider';
import { ChatContext } from '../../contexts/ChatProvider';
import { UserContext } from '../../contexts/UserProvider';

function Chat({ }) {

    const {
        contacts,
        setContacts,
        lastMessages,
        setLastMessages,
        currentChat,
    } = useContext(ChatContext);

    const [messages, setMessages] = useState([]);
    const socket = useContext(SocketContext);
    const { user } = useContext(UserContext);
    const chatMainRef = useRef();




    // to get Messages of currently opened chat
    //--------------------------------------------------------------------------------------------------------------//
    useEffect(() => {

        if (Object.keys(currentChat).length === 0) return;

        const fetchData = async () => {

            if (!socket) return;
            // console.log()
            socket.on("messages", (messages) => {
                console.log("on-messages", messages);
                setMessages(messages.reverse());
            });

            socket.emit("get_messages", currentChat.id);
        }
        fetchData();

        return () => {
            if (!socket) return;
            socket.off("messages");
        }
    }, [currentChat, socket]);

    // to add receive_message listener
    useEffect(() => {
        if (socket) {
            socket.on("receive_message", (message) => {
                console.log("receive_message:", message);


                // if message is received in the current open chat 
                if (message.sender_id == currentChat.id || message.sender_id == user.id) {
                    setMessages((prev) => [...prev, message]);
                }


                const isMsgOfOpenedChat = (contact) => (contact.id == message.receiver_id) || (contact.id == message.sender_id);
                const updateUnseenCount = (contact) => {
                    if (isMsgOfOpenedChat(contact)) {
                        return contact.unseen_count;
                    }
                    else {
                        return contact.unseen_count + 1;
                    }
                };
                var updatedContacts = contacts.map((contact) => {
                    var chat_data = { ...contact.chat_data };
                    // console.log(contact);
                    if (contact.id == message.receiver_id || contact.id == message.sender_id) {
                        chat_data.last_message = message;
                    }
                    chat_data.unseen_count = updateUnseenCount(contact);

                    return { ...contact, chat_data };
                });

                updatedContacts.sort((a, b) => Date.parse(b.chat_data.last_message.timestamp) - Date.parse(a.chat_data.last_message.timestamp));
                // console.log(updatedContacts);

                setContacts(updatedContacts);

                // if message from a new Contact
                const contact = contacts.find(contact => contact.id == message.sender_id);
                if (!contact && message.sender_id != user.id) {
                    socket.emit("get_contact", message.sender_id);
                }

            });


            return () => {
                socket.off("receive_message");
            };
        }
    }, [socket, contacts, currentChat]);

    const scrollToBottom = () => {
        if (chatMainRef.current) {
            chatMainRef.current.scrollTo(0, chatMainRef.current.scrollHeight);
        }
    };

    // when ever a chat's messages are updated, scrollToBottom
    useEffect(() => {
        scrollToBottom();
    }, [messages]);

    useEffect(() => {
        if (messages.length === 0) return;
        const unseen_messages = messages.filter(message => message.is_seen == 0);
        console.log(unseen_messages);
        socket.emit("mark_messages_seen", unseen_messages.map(msg => msg.id));
    }, [messages]);

    // Until no chat is selected
    if (Object.keys(currentChat).length === 0) {

        return (
            <div className='chat_dummy'>
                <h2>Choose a chat</h2>
            </div>
        )
    }

    // console.log("currentChat",currentChat);
    // console.log("currentChat",currentChat.id);
    // once a chat is selected
    return (
        <div className='chat'>
            <ChatHeader name={currentChat.username} />
            <ChatMain messages={messages} ref={chatMainRef} />
            <ChatFooter currentChatId={currentChat.id} />
        </div>
    )
}

export default Chat