import { useCallback, useContext, useMemo, useRef, useState } from "preact/hooks";
import { MessageTools, type IMessage } from "../../tools/messages";
import { StateContext } from "../../contexts/state";
import { DOMTools } from "../../tools/dom";

import styles from './message.module.css';
import { AutoTextarea } from "../autoTextarea";
import { useInputState } from "@common/hooks/useInputState";

interface IProps {
    message: IMessage;
    index: number;
    isLastUser: boolean;
    isLastAssistant: boolean;
}

export const Message = ({ message, index, isLastUser, isLastAssistant }: IProps) => {
    const { messages, editMessage, editSummary, deleteMessage, setCurrentSwipe, setMessages, continueMessage } = useContext(StateContext);
    const [editing, setEditing] = useState(false);
    const [editedMessage, setEditedMessage] = useInputState('');
    const textRef = useRef<HTMLDivElement>(null);

    const swipe = useMemo(() => MessageTools.getSwipe(message), [message]);

    const content = swipe?.content;
    const summary = swipe?.summary;
    const cost = swipe?.cost ?? 0;
    const htmlContent = useMemo(() => MessageTools.format(content ?? ''), [content]);

    const handleEnableEdit = useCallback(() => {
        setEditing(true);
        setEditedMessage(content ?? '');
    }, [content]);

    const handleSaveEdit = useCallback(() => {
        editMessage(index, editedMessage.trim(), cost);
        editSummary(index, '', 0);
        setEditing(false);
    }, [editMessage, editSummary, index, editedMessage, cost]);

    const handleCancelEdit = useCallback(() => {
        setEditing(false);
    }, [editMessage, index]);

    const handleDeleteMessage = useCallback(() => {
        if (confirm('Delete message?')) {
            setEditing(false);
            deleteMessage(index);
        }
    }, [deleteMessage, index]);

    const handleStopHere = useCallback(() => {
        if (confirm('Delete all messages after that?')) {
            setMessages(messages.filter((_, i) => i <= index));
            setEditing(false);
        }
    }, [messages, setMessages, index]);

    const handleSwipeLeft = useCallback(() => {
        setCurrentSwipe(index, message.currentSwipe - 1);
        DOMTools.animate(textRef.current, 'swipe-from-left');
    }, [setCurrentSwipe, index, message]);

    const handleSwipeRight = useCallback(() => {
        setCurrentSwipe(index, message.currentSwipe + 1);
        DOMTools.animate(textRef.current, 'swipe-from-right');
    }, [setCurrentSwipe, index, message]);

    const handleContinueMessage = useCallback(() => {
        continueMessage(true);
    }, [continueMessage]);

    return (
        <div class={`${styles.message} ${styles[message.role]} ${isLastUser ? styles.lastUser : ''}`}>
            <div class={styles.content}>
                {editing
                    ? <AutoTextarea onInput={setEditedMessage} value={editedMessage} />
                    : <>
                        <div class={styles.text} dangerouslySetInnerHTML={{ __html: htmlContent }} ref={textRef} />
                        {summary && <small class={styles.summary}>{summary}</small>}
                        {cost > 0 && <small class={styles.summary}>💲&nbsp;{cost}</small>}
                    </>
                }
                <div class={styles.buttons}>
                    {editing
                        ? <>
                            <button class='icon' onClick={handleSaveEdit} title='Save'>✔</button>
                            <button class='icon' onClick={handleDeleteMessage} title='Delete'>🗑️</button>
                            <button class='icon' onClick={handleStopHere} title='Stop here'>⛔</button>
                            <button class='icon' onClick={handleCancelEdit} title='Cancel'>❌</button>
                        </>
                        : <>
                            {isLastAssistant && <>
                                <div class={styles.swipes}>
                                    <div onClick={handleSwipeLeft}>◀</div>
                                    <div>{message.currentSwipe + 1}/{message.swipes.length}</div>
                                    <div onClick={handleSwipeRight}>▶</div>
                                </div>
                                <button class='icon' onClick={handleContinueMessage} title="Continue">▶</button>
                            </>}
                            <button class='icon' onClick={handleEnableEdit} title="Edit">🖊</button>
                        </>
                    }
                </div>
            </div>
        </div>
    );
};
