import { useCallback, useContext, useEffect, useMemo, useState } from "preact/hooks";
import { useBool } from "@common/hooks/useBool";
import { Modal } from "@common/components/modal/modal";

import { Instruct, StateContext } from "../../contexts/state";
import { LLMContext } from "../../contexts/llm";
import { MiniChat } from "../minichat/minichat";
import { AutoTextarea } from "../autoTextarea";

import styles from './header.module.css';
import { Ace } from "../ace";

export const Header = () => {
    const { modelName, modelTemplate, contextLength, promptTokens, blockConnection } = useContext(LLMContext);
    const {
        messages, connectionUrl, systemPrompt, lore, userPrompt, bannedWords, instruct,
        setConnectionUrl, setSystemPrompt, setLore, setUserPrompt, addSwipe, setBannedWords, setInstruct
    } = useContext(StateContext);

    const loreOpen = useBool();
    const promptsOpen = useBool();
    const assistantOpen = useBool();

    const bannedWordsInput = useMemo(() => bannedWords.join('\n'), [bannedWords]);
    const urlValid = useMemo(() => contextLength > 0, [contextLength]);

    const handleBlurUrl = useCallback(() => {
        const regex = /^(?:http(s?):\/\/)?(.*?)\/?$/i
        const normalizedConnectionUrl = connectionUrl.replace(regex, 'http$1://$2');
        setConnectionUrl(normalizedConnectionUrl);
        blockConnection.setFalse();
    }, [connectionUrl, setConnectionUrl, blockConnection]);

    const handleAssistantAddSwipe = useCallback((answer: string) => {
        const index = messages.findLastIndex(m => m.role === 'assistant');
        addSwipe(index, answer);
        assistantOpen.setFalse();
    }, [addSwipe, messages]);

    const handleSetBannedWords = useCallback((e: Event) => {
        if (e.target instanceof HTMLTextAreaElement) {
            const words = e.target.value.split('\n');
            setBannedWords(words);
        }
    }, [setBannedWords]);

    const handleBlurBannedWords = useCallback((e: Event) => {
        if (e.target instanceof HTMLTextAreaElement) {
            const words = e.target.value.split('\n').sort();
            setBannedWords(words);
        }
    }, [setBannedWords]);

    return (
        <div class={styles.header}>
            <div class={styles.inputs}>
                <input value={connectionUrl}
                    onInput={setConnectionUrl}
                    onFocus={blockConnection.setTrue}
                    onBlur={handleBlurUrl}
                    class={blockConnection.value ? '' : urlValid ? styles.valid : styles.invalid}
                />
                <select value={instruct} onChange={setInstruct}>
                    {modelName && modelTemplate && <option value={modelTemplate}>{modelName}</option>}
                    {Object.entries(Instruct).map(([label, value]) => (
                        <option value={value} key={value}>
                            {label.toLowerCase()}
                        </option>
                    ))}
                </select>
                <div class={styles.info}>
                    {promptTokens} / {contextLength}
                </div>
            </div>
            <div class={styles.buttons}>
                <button class='icon color' title='Edit lore' onClick={loreOpen.setTrue}>
                    🌍
                </button>
                <button class='icon color' title='Edit prompts' onClick={promptsOpen.setTrue}>
                    📃
                </button>
            </div>
            <div class={styles.buttons}>
                <button class='icon' onClick={assistantOpen.setTrue} title='Ask assistant'>
                    ❓
                </button>
            </div>
            <Modal open={loreOpen.value} onClose={loreOpen.setFalse}>
                <h3 class={styles.modalTitle}>Lore Editor</h3>
                <AutoTextarea
                    value={lore}
                    onInput={setLore}
                    placeholder="Describe your world, for example: World of Awoo has big mountains and wide rivers."
                />
            </Modal>
            <Modal open={promptsOpen.value} onClose={promptsOpen.setFalse}>
                <h3 class={styles.modalTitle}>Prompts Editor</h3>
                <div className={styles.scrollPane}>
                    <h4 class={styles.modalTitle}>System prompt</h4>
                    <AutoTextarea value={systemPrompt} onInput={setSystemPrompt} />
                    <hr />
                    <h4 class={styles.modalTitle}>User prompt template</h4>
                    <Ace value={userPrompt} onInput={setUserPrompt} />
                    <hr />
                    <h4 class={styles.modalTitle}>Banned phrases</h4>
                    <AutoTextarea
                        placeholder="Each phrase on separate line"
                        value={bannedWordsInput}
                        onInput={handleSetBannedWords}
                        onBlur={handleBlurBannedWords}
                        class={styles.template}
                    />
                </div>
            </Modal>
            <MiniChat
                history={messages}
                open={assistantOpen.value}
                onClose={assistantOpen.setFalse}
                buttons={{ 'Add swipe': handleAssistantAddSwipe }}
            />
        </div>
    );
}