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;
};
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { forwardRef, useCallback, useEffect, useRef, useState } from 'react';
import { TextArea } from '@patternfly/react-core';
// Import Chatbot components
import SendButton from './SendButton';
import MicrophoneButton from './MicrophoneButton';
import { AttachButton } from './AttachButton';
import AttachMenu from '../AttachMenu';
import StopButton from './StopButton';
export const MessageBarBase = (_a) => {
    var _b;
    var { onSendMessage, className, alwayShowSendButton, placeholder = 'Send a message...', hasAttachButton = true, 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 } = _a, props = __rest(_a, ["onSendMessage", "className", "alwayShowSendButton", "placeholder", "hasAttachButton", "hasMicrophoneButton", "listeningText", "handleAttach", "attachMenuProps", "isSendButtonDisabled", "handleStopButton", "hasStopButton", "buttonProps", "onChange", "displayMode", "value", "isCompact", "allowedFileTypes", "minSize", "maxSize", "maxFiles", "isAttachmentDisabled", "onAttach", "onAttachRejected", "validator", "dropzoneProps", "innerRef", "isPrimary"]);
    // Text Input
    // --------------------------------------------------------------------------
    const [message, setMessage] = useState(value !== null && value !== void 0 ? value : '');
    const [isListeningMessage, setIsListeningMessage] = useState(false);
    const [hasSentMessage, setHasSentMessage] = useState(false);
    const [isComposing, setIsComposing] = useState(false);
    const inputRef = useRef(null);
    const textareaRef = (_b = innerRef) !== null && _b !== void 0 ? _b : inputRef;
    const attachButtonRef = useRef(null);
    const topMargin = '1rem';
    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', '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 setAutoWidth = useCallback((field) => {
        const parent = field.parentElement;
        if (parent) {
            const grandparent = parent.parentElement;
            if (textIsLongerThan2Lines(field) && 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);
        }
    };
    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]);
    useEffect(() => {
        const field = textareaRef.current;
        if (field) {
            if (field.value === '') {
                setInitialLineHeight(field);
            }
            else {
                setAutoHeight(field);
                setAutoWidth(field);
            }
        }
    }, [displayMode, message, setAutoWidth]);
    useEffect(() => {
        const field = textareaRef.current;
        if (field) {
            setInitialLineHeight(field);
            setHasSentMessage(false);
        }
    }, [hasSentMessage]);
    const handleChange = useCallback((event) => {
        onChange && onChange(event, event.target.value);
        if (textareaRef.current) {
            if (event.target.value === '') {
                setInitialLineHeight(textareaRef.current);
            }
            else {
                setAutoHeight(textareaRef.current);
            }
        }
        setMessage(event.target.value);
    }, [onChange]);
    // Handle sending message
    const handleSend = useCallback((newMessage) => {
        onSendMessage(newMessage);
        setHasSentMessage(true);
        setMessage('');
    }, [onSendMessage]);
    const handleKeyDown = 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 = useCallback(() => {
        setIsComposing(true);
    }, []);
    const handleCompositionEnd = 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 renderButtons = () => {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
        if (hasStopButton && handleStopButton) {
            return (_jsx(StopButton, 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 (_jsxs(_Fragment, { children: [attachMenuProps && (_jsx(AttachButton, Object.assign({ ref: attachButtonRef, onClick: handleAttachMenuToggle, isDisabled: isListeningMessage, tooltipContent: (_d = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _d === void 0 ? void 0 : _d.tooltipContent, isCompact: isCompact, tooltipProps: (_e = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _e === void 0 ? void 0 : _e.tooltipProps, allowedFileTypes: allowedFileTypes, minSize: minSize, maxSize: maxSize, maxFiles: maxFiles, isAttachmentDisabled: isAttachmentDisabled, onAttach: onAttach, onAttachRejected: onAttachRejected, validator: validator, dropzoneProps: dropzoneProps }, (_f = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _f === void 0 ? void 0 : _f.props))), !attachMenuProps && hasAttachButton && (_jsx(AttachButton, Object.assign({ onAttachAccepted: handleAttach, isDisabled: isListeningMessage, tooltipContent: (_g = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _g === void 0 ? void 0 : _g.tooltipContent, inputTestId: (_h = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _h === void 0 ? void 0 : _h.inputTestId, isCompact: isCompact, tooltipProps: (_j = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _j === void 0 ? void 0 : _j.tooltipProps, allowedFileTypes: allowedFileTypes, minSize: minSize, maxSize: maxSize, maxFiles: maxFiles, isAttachmentDisabled: isAttachmentDisabled, onAttach: onAttach, onAttachRejected: onAttachRejected, validator: validator, dropzoneProps: dropzoneProps }, (_k = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.attach) === null || _k === void 0 ? void 0 : _k.props))), hasMicrophoneButton && (_jsx(MicrophoneButton, Object.assign({ isListening: isListeningMessage, onIsListeningChange: setIsListeningMessage, onSpeechRecognition: handleSpeechRecognition, tooltipContent: (_l = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _l === void 0 ? void 0 : _l.tooltipContent, language: (_m = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _m === void 0 ? void 0 : _m.language, isCompact: isCompact, tooltipProps: (_o = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _o === void 0 ? void 0 : _o.tooltipProps }, (_p = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _p === void 0 ? void 0 : _p.props))), (alwayShowSendButton || message) && (_jsx(SendButton, Object.assign({ value: message, onClick: () => handleSend(message), isDisabled: isSendButtonDisabled, tooltipContent: (_q = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _q === void 0 ? void 0 : _q.tooltipContent, isCompact: isCompact, tooltipProps: (_r = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _r === void 0 ? void 0 : _r.tooltipProps }, (_s = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _s === void 0 ? void 0 : _s.props)))] }));
    };
    const messageBarContents = (_jsxs(_Fragment, { children: [_jsx("div", { className: `pf-chatbot__message-bar-input ${isCompact ? 'pf-m-compact' : ''}`, children: _jsx(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)) }), _jsx("div", { className: "pf-chatbot__message-bar-actions", children: renderButtons() })] }));
    if (attachMenuProps) {
        return (_jsx(AttachMenu, Object.assign({ toggle: (toggleRef) => (_jsx("div", { ref: toggleRef, className: `pf-chatbot__message-bar ${className !== null && className !== void 0 ? 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 (_jsx("div", { className: `pf-chatbot__message-bar ${isPrimary ? 'pf-m-primary' : ''} ${className !== null && className !== void 0 ? className : ''}`, children: messageBarContents }));
};
const MessageBar = forwardRef((props, ref) => (_jsx(MessageBarBase, Object.assign({ innerRef: ref }, props))));
export { MessageBar };
export default MessageBar;
