import {useEffect, useRef, useState} from "@wordpress/element";
import {__} from "@wordpress/i18n";
import {getLocale, parseDateString} from "../../../../../helpers";
import ChatMenu from "./chat-menu";
import EditChatName from "./edit-chat-name";

export default function ChatsHistory({getChats, editChat, deleteChat, chatSelected, loading, setLoading, loadingBar, setLoadingBar}) {
    const [chats, setChats] = useState([]);
    const [chatsGroups, setChatsGroups] = useState([]);
    const page = useRef(0);
    const perPage = useRef(10);
    const [hasMore, setHasMore] = useState(false);
    const [editing, setEditing] = useState(false);

    useEffect(() => {
        loadChatsHistory();
    }, []);

    useEffect(() => {
        const now = new Date();
        const oneDayInMs = 24 * 60 * 60 * 1000;
        const chatsDatesGroups = [];
        chats.forEach(chat => {
            const date = parseDateString(chat.created_at);
            if (!date) {
                // Invalid chat date
                return;
            }
            const data = {
                uuid: chat.uuid,
                name: chat.name,
            };
            const diffInMs = now - date;
            if (diffInMs <= oneDayInMs) {
                // Last 24h
                if (chatsDatesGroups.length) {
                    chatsDatesGroups[0].items.push(data);
                } else {
                    chatsDatesGroups.push({
                        date: __("Last 24h", 'limb-chatbot'),
                        items: [data],
                    });
                }
            } else {
                // Other days
                let dayKey;
                try {
                    dayKey = date.toLocaleDateString(getLocale(), {
                        month: 'short',
                        day: 'numeric',
                    });
                } catch (e) {
                    // Fallback to en-US if locale is invalid
                    dayKey = date.toLocaleDateString('en-US', {
                        month: 'short',
                        day: 'numeric',
                    });
                }
                const i = chatsDatesGroups.findIndex(dateGroup => dateGroup.date === dayKey);
                if (i === -1) {
                    chatsDatesGroups.push({
                        date: dayKey,
                        items: [data],
                    });
                } else {
                    chatsDatesGroups[i].items.push(data);
                }
            }
        });
        setChatsGroups(chatsDatesGroups);
    }, [chats]);

    /**
     * Get chats
     */
    const loadChatsHistory = async () => {
        setLoading(prev => prev + 1);
        const res = await getChats({
            page: page.current + 1,
            per_page: perPage.current,
            orderby: 'id',
            order: 'desc',
        });
        if (res?.items?.length) {
            page.current++;
            setChats(prevState => [...prevState, ...res.items]);
            setHasMore(prevState => (+res.total) > (page.current * perPage.current));
        }
        setLoading(prev => prev - 1);
    }

    /**
     * Handle edit chat
     *
     * @param {string} uuid Chat uuid
     * @param {string} name Chat name
     * @return {Promise<void>}
     */
    const handleEditChat = async (uuid, name) => {
        const res = await editChat(uuid, {name});
        if (res) {
            setChats(prevState => prevState.map(item => {
                if (item.uuid === uuid) {
                    return {
                        ...item,
                        name: name,
                    }
                }
                return item;
            }));
            setEditing(false);
        }
    }

    /**
     * Delete chat
     *
     * @param {string} uuid Chat UUID
     * @return {Promise<void>}
     */
    const handleDeleteChat = async (uuid) => {
        const res = await deleteChat(uuid);
        if (res) {
            setChats(prevState => prevState.filter(item => item.uuid !== uuid));
        }
    }

    /**
     * Select chat
     *
     * @param {string} uuid Chat UUID
     */
    const selectChat = (uuid) => {
        chatSelected(uuid);
    }

    return <>
        {chatsGroups.map(chatsGroup =>
            <div key={chatsGroup.date} className='lbaic-message-history-group'>
                <div className='lbaic-message-history-group-date'>
                    <span className='lbaic-message-history-group-date-in'>{chatsGroup.date}</span>
                </div>
                {chatsGroup.items.map(item =>
                    <div key={item.uuid} className='lbaic-message-row lbaic-message-history'>
                        {editing === item.uuid ?
                            <EditChatName name={item.name} edit={(value) => handleEditChat(item.uuid, value)}
                                          close={() => setEditing(false)}/>
                            :
                            <div className='lbaic-message' onClick={() => selectChat(item.uuid)}>
                                <div className='lbaic-message-in'>
                                    <p className='lbaic-message-info'>{item.name || __("No name", 'limb-chatbot')}</p>
                                </div>
                                <ChatMenu uuid={item.uuid} editChat={() => setEditing(item.uuid)}
                                          deleteChat={handleDeleteChat} loading={loading || loadingBar}/>
                            </div>}
                    </div>)}
            </div>)}
        {!loading && !chatsGroups.length &&
            <div className='lbaic-message-history-empty'>
                <span className='lbaic-message-history-empty-label'>{__("No chats found.", 'limb-chatbot')}</span>
            </div>}
        {hasMore &&
            <div className='lbaic-message-history-load-more'>
                <button className="lbaic-message-history-load-more-in" onClick={loadChatsHistory} disabled={loading > 0}>
                    <span className="lbaic-message-history-load-more-label">{__("Load more", 'limb-chatbot')}</span>
                </button>
            </div>}
    </>;
}