"use client";
import { useCallback, useEffect, useRef, useState } from "react";
import { getTextCompletion, normalizeTextCompletion, } from "../services/textCompletionService";
export function useTextCompletion({ editContext, field, inputRef, readOnly, value, setValue, updateValue, }) {
    const [completion, setCompletion] = useState("");
    const [isLoadingCompletion, setIsLoadingCompletion] = useState(false);
    const requestIdRef = useRef(0);
    const abortControllerRef = useRef(null);
    const clearCompletion = useCallback(() => {
        abortControllerRef.current?.abort();
        abortControllerRef.current = null;
        setCompletion("");
        setIsLoadingCompletion(false);
    }, []);
    const applyCompletion = useCallback(() => {
        const input = inputRef.current;
        const normalizedCompletion = normalizeTextCompletion(completion);
        if (!input || !normalizedCompletion) {
            return false;
        }
        const start = input.selectionStart ?? value.length;
        const end = input.selectionEnd ?? start;
        const nextValue = value.slice(0, start) + normalizedCompletion + value.slice(end);
        const nextCursor = start + normalizedCompletion.length;
        setValue(nextValue);
        updateValue(nextValue);
        setCompletion("");
        window.setTimeout(() => {
            input.focus();
            input.setSelectionRange(nextCursor, nextCursor);
            input.dispatchEvent(new Event("select", { bubbles: true }));
        }, 0);
        return true;
    }, [completion, inputRef, setValue, updateValue, value]);
    const requestCompletion = useCallback(async (force = false) => {
        const input = inputRef.current;
        if (!editContext?.enableCompletions || readOnly || !input) {
            clearCompletion();
            return;
        }
        const selectionStart = input.selectionStart ?? value.length;
        const selectionEnd = input.selectionEnd ?? selectionStart;
        if (!force && value.slice(0, selectionStart).trim().length < 3) {
            clearCompletion();
            return;
        }
        const requestId = requestIdRef.current + 1;
        requestIdRef.current = requestId;
        abortControllerRef.current?.abort();
        const abortController = new AbortController();
        abortControllerRef.current = abortController;
        setIsLoadingCompletion(true);
        try {
            const textCompletion = await getTextCompletion({
                editContext,
                field,
                value,
                selectionStart,
                selectionEnd,
                signal: abortController.signal,
            });
            if (requestId !== requestIdRef.current ||
                abortController.signal.aborted) {
                return;
            }
            setCompletion(textCompletion);
        }
        catch (error) {
            if (!abortController.signal.aborted) {
                console.warn("Failed to get text completion", error);
                setCompletion("");
            }
        }
        finally {
            if (requestId === requestIdRef.current) {
                setIsLoadingCompletion(false);
            }
        }
    }, [clearCompletion, editContext, field, inputRef, readOnly, value]);
    useEffect(() => {
        const input = inputRef.current;
        if (!editContext?.enableCompletions ||
            readOnly ||
            !input ||
            document.activeElement !== input) {
            clearCompletion();
            return;
        }
        const handle = window.setTimeout(() => {
            void requestCompletion(false);
        }, 900);
        return () => window.clearTimeout(handle);
    }, [
        clearCompletion,
        editContext?.enableCompletions,
        inputRef,
        readOnly,
        requestCompletion,
        value,
    ]);
    const handleCompletionKeyDown = useCallback((event) => {
        if ((event.ctrlKey || event.metaKey) && event.code === "Space") {
            event.preventDefault();
            event.stopPropagation();
            void requestCompletion(true);
            return true;
        }
        if (event.key === "Tab" && completion) {
            event.preventDefault();
            event.stopPropagation();
            return applyCompletion();
        }
        if (event.key === "Escape" && (completion || isLoadingCompletion)) {
            event.preventDefault();
            event.stopPropagation();
            clearCompletion();
            return true;
        }
        return false;
    }, [
        applyCompletion,
        clearCompletion,
        completion,
        isLoadingCompletion,
        requestCompletion,
    ]);
    useEffect(() => () => abortControllerRef.current?.abort(), []);
    return {
        completion,
        isLoadingCompletion,
        clearCompletion,
        handleCompletionKeyDown,
    };
}
//# sourceMappingURL=useTextCompletion.js.map