"use strict";
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MessageBar = exports.MessageBarBase = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const react_core_1 = require("@patternfly/react-core");
const react_styles_1 = require("@patternfly/react-styles");
// Import Chatbot components
const SendButton_1 = __importDefault(require("./SendButton"));
const MicrophoneButton_1 = __importDefault(require("./MicrophoneButton"));
const AttachButton_1 = require("./AttachButton");
const AttachMenu_1 = __importDefault(require("../AttachMenu"));
const StopButton_1 = __importDefault(require("./StopButton"));
const MessageBarBase = (_a) => {
    var _b;
    var { onSendMessage, className, alwayShowSendButton, placeholder = 'Send a message...', hasAttachButton = true, attachButtonPosition = 'end', hasMicrophoneButton, listeningText = 'Listening', handleAttach, attachMenuProps, isSendButtonDisabled, handleStopButton, hasStopButton, buttonProps, onChange, displayMode, value, isCompact = false, allowedFileTypes, minSize, maxSize, maxFiles, isAttachmentDisabled, onAttach, onAttachRejected, validator, dropzoneProps, innerRef, isPrimary, additionalActions, forceMultilineLayout = false, hasAiIndicator, isThinking } = _a, props = __rest(_a, ["onSendMessage", "className", "alwayShowSendButton", "placeholder", "hasAttachButton", "attachButtonPosition", "hasMicrophoneButton", "listeningText", "handleAttach", "attachMenuProps", "isSendButtonDisabled", "handleStopButton", "hasStopButton", "buttonProps", "onChange", "displayMode", "value", "isCompact", "allowedFileTypes", "minSize", "maxSize", "maxFiles", "isAttachmentDisabled", "onAttach", "onAttachRejected", "validator", "dropzoneProps", "innerRef", "isPrimary", "additionalActions", "forceMultilineLayout", "hasAiIndicator", "isThinking"]);
    // Text Input
    // --------------------------------------------------------------------------
    const [message, setMessage] = (0, react_1.useState)(value !== null && value !== void 0 ? value : '');
    const [isListeningMessage, setIsListeningMessage] = (0, react_1.useState)(false);
    const [hasSentMessage, setHasSentMessage] = (0, react_1.useState)(false);
    const [isComposing, setIsComposing] = (0, react_1.useState)(false);
    const shouldForceMultiline = forceMultilineLayout || additionalActions;
    const [isMultiline, setIsMultiline] = (0, react_1.useState)(shouldForceMultiline);
    const inputRef = (0, react_1.useRef)(null);
    const textareaRef = (_b = innerRef) !== null && _b !== void 0 ? _b : inputRef;
    const attachButtonRef = (0, react_1.useRef)(null);
    const topMargin = '1rem';
    (0, react_1.useEffect)(() => {
        if (value !== undefined && value !== message) {
            setMessage(value);
        }
    }, [value, message]);
    const setInitialLineHeight = (field) => {
        field.style.setProperty('line-height', '1rem');
        const parent = field.parentElement;
        if (parent) {
            parent.style.setProperty('margin-top', topMargin);
            parent.style.setProperty('margin-bottom', `0rem`);
            parent.style.setProperty('height', 'inherit');
            const grandparent = parent.parentElement;
            if (grandparent) {
                grandparent.style.setProperty('flex-basis', shouldForceMultiline ? '100%' : 'auto');
            }
        }
    };
    const setAutoHeight = (field) => {
        const parent = field.parentElement;
        if (parent) {
            parent.style.setProperty('height', 'inherit');
            const computed = window.getComputedStyle(field);
            // Calculate the height
            const height = parseInt(computed.getPropertyValue('border-top-width')) +
                parseInt(computed.getPropertyValue('padding-top')) +
                field.scrollHeight +
                parseInt(computed.getPropertyValue('padding-bottom')) +
                parseInt(computed.getPropertyValue('border-bottom-width'));
            parent.style.setProperty('height', `${height}px`);
            if (height > 32 || window.innerWidth <= 507) {
                parent.style.setProperty('margin-bottom', topMargin);
                parent.style.setProperty('margin-top', topMargin);
            }
        }
    };
    const textIsLongerThan2Lines = (field) => {
        const lineHeight = parseFloat(window.getComputedStyle(field).lineHeight);
        const lines = field.scrollHeight / lineHeight;
        return lines > 2;
    };
    const checkIfMultiline = (0, react_1.useCallback)((field) => {
        const parent = field.parentElement;
        const grandparent = parent === null || parent === void 0 ? void 0 : parent.parentElement;
        if (grandparent) {
            const containerHeight = grandparent.offsetHeight;
            const threshold = isCompact ? 56 : 70;
            setIsMultiline(containerHeight > threshold);
        }
    }, [isCompact]);
    const setAutoWidth = (0, react_1.useCallback)((field) => {
        const parent = field.parentElement;
        if (parent) {
            const grandparent = parent.parentElement;
            if ((textIsLongerThan2Lines(field) || shouldForceMultiline) && grandparent) {
                grandparent.style.setProperty('flex-basis', `100%`);
            }
        }
    }, []);
    const handleNewLine = (field) => {
        const parent = field.parentElement;
        if (parent) {
            parent.style.setProperty('margin-bottom', topMargin);
            parent.style.setProperty('margin-top', topMargin);
        }
    };
    (0, react_1.useEffect)(() => {
        const field = textareaRef.current;
        if (field) {
            if (field.value === '') {
                if (window.innerWidth > 507) {
                    setInitialLineHeight(field);
                }
            }
            else {
                setAutoHeight(field);
                setAutoWidth(field);
            }
        }
        const resetHeight = () => {
            if (field) {
                if (field.value === '') {
                    if (window.innerWidth > 507) {
                        setInitialLineHeight(field);
                    }
                }
                else {
                    setAutoHeight(field);
                    setAutoWidth(field);
                }
            }
        };
        window.addEventListener('resize', resetHeight);
        return () => {
            window.removeEventListener('resize', resetHeight);
        };
    }, [setAutoWidth]);
    (0, react_1.useEffect)(() => {
        const field = textareaRef.current;
        if (field) {
            if (field.value === '') {
                setInitialLineHeight(field);
                !shouldForceMultiline && setIsMultiline(false);
            }
            else {
                setAutoHeight(field);
                setAutoWidth(field);
                !shouldForceMultiline && checkIfMultiline(field);
            }
        }
    }, [displayMode, message, setAutoWidth, shouldForceMultiline, checkIfMultiline]);
    (0, react_1.useEffect)(() => {
        const field = textareaRef.current;
        if (field) {
            setInitialLineHeight(field);
            setHasSentMessage(false);
        }
    }, [hasSentMessage]);
    const handleChange = (0, react_1.useCallback)((event) => {
        onChange && onChange(event, event.target.value);
        if (textareaRef.current) {
            if (event.target.value === '') {
                setInitialLineHeight(textareaRef.current);
                !shouldForceMultiline && setIsMultiline(false);
            }
            else {
                setAutoHeight(textareaRef.current);
                !shouldForceMultiline && checkIfMultiline(textareaRef.current);
            }
        }
        setMessage(event.target.value);
    }, [onChange, checkIfMultiline]);
    // Handle sending message
    const handleSend = (0, react_1.useCallback)((newMessage) => {
        onSendMessage(newMessage);
        setHasSentMessage(true);
        setMessage('');
    }, [onSendMessage]);
    const handleKeyDown = (0, react_1.useCallback)((event) => {
        // Japanese and other languages may use IME for character input.
        // In these cases, enter is used to select the final input, so we need to check for composition end instead.
        // See more info at https://www.stum.de/2016/06/24/handling-ime-events-in-javascript/
        // Chrome, Edge, and Firefox seem to work well with just the compose event.
        // Safari is a little bit special. We need to handle 229 as well in this case.
        const nativeEvent = event.nativeEvent;
        const isCompositionKey = nativeEvent.which === 229;
        const isCurrentlyComposing = isComposing || isCompositionKey;
        if (event.key === 'Enter' && !isCurrentlyComposing && !event.shiftKey) {
            event.preventDefault();
            if (!isSendButtonDisabled && !hasStopButton) {
                handleSend(message);
            }
        }
        if (event.key === 'Enter' && !isCurrentlyComposing && event.shiftKey) {
            if (textareaRef.current) {
                handleNewLine(textareaRef.current);
            }
        }
    }, [isSendButtonDisabled, hasStopButton, handleSend, message, isComposing]);
    const handleCompositionStart = (0, react_1.useCallback)(() => {
        setIsComposing(true);
    }, []);
    const handleCompositionEnd = (0, react_1.useCallback)(() => {
        setIsComposing(false);
    }, []);
    const handleAttachMenuToggle = () => {
        (attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.setIsAttachMenuOpen) && (attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.setIsAttachMenuOpen(!(attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.isAttachMenuOpen)));
        attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.onAttachMenuToggleClick();
    };
    const handleSpeechRecognition = (message) => {
        setMessage(message);
        onChange && onChange({}, message);
    };
    const renderAttachButton = () => {
        var _a, _b, _c, _d, _e, _f;
        if (!attachMenuProps && hasAttachButton) {
            return ((0, jsx_runtime_1.jsx)(AttachButton_1.AttachButton, Object.assign({ onAttachAccepted: handleAttach, isDisabled: isListeningMessage, tooltipContent: (_a = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _a === void 0 ? void 0 : _a.tooltipContent, inputTestId: (_b = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _b === void 0 ? void 0 : _b.inputTestId, isCompact: isCompact, tooltipProps: (_c = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _c === void 0 ? void 0 : _c.tooltipProps, allowedFileTypes: allowedFileTypes, minSize: minSize, maxSize: maxSize, maxFiles: maxFiles, isAttachmentDisabled: isAttachmentDisabled, onAttach: onAttach, onAttachRejected: onAttachRejected, validator: validator, dropzoneProps: dropzoneProps }, buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach, (_d = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _d === void 0 ? void 0 : _d.props)));
        }
        if (attachMenuProps) {
            return ((0, jsx_runtime_1.jsx)(AttachButton_1.AttachButton, Object.assign({ ref: attachButtonRef, onClick: handleAttachMenuToggle, isDisabled: isListeningMessage, tooltipContent: (_e = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _e === void 0 ? void 0 : _e.tooltipContent, isCompact: isCompact, tooltipProps: (_f = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _f === void 0 ? void 0 : _f.tooltipProps, allowedFileTypes: allowedFileTypes, minSize: minSize, maxSize: maxSize, maxFiles: maxFiles, isAttachmentDisabled: isAttachmentDisabled, onAttach: onAttach, onAttachRejected: onAttachRejected, validator: validator, dropzoneProps: dropzoneProps }, buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach)));
        }
    };
    const isAttachButtonAtStart = attachButtonPosition === 'start';
    const renderButtons = () => {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
        if (hasStopButton && handleStopButton) {
            return ((0, jsx_runtime_1.jsx)(StopButton_1.default, Object.assign({ onClick: handleStopButton, tooltipContent: (_a = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.stop) === null || _a === void 0 ? void 0 : _a.tooltipContent, isCompact: isCompact, tooltipProps: (_b = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.stop) === null || _b === void 0 ? void 0 : _b.tooltipProps }, (_c = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.stop) === null || _c === void 0 ? void 0 : _c.props)));
        }
        return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [!isAttachButtonAtStart && renderAttachButton(), hasMicrophoneButton && ((0, jsx_runtime_1.jsx)(MicrophoneButton_1.default, Object.assign({ isListening: isListeningMessage, onIsListeningChange: setIsListeningMessage, onSpeechRecognition: handleSpeechRecognition, tooltipContent: (_d = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _d === void 0 ? void 0 : _d.tooltipContent, language: (_e = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _e === void 0 ? void 0 : _e.language, isCompact: isCompact, tooltipProps: (_f = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _f === void 0 ? void 0 : _f.tooltipProps }, (_g = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _g === void 0 ? void 0 : _g.props))), (alwayShowSendButton || message) && ((0, jsx_runtime_1.jsx)(SendButton_1.default, Object.assign({ value: message, onClick: () => handleSend(message), isDisabled: isSendButtonDisabled, tooltipContent: (_h = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _h === void 0 ? void 0 : _h.tooltipContent, isCompact: isCompact, tooltipProps: (_j = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _j === void 0 ? void 0 : _j.tooltipProps }, (_k = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _k === void 0 ? void 0 : _k.props)))] }));
    };
    const hasGroupedActions = additionalActions || (isAttachButtonAtStart && isMultiline);
    const messageBarContents = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [isAttachButtonAtStart && !isMultiline && ((0, jsx_runtime_1.jsx)("div", { className: "pf-chatbot__message-bar-actions test", children: renderAttachButton() })), (0, jsx_runtime_1.jsx)("div", { className: `pf-chatbot__message-bar-input ${isCompact ? 'pf-m-compact' : ''}`, children: (0, jsx_runtime_1.jsx)(react_core_1.TextArea, Object.assign({ className: "pf-chatbot__message-textarea", value: message, onChange: handleChange, "aria-label": isListeningMessage ? listeningText : placeholder, placeholder: isListeningMessage ? listeningText : placeholder, ref: textareaRef, onKeyDown: handleKeyDown, onCompositionStart: handleCompositionStart, onCompositionEnd: handleCompositionEnd }, props)) }), (0, jsx_runtime_1.jsx)("div", { className: (0, react_styles_1.css)('pf-chatbot__message-bar-actions', hasGroupedActions && 'pf-m-grouped'), children: hasGroupedActions ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: (0, react_styles_1.css)('pf-chatbot__message-bar-actions-group'), children: [isAttachButtonAtStart && renderAttachButton(), additionalActions] }), (0, jsx_runtime_1.jsx)("div", { className: (0, react_styles_1.css)('pf-chatbot__message-bar-actions-group'), children: renderButtons() })] })) : (renderButtons()) })] }));
    if (attachMenuProps) {
        return ((0, jsx_runtime_1.jsx)(AttachMenu_1.default, Object.assign({ toggle: (toggleRef) => ((0, jsx_runtime_1.jsx)("div", { ref: toggleRef, className: (0, react_styles_1.css)('pf-chatbot__message-bar', isMultiline && 'pf-m-multiline', className), children: messageBarContents })), filteredItems: attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.attachMenuItems }, (attachMenuProps && { isOpen: attachMenuProps.isAttachMenuOpen }), { onOpenChange: (isAttachMenuOpen) => {
                var _a;
                (_a = attachButtonRef.current) === null || _a === void 0 ? void 0 : _a.focus();
                attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.setIsAttachMenuOpen(isAttachMenuOpen);
                (attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.onAttachMenuOpenChange) && (attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.onAttachMenuOpenChange(isAttachMenuOpen));
            }, onOpenChangeKeys: attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.onAttachMenuOnOpenChangeKeys, onSelect: attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.onAttachMenuSelect }, (attachMenuProps && { handleTextInputChange: attachMenuProps.onAttachMenuInputChange }), { popperProps: { direction: 'up', distance: 8 }, searchInputPlaceholder: attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.attachMenuInputPlaceholder }, attachMenuProps)));
    }
    return ((0, jsx_runtime_1.jsx)("div", { className: (0, react_styles_1.css)('pf-chatbot__message-bar', isPrimary && 'pf-m-primary', hasAiIndicator && 'pf-v6-m-ai-indicator', isThinking && 'pf-v6-m-thinking', isMultiline && 'pf-m-multiline', className), children: messageBarContents }));
};
exports.MessageBarBase = MessageBarBase;
const MessageBar = (0, react_1.forwardRef)((props, ref) => ((0, jsx_runtime_1.jsx)(exports.MessageBarBase, Object.assign({ innerRef: ref }, props))));
exports.MessageBar = MessageBar;
exports.default = MessageBar;
