import React, { useEffect } from 'react';
import clsx from 'clsx';
import { MESSAGE_ACTIONS } from '../Message';
import { MessageInput, MessageInputFlat } from '../MessageInput';
import { MessageList, VirtualizedMessageList, } from '../MessageList';
import { ThreadHeader as DefaultThreadHeader } from './ThreadHeader';
import { ThreadHead as DefaultThreadHead } from '../Thread/ThreadHead';
import { useChannelActionContext, useChannelStateContext, useChatContext, useComponentContext, } from '../../context';
import { useStateStore, useThreadContext } from '../../components/Threads';
/**
 * The Thread component renders a parent Message with a list of replies
 */
export const Thread = (props) => {
    const { channel, channelConfig, thread } = useChannelStateContext('Thread');
    const threadInstance = useThreadContext();
    if ((!thread && !threadInstance) || channelConfig?.replies === false)
        return null;
    // the wrapper ensures a key variable is set and the component recreates on thread switch
    return (
    // FIXME: TS is having trouble here as at least one of the two would always be defined
    React.createElement(ThreadInner, { ...props, key: `thread-${(thread ?? threadInstance)?.id}-${channel?.cid}` }));
};
const selector = (nextValue) => [
    nextValue.replies,
    nextValue.pagination.isLoadingPrev,
    nextValue.pagination.isLoadingNext,
    nextValue.parentMessage,
];
const ThreadInner = (props) => {
    const { additionalMessageInputProps, additionalMessageListProps, additionalParentMessageProps, additionalVirtualizedMessageListProps, autoFocus = true, enableDateSeparator = false, Input: PropInput, Message: PropMessage, messageActions = Object.keys(MESSAGE_ACTIONS), virtualized, } = props;
    const threadInstance = useThreadContext();
    const [latestReplies, isLoadingPrev, isLoadingNext, parentMessage] = useStateStore(threadInstance?.state, selector) ?? [];
    const { thread, threadHasMore, threadLoadingMore, threadMessages = [], threadSuppressAutoscroll, } = useChannelStateContext('Thread');
    const { closeThread, loadMoreThread } = useChannelActionContext('Thread');
    const { customClasses } = useChatContext('Thread');
    const { ThreadInput: ContextInput, Message: ContextMessage, ThreadHead = DefaultThreadHead, ThreadHeader = DefaultThreadHeader, VirtualMessage, } = useComponentContext('Thread');
    const ThreadInput = PropInput ?? additionalMessageInputProps?.Input ?? ContextInput ?? MessageInputFlat;
    const ThreadMessage = PropMessage || additionalMessageListProps?.Message;
    const FallbackMessage = virtualized && VirtualMessage ? VirtualMessage : ContextMessage;
    const MessageUIComponent = ThreadMessage || FallbackMessage;
    const ThreadMessageList = virtualized ? VirtualizedMessageList : MessageList;
    useEffect(() => {
        if (thread?.id && thread?.reply_count) {
            // FIXME: integrators can customize channel query options but cannot customize channel.getReplies() options
            loadMoreThread();
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [thread, loadMoreThread]);
    const threadProps = threadInstance
        ? {
            loadingMore: isLoadingPrev,
            loadingMoreNewer: isLoadingNext,
            loadMore: threadInstance.loadPrevPage,
            loadMoreNewer: threadInstance.loadNextPage,
            messages: latestReplies,
        }
        : {
            hasMore: threadHasMore,
            loadingMore: threadLoadingMore,
            loadMore: loadMoreThread,
            messages: threadMessages,
        };
    const messageAsThread = thread ?? parentMessage;
    if (!messageAsThread)
        return null;
    const threadClass = customClasses?.thread ||
        clsx('str-chat__thread-container str-chat__thread', {
            'str-chat__thread--virtualized': virtualized,
        });
    const head = (React.createElement(ThreadHead, { key: messageAsThread.id, message: messageAsThread, Message: MessageUIComponent, ...additionalParentMessageProps }));
    return (React.createElement("div", { className: threadClass },
        React.createElement(ThreadHeader, { closeThread: closeThread, thread: messageAsThread }),
        React.createElement(ThreadMessageList, { disableDateSeparator: !enableDateSeparator, head: head, Message: MessageUIComponent, messageActions: messageActions, suppressAutoscroll: threadSuppressAutoscroll, threadList: true, ...threadProps, ...(virtualized ? additionalVirtualizedMessageListProps : additionalMessageListProps) }),
        React.createElement(MessageInput, { focus: autoFocus, Input: ThreadInput, parent: thread ?? parentMessage, publishTypingEvent: false, ...additionalMessageInputProps })));
};
