"use client";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { Textarea } from "../../components/ui/textarea";
import { useEditContext, useEditContextRef, useFieldsEditContextRef, } from "../client/editContext";
import { useFieldModification } from "../client/fieldModificationStore";
import { useSlotContext } from "../views/editorSlotContext";
import { extractPlainTextContext } from "../utils/selectionContext";
import { useEffect, useRef, useState, useCallback } from "react";
import { useFormFieldCaretPresence } from "./useFormFieldCaretPresence";
import { useTextCompletion } from "./useTextCompletion";
export function MultiLineText({ field, readOnly, updateFieldValue, tabIndex, }) {
    const editContext = useEditContext();
    const slotContext = useSlotContext();
    const editContextRef = useEditContextRef();
    const fieldsContextRef = useFieldsEditContextRef();
    const inputRef = useRef(null);
    const { clearCaretPresence, publishCaretPresence, publishCaretPresenceAfterSelectionSettles, } = useFormFieldCaretPresence({
        field,
        inputRef,
        readOnly,
    });
    const fieldItem = field.descriptor.item;
    const [value, setValue] = useState(field.value);
    // Field-specific subscription - only rerenders when THIS field changes
    const { modifiedField } = useFieldModification(field.id, fieldItem.id, fieldItem.language, fieldItem.version, slotContext?.fieldModificationStore);
    const { completion, isLoadingCompletion, clearCompletion, handleCompletionKeyDown, } = useTextCompletion({
        editContext,
        field,
        inputRef,
        readOnly,
        value,
        setValue,
        updateValue: updateFieldValue,
    });
    useEffect(() => {
        if (inputRef.current !== document.activeElement) {
            if (field.isHistoric)
                setValue(field.value);
            else
                setValue(modifiedField?.value ?? field.value);
        }
    }, [field.value, field.isHistoric, modifiedField?.value]);
    if (!editContextRef.current)
        return;
    if (!fieldItem)
        return;
    // Create a stable callback for replacing selected text or inserting at cursor
    const createReplaceTextCallback = useCallback((currentValue, startOffset, endOffset) => {
        return (newText) => {
            // If startOffset === endOffset, there's no selection - insert at cursor
            const newValue = currentValue.slice(0, startOffset) +
                newText +
                currentValue.slice(endOffset);
            setValue(newValue);
            updateFieldValue(newValue);
        };
    }, [updateFieldValue]);
    // Handle text selection for inline AI editing
    const handleSelect = (e) => {
        const target = e.target;
        const startOffset = target.selectionStart || 0;
        const endOffset = target.selectionEnd || 0;
        const selectedText = target.value.slice(startOffset, endOffset);
        // Extract context around the cursor/selection position
        const { contextBefore, contextAfter } = extractPlainTextContext(target.value, startOffset, endOffset);
        // Always set selection range, even if empty (for cursor position tracking)
        const range = {
            itemId: fieldItem.id,
            fieldId: field.id,
            language: fieldItem.language,
            version: fieldItem.version,
            startOffset,
            endOffset,
            text: selectedText, // Empty string if no selection
            element: target, // Include element reference for AI trigger positioning
            contextBefore,
            contextAfter,
            replaceText: createReplaceTextCallback(target.value, startOffset, endOffset),
        };
        // Update if cursor position changed or selection changed
        const currentRange = editContext?.selectedRange;
        if (range.text !== currentRange?.text ||
            range.startOffset !== currentRange?.startOffset ||
            range.endOffset !== currentRange?.endOffset ||
            range.fieldId !== currentRange?.fieldId ||
            range.itemId !== currentRange?.itemId) {
            editContextRef.current?.setSelectedRange(range);
        }
        publishCaretPresence(target);
    };
    // Handle keyboard shortcut (Ctrl/Cmd + .) to trigger AI text edit
    const handleKeyDown = useCallback((e) => {
        if (handleCompletionKeyDown(e)) {
            return;
        }
        // Check for Ctrl+. or Cmd+.
        if ((e.ctrlKey || e.metaKey) && e.key === ".") {
            // Allow triggering even without selection - just need to be in this field
            if (editContext?.focusedField?.fieldId === field.id) {
                e.preventDefault();
                e.stopPropagation();
                // Dispatch custom event to trigger AI dialog
                document.dispatchEvent(new CustomEvent("inline-ai-open"));
            }
        }
    }, [editContext, field.id, handleCompletionKeyDown]);
    // Restore selection when selectedRange changes externally
    useEffect(() => {
        const focusedField = fieldsContextRef.current?.focusedField;
        if (focusedField?.fieldId === field.id &&
            focusedField?.item.id === fieldItem.id &&
            focusedField?.item.language === fieldItem.language &&
            focusedField?.item.version === fieldItem.version) {
            const range = editContextRef.current?.selectedRange;
            if (range && inputRef.current) {
                inputRef.current.setSelectionRange(range.startOffset, range.endOffset);
            }
        }
    }, [editContext?.selectedRange]);
    useEffect(() => {
        setTimeout(() => {
            const focusedField = fieldsContextRef.current?.focusedField;
            if (focusedField?.fieldId === field.id &&
                focusedField?.item.id === fieldItem.id &&
                focusedField?.item.language === fieldItem.language &&
                focusedField?.item.version === fieldItem.version) {
                // Only focus if no other element currently has focus (e.g., popover buttons)
                if (inputRef.current &&
                    (!document.activeElement || document.activeElement === document.body)) {
                    inputRef.current.focus();
                }
            }
        }, 500);
    }, [fieldsContextRef.current?.focusedField]);
    return (_jsxs("div", { className: "relative", children: [_jsx(Textarea, { ref: inputRef, value: value, disabled: readOnly, className: "focus-shadow border-neutral-grey-10 bg-neutral-grey-5 field-sizing-fixed max-h-[400px] min-h-32 w-full resize-y overflow-y-auto p-2 text-xs", rows: 12, onChange: (e) => {
                    setValue(e.target.value);
                    updateFieldValue(e.target.value);
                    clearCompletion();
                    publishCaretPresenceAfterSelectionSettles(e.target);
                }, onBlur: () => {
                    clearCaretPresence();
                    clearCompletion();
                }, onFocus: (e) => publishCaretPresenceAfterSelectionSettles(e.currentTarget), onKeyUp: (e) => publishCaretPresenceAfterSelectionSettles(e.currentTarget), onMouseUp: (e) => publishCaretPresence(e.currentTarget), onSelect: handleSelect, onKeyDown: handleKeyDown, tabIndex: tabIndex }, fieldItem.id + field.id + fieldItem.language + fieldItem.version), (completion || isLoadingCompletion) && (_jsx("div", { className: "border-border-default bg-background text-neutral-grey-50 absolute right-2 bottom-2 left-2 z-20 rounded border px-2 py-1 text-xs shadow-sm", children: isLoadingCompletion ? "Completing..." : completion }))] }));
}
//# sourceMappingURL=MultiLineText.js.map