import { jsx as _jsx } from "react/jsx-runtime";
// (C) 2007-2025 GoodData Corporation
import { useCallback, useEffect, useMemo, useRef, useState, } from "react";
/**
 * @internal
 */
export function TextAreaWithSubmit({ className = "", maxLength = 100000, rows = 1, onCancel = (v) => v, onEditingStart = (v) => v, onChange = (v) => v, placeholder = "", scrollToEndOnEditingStart = true, autofocus = false, disabled = false, defaultValue, onSubmit: onSubmitProp, }) {
    const [value, setValue] = useState(defaultValue);
    const [isEditing, setIsEditing] = useState(false);
    const root = useRef(null);
    const textarea = useRef(null);
    const focusTimeoutRef = useRef(0);
    const onSelectStart = useCallback((e) => {
        e.stopPropagation();
    }, []);
    const isClickOutsideTextarea = useCallback((clickedTarget) => {
        return !!textarea.current && !textarea.current.contains(clickedTarget);
    }, []);
    const onDocumentClick = useCallback((e) => {
        if (isClickOutsideTextarea(e.target)) {
            const textAreaNode = textarea.current;
            textAreaNode?.blur();
        }
    }, [isClickOutsideTextarea]);
    const removeListeners = useCallback(() => {
        document.removeEventListener("mousedown", onDocumentClick);
    }, [onDocumentClick]);
    const onSubmit = useCallback(() => {
        const oldValue = defaultValue;
        const newTrimmedValue = value.trim();
        if (newTrimmedValue === "") {
            setValue("");
        }
        if (oldValue === newTrimmedValue) {
            onCancel(oldValue);
        }
        else {
            onSubmitProp(newTrimmedValue);
        }
        setValue(newTrimmedValue);
        setIsEditing(false);
        removeListeners();
    }, [defaultValue, value, onSubmitProp, onCancel, removeListeners]);
    const onCancelHandler = useCallback(() => {
        onCancel(defaultValue);
        setValue(defaultValue);
        setIsEditing(false);
        removeListeners();
    }, [defaultValue, onCancel, removeListeners]);
    const onChangeHandler = useCallback((e) => {
        const { value } = e.target;
        setValue(value);
        onChange(value);
    }, [onChange]);
    const onKeyDown = useCallback((e) => {
        const isSubmit = e.key === "Enter" && !e.shiftKey;
        const isCancel = e.key === "Escape";
        if (isSubmit || isCancel) {
            e.preventDefault();
            e.stopPropagation();
        }
        if (isSubmit) {
            onSubmit();
        }
        if (isCancel) {
            onCancelHandler();
        }
    }, [onSubmit, onCancelHandler]);
    const isMultiLine = useCallback(() => {
        return rows > 1;
    }, [rows]);
    const selectAndFocus = useCallback(() => {
        const componentElement = textarea.current;
        if (componentElement) {
            window.clearTimeout(focusTimeoutRef.current);
            // without the timeout the focus sometimes got stolen by the previously active item for some reason
            focusTimeoutRef.current = window.setTimeout(() => {
                componentElement.focus();
                if (scrollToEndOnEditingStart && isMultiLine()) {
                    componentElement.scrollTop = componentElement.scrollHeight;
                }
                componentElement.select();
            }, 1);
        }
    }, [scrollToEndOnEditingStart, isMultiLine]);
    const edit = useCallback((_e) => {
        if (!isEditing) {
            setIsEditing(true);
            // Use setTimeout to ensure state update is processed before side effects
            setTimeout(() => {
                selectAndFocus();
                document.addEventListener("mousedown", onDocumentClick);
            }, 0);
            onEditingStart();
        }
    }, [isEditing, selectAndFocus, onDocumentClick, onEditingStart]);
    const renderTextarea = useCallback((style = {}) => {
        return (_jsx("textarea", { className: className, style: style, rows: rows, maxLength: maxLength, onKeyDown: onKeyDown, onBlur: onSubmit, onChange: onChangeHandler, value: value, placeholder: placeholder, ref: textarea, disabled: disabled }));
    }, [className, rows, maxLength, onKeyDown, onSubmit, onChangeHandler, value, placeholder, disabled]);
    const renderTextAreaWithSubmitEdit = useMemo(() => {
        return renderTextarea({});
    }, [renderTextarea]);
    useEffect(() => {
        const rootNode = root.current;
        if (rootNode) {
            rootNode.addEventListener("dragstart", onSelectStart);
            rootNode.addEventListener("selectstart", onSelectStart);
        }
        if (autofocus) {
            edit();
        }
        return () => {
            if (rootNode) {
                rootNode.removeEventListener("dragstart", onSelectStart);
                rootNode.removeEventListener("selectstart", onSelectStart);
            }
            removeListeners();
            clearTimeout(focusTimeoutRef.current);
        };
    }, [autofocus, edit, onSelectStart, removeListeners]);
    useEffect(() => {
        setValue(defaultValue);
    }, [defaultValue]);
    return (_jsx("div", { role: "editable-label", onClick: edit, children: _jsx("div", { ref: root, children: renderTextAreaWithSubmitEdit }) }));
}
