import { Host, h } from "@stencil/core";
import { computePosition, autoUpdate, offset, flip, shift } from "@floating-ui/dom";
import { ZIconButton } from "../internal-component/z-icon-button";
import { chatInputStore, configStore, deviceModeStore, messagesStore, selectedChatStore, selectedMessageToReplyStore, translateStore } from "../../store/store";
import { getGroupMembers, saveUserEvent, sendMessage, translateChatMessage, updateChat } from "../../api";
import { scrollBottomMessage, serviceUpdateChatItem, serviceUpdateMessageItems, storeTranslation } from "../../store/message";
import { uploadFileService } from "../../utils/upload";
import dayjs from "dayjs";
import { base64ToFileList, useTranslation } from "../../utils/utils";
import { closeDialog, handleError, openDialog } from "../../store/dialog";
import { bahtIcon, stickerSmile } from "../../utils/icon-svg";
import { ZButton } from "../internal-component/z-button";
import { Icon } from "../internal-component/icon";
import { handleGetChat } from "../../store/chat";
import { BASE_ZIGNAL_CMS_URL, MESSAGE_LIMIT, TRANSLATE_LANGUAGES } from "../../utils/constant";
import { emitTyping, emitStopTyping } from "../../utils/socket";
import { getCurrentAdmin } from "../../store/typing";
import { getSenderName, openWindow } from "../../utils/func";
export class ChatInput {
    disposeListener;
    // Typing indicator state
    isTypingSent = false;
    typingThrottleTimer;
    value = '';
    // @State() originalText: string = '';
    images = [];
    isLoading = false;
    isFileLoading = false;
    isImageLoading = false;
    isTranslated = false;
    isTranslateLoading = false;
    showQuickMessageModal = false;
    hasQuickMessageModalOpened = false;
    isQuickMessageLoading = false;
    showDialogBill = false;
    isDialogBillLoading = false;
    showDialogSticker = false;
    isExpanded = false;
    isFocused = false;
    groupMembers = [];
    mentionees = [];
    showMentionList = false;
    mentionSearchText = '';
    mentionStartIndex = -1;
    selectedMentionIndex = 0;
    send;
    inputEl;
    overlayEl;
    mentionPopperEl;
    popperCleanup;
    onFocusRequested() {
        const isMobile = deviceModeStore.get('mode') === 'mobile';
        if (this.inputEl && !isMobile)
            this.inputEl.focus();
    }
    componentDidLoad() {
        this.adjustHeight();
        this.onFocusRequested();
    }
    componentDidUpdate() {
        this.adjustHeight();
    }
    handleShowMentionListChange(newValue) {
        if (newValue) {
            setTimeout(() => {
                const referenceEl = this.inputEl;
                if (!referenceEl || !this.mentionPopperEl)
                    return;
                const container = document.getElementById('chat-app') || document.body;
                container.appendChild(this.mentionPopperEl);
                this.popperCleanup = autoUpdate(referenceEl, this.mentionPopperEl, () => {
                    computePosition(referenceEl, this.mentionPopperEl, {
                        placement: 'top-start',
                        middleware: [offset(4), flip(), shift()],
                    }).then(({ x, y }) => {
                        Object.assign(this.mentionPopperEl.style, {
                            left: `${x}px`,
                            top: `${y}px`,
                            zIndex: '9999',
                        });
                    });
                });
            }, 0);
            document.addEventListener('mousedown', this.handleOutsideClick);
        }
        else {
            if (this.popperCleanup) {
                this.popperCleanup();
                this.popperCleanup = undefined;
            }
            if (this.mentionPopperEl) {
                this.mentionPopperEl.remove();
            }
            document.removeEventListener('mousedown', this.handleOutsideClick);
        }
    }
    handleOutsideClick = (e) => {
        if (this.showMentionList &&
            this.mentionPopperEl && !this.mentionPopperEl.contains(e.target) &&
            this.inputEl && !this.inputEl.contains(e.target)) {
            this.showMentionList = false;
            this.mentionSearchText = '';
            this.mentionStartIndex = -1;
        }
    };
    async componentWillLoad() {
        this.disposeListener = selectedChatStore.onChange('selectedChat', async (newChat) => {
            // Stop typing for old chat when switching
            this.handleStopTyping();
            // Reset reply state so it doesn't carry over to the new chat
            selectedMessageToReplyStore.reset();
            if (!newChat) {
                this.value = '';
                this.isTranslated = false;
                this.showDialogBill = false;
                this.showQuickMessageModal = false;
                this.hasQuickMessageModalOpened = false;
                this.groupMembers = [];
                return;
            }
            this.value = '';
            this.images = [];
            this.isTranslated = false;
            this.showDialogBill = false;
            this.showQuickMessageModal = false;
            this.hasQuickMessageModalOpened = false;
            this.getAllGroupMembers();
        });
        this.getAllGroupMembers();
    }
    handleInput = (e) => {
        const target = e.target;
        this.value = target.value;
        this.isTranslated = false;
        this.adjustHeight();
        this.isExpanded = false;
        // Typing indicator logic
        if (this.value.length > 0) {
            this.handleThrottledTyping();
        }
        else if (this.isTypingSent) {
            this.handleStopTyping();
        }
        const selectedChat = selectedChatStore.get('selectedChat');
        if (selectedChat && (selectedChat.type === 'group' && selectedChat.channel === 'line')) {
            this.checkMention(target);
        }
        else {
            this.showMentionList = false;
        }
    };
    checkMention(target) {
        const cursorPosition = target.selectionStart;
        const textBeforeCursor = this.value.substring(0, cursorPosition);
        const lastAtIndex = textBeforeCursor.lastIndexOf('@');
        if (lastAtIndex !== -1) {
            const isStartOrSpace = lastAtIndex === 0 || textBeforeCursor[lastAtIndex - 1] === ' ' || textBeforeCursor[lastAtIndex - 1] === '\n';
            if (isStartOrSpace) {
                const searchText = textBeforeCursor.substring(lastAtIndex + 1);
                if (!searchText.includes(' ') && !searchText.includes('\n')) {
                    this.mentionSearchText = searchText.toLowerCase();
                    this.mentionStartIndex = lastAtIndex;
                    this.showMentionList = true;
                    if (!this.groupMembers.length) {
                        this.getAllGroupMembers();
                    }
                    return;
                }
            }
        }
        this.showMentionList = false;
    }
    selectMention = (member) => {
        const textBeforeMention = this.value.substring(0, this.mentionStartIndex);
        const textAfterMention = this.value.substring(this.inputEl?.selectionStart || this.value.length);
        const mentionName = `@${member.nickname || member.name}`;
        const mentionText = `${mentionName} `;
        this.value = textBeforeMention + mentionText + textAfterMention;
        this.mentionees = [
            ...this.mentionees,
            {
                index: textBeforeMention.length,
                length: mentionName.length,
                type: member.id === 'all' ? 'all' : 'user',
                user_id: member.id === 'all' ? undefined : member.id,
            }
        ];
        this.showMentionList = false;
        this.mentionSearchText = '';
        this.mentionStartIndex = -1;
        this.selectedMentionIndex = 0;
        setTimeout(() => {
            if (this.inputEl) {
                this.inputEl.focus();
                const newCursorPos = textBeforeMention.length + mentionText.length;
                this.inputEl.setSelectionRange(newCursorPos, newCursorPos);
                this.adjustHeight();
            }
        }, 0);
    };
    filteredMembers = () => {
        const allMember = {
            id: 'all',
            name: 'All',
            nickname: 'All',
            picture_url: null
        };
        if (!this.mentionSearchText) {
            return [allMember, ...this.groupMembers];
        }
        const filtered = this.groupMembers.filter(m => (m.name || '').toLowerCase().includes(this.mentionSearchText) ||
            (m.nickname || '').toLowerCase().includes(this.mentionSearchText));
        if ('all'.includes(this.mentionSearchText.toLowerCase())) {
            return [allMember, ...filtered];
        }
        return filtered;
    };
    getValidMentionees() {
        const text = this.value;
        const validMentionees = [];
        this.mentionees.forEach(m => {
            let name = '';
            if (m.type === 'all') {
                name = '@All';
            }
            else {
                const member = this.groupMembers.find(g => g.id === m.user_id);
                if (member) {
                    name = `@${member.nickname || member.name}`;
                }
            }
            if (name) {
                let startIndex = 0, index;
                while ((index = text.indexOf(name, startIndex)) > -1) {
                    if (!validMentionees.find(vm => vm.index === index)) {
                        validMentionees.push({
                            index,
                            length: name.length,
                            type: m.type,
                            user_id: m.user_id,
                        });
                        break;
                    }
                    startIndex = index + name.length;
                }
            }
        });
        return validMentionees.sort((a, b) => a.index - b.index);
    }
    renderHighlightedText = () => {
        if (!this.value)
            return null;
        const validMentionees = this.getValidMentionees();
        const elements = [];
        if (!validMentionees || validMentionees.length === 0) {
            elements.push(h("span", null, this.value));
        }
        else {
            let lastIndex = 0;
            validMentionees.forEach((mention) => {
                if (mention.index >= lastIndex) {
                    const textBefore = this.value.substring(lastIndex, mention.index);
                    const mentionText = this.value.substring(mention.index, mention.index + mention.length);
                    if (textBefore)
                        elements.push(h("span", null, textBefore));
                    elements.push(h("span", { class: "z-text-with-link" }, mentionText));
                    lastIndex = mention.index + mention.length;
                }
            });
            const textAfter = this.value.substring(lastIndex);
            if (textAfter)
                elements.push(h("span", null, textAfter));
        }
        // Add a trailing newline if the textarea has one to keep scroll heights exact
        if (this.value.endsWith('\n')) {
            elements.push(h("br", null));
        }
        return elements;
    };
    handleScroll = (e) => {
        const target = e.target;
        if (this.overlayEl) {
            this.overlayEl.scrollTop = target.scrollTop;
            this.overlayEl.scrollLeft = target.scrollLeft;
        }
    };
    handleFocus = () => {
        this.isFocused = true;
        if (deviceModeStore.get('mode') === 'mobile') {
            this.isExpanded = false;
        }
    };
    handleBlur = () => {
        this.isFocused = false;
        this.isExpanded = false;
    };
    handleClick = () => {
        if (deviceModeStore.get('mode') === 'mobile') {
            this.isExpanded = false;
        }
    };
    handlePaste = (event) => {
        if (!event.clipboardData)
            return;
        const clipboardItems = event.clipboardData.items;
        if (!clipboardItems)
            return;
        for (let i = 0; i < clipboardItems.length; i++) {
            const item = clipboardItems[i];
            if (item.type.indexOf('image') !== -1) {
                const file = item.getAsFile();
                const reader = new FileReader();
                reader.onload = e => {
                    const base64 = e.target ? e.target.result : '';
                    this.images = [...this.images, base64];
                };
                if (file)
                    reader.readAsDataURL(file);
                event.preventDefault();
            }
        }
    };
    disconnectedCallback() {
        if (this.disposeListener)
            this.disposeListener();
        this.handleStopTyping();
        if (this.popperCleanup)
            this.popperCleanup();
        if (this.mentionPopperEl)
            this.mentionPopperEl.remove();
        document.removeEventListener('mousedown', this.handleOutsideClick);
    }
    /**
     * Throttled typing emit: sends at most 1 `typing` event every 3 seconds
     * while the admin continues to type.
     */
    handleThrottledTyping() {
        if (this.isTypingSent)
            return;
        const selectedChat = selectedChatStore.get('selectedChat');
        const admin = getCurrentAdmin();
        if (!selectedChat || !admin)
            return;
        emitTyping(selectedChat.id, admin);
        this.isTypingSent = true;
        this.typingThrottleTimer = setTimeout(() => {
            this.isTypingSent = false;
        }, 3000);
    }
    /**
     * Immediately emit stop_typing and reset throttle state.
     */
    handleStopTyping() {
        if (this.typingThrottleTimer) {
            clearTimeout(this.typingThrottleTimer);
            this.typingThrottleTimer = undefined;
        }
        if (this.isTypingSent) {
            const selectedChat = selectedChatStore.get('selectedChat');
            if (selectedChat) {
                emitStopTyping(selectedChat.id);
            }
            this.isTypingSent = false;
        }
    }
    adjustHeight() {
        const textarea = this.inputEl;
        if (!textarea)
            return;
        textarea.style.height = '0px';
        if (this.overlayEl) {
            this.overlayEl.style.height = '0px';
        }
        const isMobile = deviceModeStore.get('mode') === 'mobile';
        const lineHeight = isMobile ? 24 : 20;
        const padding = 16;
        const minHeight = (1 * lineHeight) + padding;
        const maxHeight = (5 * lineHeight) + padding;
        const scrollHeight = textarea.scrollHeight;
        const newHeight = this.value.length === 0
            ? minHeight
            : Math.min(Math.max(scrollHeight, minHeight), maxHeight);
        textarea.style.height = `${newHeight}px`;
        if (this.overlayEl) {
            this.overlayEl.style.height = `${newHeight}px`;
            const scrollbarWidth = textarea.offsetWidth - textarea.clientWidth;
            if (scrollbarWidth >= 0) {
                this.overlayEl.style.right = `${scrollbarWidth}px`;
            }
        }
        textarea.rows = Math.round((newHeight - padding) / lineHeight);
        // When content exceeds max height, scroll textarea to bottom so
        // the cursor stays visible, then sync the overlay's scroll position.
        if (scrollHeight > maxHeight) {
            requestAnimationFrame(() => {
                textarea.scrollTop = textarea.scrollHeight;
                if (this.overlayEl) {
                    this.overlayEl.scrollTop = textarea.scrollTop;
                }
            });
        }
    }
    canShowTranslateButton() {
        const translationSettings = configStore.get('translationSettings');
        const selectedChat = selectedChatStore.get('selectedChat');
        return ((selectedChat ? selectedChat.language : '') !== translationSettings.target_language &&
            !translationSettings.exclude_languages.includes((selectedChat ? selectedChat.language : '')) &&
            this.value.length > 0 &&
            !this.isTranslated);
    }
    renderTranslateButton() {
        const t = useTranslation();
        const selectedChat = selectedChatStore.get('selectedChat');
        if (this.canShowTranslateButton()) {
            const handleGetTranslateValue = () => {
                let _language = '';
                if (selectedChat) {
                    const chatLanguage = selectedChat.language.includes('_') ? selectedChat.language.split('_')[0] : selectedChat.language;
                    if (TRANSLATE_LANGUAGES && TRANSLATE_LANGUAGES[chatLanguage]) {
                        _language = TRANSLATE_LANGUAGES[chatLanguage];
                    }
                    else {
                        _language = chatLanguage;
                    }
                }
                return _language;
            };
            const title = selectedChat.language ? `${t('translate_to')} ${handleGetTranslateValue()}` : t('translate');
            const handleTranslate = async () => {
                if (configStore.get('package').level === 0) {
                    openDialog({
                        open: true,
                        type: "CUSTOM" /* DIALOG_TYPE.CUSTOM */,
                        title: t('feature_available_for_lite_package_or_higher'),
                        contentCustom: t('start_using_more_by_upgrading_your_package'),
                        buttonName: t('see_the_plans'),
                        customSign: h("div", { class: "flex justify-center" }, h(Icon, { name: "AlertCircle", addClass: "h-[80px] w-[80px] text-primary my-4" })),
                        onSubmitDialog: () => {
                            const _baseUrl = BASE_ZIGNAL_CMS_URL();
                            const baseUrl = `${_baseUrl}/${configStore.get('language')}/package`;
                            if (configStore.get('isZwiz')) {
                                openWindow(`${baseUrl}?business_id=${configStore.get('businessId')}&shop_id=${configStore.get('shopId')}&access_token=${configStore.get('accessToken')}`);
                            }
                            else {
                                window.location.href = baseUrl;
                            }
                        },
                        onCloseDialog: closeDialog,
                        displayCloseButton: true,
                    });
                }
                else {
                    try {
                        this.isTranslateLoading = true;
                        const _originalText = this.value.trim();
                        const selectedChatId = selectedChat ? selectedChat.id : '';
                        const translatedResponse = await translateChatMessage({
                            sessionId: selectedChatId,
                            text: _originalText,
                        });
                        if (!selectedChat.language) {
                            const chat = await handleGetChat(selectedChatId);
                            selectedChatStore.set('selectedChat', chat);
                        }
                        if (translatedResponse.text /*&& translatedResponse.text !== _originalText*/) {
                            chatInputStore.set('originalText', _originalText);
                            this.value = translatedResponse.text;
                            this.isTranslated = true;
                            setTimeout(async () => {
                                this.onFocusRequested();
                                this.adjustHeight();
                            }, 100);
                        }
                    }
                    catch (error) {
                        handleError(error, 'Failed to translate chat message');
                    }
                    finally {
                        this.isTranslateLoading = false;
                    }
                }
            };
            return h("div", null, h(ZButton, { size: "small", startIcon: h(Icon, { name: "Languages" }), title: title, label: deviceModeStore.get('mode') === 'mobile' ? undefined : title, onClick: handleTranslate, disabled: this.isTranslateLoading }));
        }
        return null;
    }
    getMessageLimit() {
        const selectedChat = selectedChatStore.get('selectedChat');
        if (!selectedChat)
            return null;
        const channel = selectedChat.channel;
        return MESSAGE_LIMIT[channel] ?? null;
    }
    isOverLimit() {
        const limit = this.getMessageLimit();
        if (limit === null)
            return false;
        return this.value.length > limit;
    }
    getAllGroupMembers = async () => {
        const selectedChat = selectedChatStore.get('selectedChat');
        if (!selectedChat)
            return;
        if (selectedChat.type !== 'group' || !selectedChat.group?.id)
            return;
        try {
            const groupMembersResponse = await getGroupMembers({
                type: 'group',
                channel: selectedChat.channel,
                id: selectedChat.group?.id,
            });
            this.groupMembers = groupMembersResponse.members || [];
        }
        catch (error) {
            handleError(error, 'Failed to get group members');
        }
    };
    render() {
        const t = useTranslation();
        const selectedChat = selectedChatStore.get('selectedChat');
        const replyMessage = selectedMessageToReplyStore.get('selectedMessageToReply');
        const originalText = chatInputStore.get('originalText');
        const isMobile = deviceModeStore.get('mode') === 'mobile';
        const messageLimit = this.getMessageLimit();
        const overLimit = this.isOverLimit();
        const sendingUploadFileMessages = async ({ files }) => {
            const uploadChatId = selectedChat ? selectedChat.id : '';
            if (files && files.length > 0) {
                const messages = [];
                for (const file of Array.from(files)) {
                    const response = await uploadFileService({
                        file,
                        filename: file.name.replace(/\s+/g, '-'),
                    });
                    if (response && response.id) {
                        messages.push({
                            type: 'file',
                            fileId: response.id,
                        });
                    }
                }
                if (messages.length === 0) {
                    removeErrorSendingMessage(uploadChatId);
                    return;
                }
                try {
                    await sendMessage({
                        sessionId: uploadChatId,
                        messages,
                    });
                }
                catch (error) {
                    removeErrorSendingMessage(uploadChatId);
                    handleError(error, 'Failed to send upload file message api');
                }
            }
        };
        const sendingMessages = (messages) => {
            const currentChat = selectedChatStore.get('selectedChat');
            if (!currentChat)
                return;
            const chatId = currentChat.id;
            const sendMessages = [];
            for (const { text, type, buttons, menu_list } of messages) {
                const currentDate = new Date();
                sendMessages.push({
                    text,
                    type,
                    sender: {
                        type: 'admin',
                    },
                    created_at: currentDate,
                    updated_at: currentDate,
                    message_at: currentDate,
                    reply_message: replyMessage,
                    buttons,
                    menu_list,
                    isSending: true,
                });
            }
            // Only add optimistic messages if we're still on the same chat
            const stillSameChat = selectedChatStore.get('selectedChat');
            if (!stillSameChat || stillSameChat.id !== chatId)
                return;
            serviceUpdateMessageItems({ updateMessages: sendMessages });
            const lastMessage = sendMessages[sendMessages.length - 1];
            serviceUpdateChatItem({
                chatId,
                updateValue: {
                    last_message: lastMessage.text,
                    last_message_at: lastMessage.message_at,
                },
            });
            scrollBottomMessage(chatId);
        };
        const sendingTextMessagesProcess = async (text, sendChatId) => {
            try {
                const chatId = sendChatId;
                const finalMentionees = this.getValidMentionees();
                const { messages } = await sendMessage({
                    sessionId: chatId,
                    messages: [
                        {
                            type: 'text',
                            text,
                            replyMessageId: replyMessage === null ? undefined : replyMessage.id,
                            ...(finalMentionees &&
                                finalMentionees.length > 0 &&
                                {
                                    mention: {
                                        mentionees: finalMentionees
                                    }
                                })
                        },
                    ],
                });
                this.mentionees = [];
                if (messages.length > 0) {
                    const messageId = messages[0].id;
                    await storeTranslation({
                        chat_id: chatId,
                        message_id: messageId,
                        translated_text: originalText,
                        is_translate_from_input: this.isTranslated ? true : undefined,
                    });
                    if (this.isTranslated && originalText) {
                        const translatedMessages = translateStore.get('translatedMessages');
                        const translatedMessagesMeta = translateStore.get('translatedMessagesMeta');
                        translateStore.set('translatedMessages', {
                            ...translatedMessages,
                            [messageId]: originalText,
                        });
                        translateStore.set('translatedMessagesMeta', {
                            ...translatedMessagesMeta,
                            [messageId]: { isTranslateFromInput: true },
                        });
                    }
                    // Deprecated get new message from api / socket instead
                    // if (originalText) {
                    //   const _messages = messagesStore.get('messages');
                    //   const idx = _messages.findIndex(message => message.id === messageId);
                    //   const translatedMessages = translateStore.get('translatedMessages');
                    //   translateStore.set('translatedMessages',
                    //     {
                    //       ...translatedMessages,
                    //       [messageId]: originalText,
                    //     });
                    //   const message = _messages[idx] ? _messages[idx] : _messages[Math.max(0, _messages.length - 1)];
                    //   const updatedMessages = [
                    //     {
                    //       ...message,
                    //       id: messageId,
                    //       translatedText: originalText,
                    //       reply_message: replyMessage,
                    //     },
                    //   ];
                    //   serviceUpdateMessageItems({ updateMessages: updatedMessages });
                    // }
                }
            }
            catch (error) {
                removeErrorSendingMessage(sendChatId);
                handleError(error, 'Failed to send message api');
            }
        };
        const handleSend = () => {
            const _value = this.value.trim();
            if (_value !== '') {
                this.send.emit(_value);
                // Capture chatId at send time to prevent race condition on quick chat switch
                const sendChatId = selectedChat ? selectedChat.id : '';
                try {
                    sendingMessages([
                        {
                            text: _value,
                            type: 'text',
                        },
                    ]);
                    sendingTextMessagesProcess(_value, sendChatId);
                    chatInputStore.set('originalText', '');
                    this.value = '';
                    selectedMessageToReplyStore.reset();
                    // Stop typing immediately on send
                    this.handleStopTyping();
                }
                catch (error) {
                    removeErrorSendingMessage(sendChatId);
                    handleError(error, 'Failed to send message');
                }
                finally {
                    this.adjustHeight();
                }
            }
        };
        const handleRemoveReply = () => {
            selectedMessageToReplyStore.reset();
        };
        const handleUploadMedia = (files, type, noLoading) => {
            const uploadMediaChatId = selectedChat ? selectedChat.id : '';
            try {
                if (!noLoading) {
                    if (type === 'file')
                        this.isFileLoading = true;
                    if (type === 'image')
                        this.isImageLoading = true;
                }
                if (files && files.length > 0) {
                    const messages = [];
                    for (let i = 0; i < Array.from(files).length; i++) {
                        messages.push({ type });
                    }
                    sendingMessages(messages);
                    sendingUploadFileMessages({ files });
                }
            }
            catch (error) {
                removeErrorSendingMessage(uploadMediaChatId);
                handleError(error, 'Failed to upload media');
            }
            finally {
                if (!noLoading) {
                    if (type === 'file')
                        this.isFileLoading = false;
                    if (type === 'image')
                        this.isImageLoading = false;
                }
                this.adjustHeight();
            }
        };
        const handleKeydown = (event) => {
            if (this.showMentionList) {
                const members = this.filteredMembers();
                if (event.key === 'ArrowUp') {
                    event.preventDefault();
                    this.selectedMentionIndex = (this.selectedMentionIndex - 1 + members.length) % members.length;
                    return;
                }
                else if (event.key === 'ArrowDown') {
                    event.preventDefault();
                    this.selectedMentionIndex = (this.selectedMentionIndex + 1) % members.length;
                    return;
                }
                else if (event.key === 'Enter') {
                    event.preventDefault();
                    if (members[this.selectedMentionIndex]) {
                        this.selectMention(members[this.selectedMentionIndex]);
                    }
                    return;
                }
                else if (event.key === 'Escape') {
                    event.preventDefault();
                    this.showMentionList = false;
                    return;
                }
            }
            if (event.key === 'Enter') {
                if (event.shiftKey) {
                    return;
                }
                else {
                    event.preventDefault();
                    handleSendAll();
                }
            }
        };
        const handleSendAll = () => {
            // Block all sending if over message limit
            if (this.isOverLimit()) {
                openDialog({
                    open: true,
                    type: "CUSTOM" /* DIALOG_TYPE.CUSTOM */,
                    title: t('message_limit_exceeded'),
                    contentCustom: t('message_limit_exceeded_desc'),
                    customSign: h("div", { class: "flex justify-center" }, h(Icon, { name: "AlertCircle", addClass: "h-[80px] w-[80px] text-primary my-4" })),
                    buttonName: t('ok'),
                    onCloseDialog: closeDialog,
                });
                return;
            }
            if (!this.isLoading) {
                handleSend();
                const files = base64ToFileList(this.images);
                this.images = [];
                if (files.length > 0) {
                    handleUploadMedia(files, 'image', true);
                }
            }
        };
        const handleSendTemplate = async (template) => {
            const selectedChatId = selectedChat ? selectedChat.id : '';
            const templateContentsLength = template ? template.contents.length : 0;
            if (this.isQuickMessageLoading || templateContentsLength === 0 || !selectedChatId) {
                return;
            }
            const isRemoteUrl = (url) => /^https?:\/\//i.test(url.trim());
            const dataUrlToFile = (dataUrl) => {
                try {
                    const [metadata, base64Data] = dataUrl.split(',');
                    if (!metadata || !base64Data) {
                        return null;
                    }
                    const mimeMatch = metadata.match(/data:(.*?);base64/);
                    const mime = (mimeMatch && mimeMatch.length >= 1) ? mimeMatch[1] : 'application/octet-stream';
                    const binary = atob(base64Data);
                    const length = binary.length;
                    const bytes = new Uint8Array(length);
                    for (let index = 0; index < length; index += 1) {
                        bytes[index] = binary.charCodeAt(index);
                    }
                    const extension = mime.split('/')[1] || 'bin';
                    const filename = `quick-message-${dayjs().format('x')}.${extension}`;
                    return new File([bytes], filename, { type: mime });
                }
                catch (error) {
                    console.error('[chat-input] Failed to convert data URL to file', error);
                    return null;
                }
            };
            const resolveMediaUrl = async (rawUrl, fileId) => {
                if (!rawUrl) {
                    return fileId ? { fileId } : {};
                }
                const trimmed = rawUrl.trim();
                if (!trimmed) {
                    return fileId ? { fileId } : {};
                }
                if (isRemoteUrl(trimmed) || !trimmed.startsWith('data:')) {
                    return { url: trimmed };
                }
                const file = dataUrlToFile(trimmed);
                if (!file) {
                    return {};
                }
                try {
                    const response = await uploadFileService({
                        file,
                        filename: file.name.replace(/\s+/g, '-'),
                        usageType: 'quick_message_template',
                    });
                    return (response ? {
                        fileId: response.id,
                        url: response.url
                    } : {});
                }
                catch (error) {
                    console.error('[chat-input] Failed to upload file for template', error);
                    return {};
                }
            };
            try {
                this.isQuickMessageLoading = true;
                const payloadMessages = [];
                for (const content of template.contents) {
                    if (!content) {
                        continue;
                    }
                    if (content.type === 'text') {
                        const text = (content.text || '').trim();
                        if (!text) {
                            continue;
                        }
                        payloadMessages.push({
                            type: 'text',
                            text,
                        });
                        continue;
                    }
                    if (content.type === 'image' || content.type === 'video' || content.type === 'file') {
                        const mediaUrl = await resolveMediaUrl(content.file_url, content.file?.id);
                        if (!mediaUrl.url && !mediaUrl.fileId) {
                            continue;
                        }
                        if (mediaUrl.fileId) {
                            payloadMessages.push({
                                type: 'file',
                                fileId: mediaUrl.fileId,
                            });
                        }
                        else if (mediaUrl.url) {
                            payloadMessages.push({
                                type: content.type,
                                url: mediaUrl.url,
                            });
                        }
                    }
                    if (content.type === 'button') {
                        payloadMessages.push({
                            text: (content.text || '').trim() || '',
                            type: 'button',
                            buttons: content.buttons,
                        });
                    }
                    if (content.type === 'menu_list') {
                        for (const menu of content.menu_list) {
                            const mediaUrl = await resolveMediaUrl(menu.file_url, menu.file?.id);
                            if (mediaUrl.fileId) {
                                menu.file_id = mediaUrl.fileId;
                                delete menu.file_url;
                            }
                            else if (mediaUrl.url) {
                                menu.file_url = mediaUrl.url;
                                delete menu.file_id;
                            }
                            menu.file_url = menu.file_url || menu.file.url;
                        }
                        payloadMessages.push({
                            type: 'menu_list',
                            menu_list: content.menu_list,
                        });
                    }
                }
                if (payloadMessages.length === 0) {
                    return;
                }
                for (const message of payloadMessages) {
                    try {
                        sendingMessages([message]);
                        await sendMessage({
                            sessionId: selectedChat.id,
                            messages: [message],
                        });
                    }
                    catch (error) {
                        removeErrorSendingMessage();
                        handleError(error, 'Failed to send quick message template');
                    }
                }
                this.showQuickMessageModal = false;
            }
            catch (error) {
                removeErrorSendingMessage();
                handleError(error, 'Failed to send quick message template');
            }
            finally {
                this.isQuickMessageLoading = false;
            }
        };
        const removeErrorSendingMessage = (chatId) => {
            // Only remove sending messages if we're still on the same chat
            if (chatId) {
                const currentChat = selectedChatStore.get('selectedChat');
                if (!currentChat || currentChat.id !== chatId)
                    return;
            }
            //remove the message when error
            const messages = messagesStore.get('messages');
            messagesStore.set('messages', messages.filter(message => !message.isSending));
        };
        const handleSendQuickMessageLibrary = async ({ /*type, */ items }) => {
            const selectedChatId = selectedChat ? selectedChat.id : '';
            const itemsLength = items ? items.length : 0;
            if (this.isQuickMessageLoading || !selectedChatId || !itemsLength) {
                return;
            }
            try {
                this.isQuickMessageLoading = true;
                for (const item of items) {
                    const payload = {
                        type: 'file',
                        filename: item.file.name,
                        mimeType: item.file.mime_type || 'application/octet-stream',
                        fileId: item.file.id,
                    };
                    sendingMessages([payload]);
                    await sendMessage({
                        sessionId: selectedChatId,
                        messages: [payload],
                    });
                    this.showQuickMessageModal = false;
                }
            }
            catch (error) {
                removeErrorSendingMessage(selectedChatId);
                handleError(error, 'Failed to send quick message library item');
            }
            finally {
                this.isQuickMessageLoading = false;
            }
        };
        const handleRemoveImage = (index) => {
            this.images = this.images.filter((_, i) => i !== index);
        };
        const handleUnSpamChatClick = async () => {
            try {
                this.isLoading = true;
                const selectedChatId = selectedChat ? selectedChat.id : '';
                const { code } = await updateChat({
                    sessionId: selectedChatId,
                    spam: false,
                });
                if (code === 'chat-updated') {
                    //Requirement: No need to update chatStore waiting user refresh or click other chat
                    const updateSelectedChat = {
                        ...selectedChatStore.get('selectedChat'),
                        spam: false,
                    };
                    selectedChatStore.set('selectedChat', updateSelectedChat);
                }
            }
            catch (error) {
                handleError(error, 'Failed to update chat spam status');
            }
            finally {
                this.isLoading = false;
            }
        };
        const handleOpenDialogBillEditor = () => {
            this.showDialogBill = true;
        };
        const handleCloseDialogBillEditor = () => {
            this.showDialogBill = false;
        };
        const handleCreateDialogBillEditor = async (value) => {
            try {
                this.isDialogBillLoading = true;
                const selectedChatId = selectedChat ? selectedChat.id : '';
                const response = await saveUserEvent({
                    sessionId: selectedChatId,
                    ...value,
                });
                if (response) {
                    this.showDialogBill = false;
                }
            }
            catch (error) {
                handleError(error, 'Failed to save user event dialog bill');
            }
            finally {
                this.isDialogBillLoading = false;
            }
        };
        const handleSendSticker = async (packageId, stickerId) => {
            const stickerChatId = selectedChat ? selectedChat.id : '';
            try {
                const message = {
                    type: 'sticker',
                    packageId,
                    stickerId,
                };
                sendingMessages([message]);
                await sendMessage({
                    sessionId: stickerChatId,
                    messages: [message],
                });
            }
            catch (error) {
                removeErrorSendingMessage(stickerChatId);
                handleError(error, 'Failed to send sticker');
            }
            finally {
                this.adjustHeight();
            }
        };
        if (!selectedChat)
            return null;
        const connection = configStore.get('connectionList').find(connection => connection.type === 'zwiz' && connection.channels?.find(channel => channel.id === selectedChat?.connection?.id));
        const isZignalQuickMessage = selectedChat.connection.type !== 'zwiz';
        const shouldKeepQuickMessageModalMounted = !isZignalQuickMessage && this.hasQuickMessageModalOpened;
        const shouldRenderQuickMessageModal = this.showQuickMessageModal || shouldKeepQuickMessageModalMounted;
        const hasButton = this.canShowTranslateButton();
        const autoHide = isMobile ? this.isFocused : this.value.length > 0;
        const showIcons = !autoHide || this.isExpanded;
        return (h(Host, null, selectedChat.spam ? (h("div", { class: "chat-input-spam-wrapper" }, "\u0E44\u0E21\u0E48\u0E2A\u0E32\u0E21\u0E32\u0E23\u0E16\u0E2A\u0E48\u0E07\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E44\u0E14\u0E49 \u0E40\u0E19\u0E37\u0E48\u0E2D\u0E07\u0E08\u0E32\u0E01\u0E21\u0E35\u0E01\u0E32\u0E23\u0E2A\u0E41\u0E1B\u0E21\u0E1C\u0E39\u0E49\u0E43\u0E0A\u0E49\u0E23\u0E32\u0E22\u0E19\u0E35\u0E49\u00A0", h("span", { class: "chat-input-spam-title", onClick: handleUnSpamChatClick }, "\u0E22\u0E01\u0E40\u0E25\u0E34\u0E01\u0E2A\u0E41\u0E1B\u0E21"))) : (h("div", { class: "chat-input" }, replyMessage !== null && (h("div", { class: "chat-input-reply-wrapper" }, h("div", { class: "text-black" }, "Replying to ", replyMessage.sender.type === 'admin' ? 'your self' : getSenderName(replyMessage.sender), h("div", { class: "chat-input-reply-text" }, replyMessage.text)), h("div", { class: "mb-auto" }, h(ZIconButton, { variant: "text", iconName: "X", onClick: handleRemoveReply })))), this.images.length > 0 && (h("div", { class: "chat-input-image-wrapper scroll-container" }, this.images.map((img, idx) => (h("div", { class: "relative" }, h("div", { class: "chat-input-image-button" }, h(ZIconButton, { variant: "text", iconName: "CircleX", onClick: () => handleRemoveImage(idx) })), h("img", { key: idx, src: img, style: { maxWidth: '150px', margin: '5px', borderRadius: '5px' }, loading: "lazy" })))))), h("div", { class: "chat-input-file-wrapper" }, h("div", { class: "flex items-center space-x-1 pb-1" }, autoHide && (h(ZIconButton, { variant: "text", iconName: this.isExpanded ? 'ChevronLeft' : 'ChevronRight', addClassIcon: "chat-input-icon", onClick: () => (this.isExpanded = !this.isExpanded) })), showIcons && (h("div", { class: "flex items-center space-x-1" }, selectedChat.channel !== 'tiktok' &&
            h("slot", null, h(ZIconButton, { variant: "text", iconName: "Paperclip", addClassIcon: "chat-input-icon", onClick: () => {
                    if (document.getElementById('fileInput'))
                        document.getElementById('fileInput').click();
                }, isLoading: this.isFileLoading }), h("input", { type: "file", id: "fileInput", hidden: true, onChange: event => handleUploadMedia(event.target.files, 'file') })), h(ZIconButton, { variant: "text", iconName: "Camera", addClassIcon: "chat-input-icon", onClick: () => {
                if (document.getElementById('cameraInput'))
                    document.getElementById('cameraInput').click();
            }, isLoading: this.isImageLoading }), h("input", { type: "file", id: "cameraInput", accept: "image/*", capture: "environment", hidden: true, onChange: event => handleUploadMedia(event.target.files, 'image') }), h(ZIconButton, { variant: "text", iconName: "Folder", addClassIcon: "chat-input-icon", onClick: () => {
                this.hasQuickMessageModalOpened = true;
                this.showQuickMessageModal = true;
            }, isLoading: this.isQuickMessageLoading }), selectedChat && connection && connection?.type === 'zwiz' && connection?.platform === 'sme' && selectedChat.channel === 'facebook' && (h("div", { class: "px-1" }, h(ZIconButton, { noPadding: true, variant: "text", icon: bahtIcon(), onClick: () => handleOpenDialogBillEditor(), isLoading: this.isDialogBillLoading }), this.showDialogBill && (h("div", { class: "dialog-backdrop" }, h("dialog-bill-editor", { onCancel: handleCloseDialogBillEditor, onCreate: event => {
                if (event)
                    handleCreateDialogBillEditor(event.detail);
            } }))))), selectedChat.channel === 'line' && (h("div", { class: "flex items-center" }, h(ZIconButton, { variant: "text", icon: stickerSmile(), addClassIcon: "chat-input-icon", onClick: () => (this.showDialogSticker = true), noPaddingY: true })))))), h("div", { class: "chat-input-textarea-wrapper" }, h("div", { class: `chat-input-textarea-overlay ${isMobile ? 'text-base' : 'text-sm'}`, "aria-hidden": "true", ref: el => this.overlayEl = el }, this.renderHighlightedText()), h("textarea", { id: "message-input", ref: el => (this.inputEl = el), class: `chat-input-textarea-input scroll-container ${hasButton ? 'has-translate-button' : ''} ${isMobile ? 'text-base' : 'text-sm'}`, placeholder: messageLimit !== null ? `${t('type_message_here')}` : t('type_message_here'), value: this.value, onInput: this.handleInput, onPaste: this.handlePaste, onKeyDown: handleKeydown, onFocus: this.handleFocus, onBlur: this.handleBlur, onScroll: this.handleScroll, onClick: this.handleClick, disabled: this.isLoading || this.isTranslateLoading }), h("div", { class: `chat-input-mention-popup ${this.showMentionList && this.filteredMembers().length > 0 ? '' : 'hidden!'}`, ref: el => this.mentionPopperEl = el }, h("div", { class: "chat-input-mention-header" }, h(ZIconButton, { variant: "text", iconName: "X", onClick: (e) => {
                e.preventDefault();
                e.stopPropagation();
                this.showMentionList = false;
                this.mentionSearchText = '';
                this.mentionStartIndex = -1;
            }, noPaddingY: true, noPadding: true, addClassIcon: "h-3 w-3 text-theme-gray" })), h("div", { class: "chat-input-mention-list scroll-container" }, this.filteredMembers().map((member, idx) => (h("div", { key: member.id, class: `chat-input-mention-item ${idx === this.selectedMentionIndex ? 'selected' : ''}`, onMouseDown: (e) => {
                e.preventDefault();
                this.selectMention(member);
            } }, member.id === 'all' ? (h("div", { class: "chat-input-mention-avatar-all" }, h("span", null, "@"))) : (h("z-avatar", { pictureUrl: member.picture_url, displayName: member.nickname || member.name, size: "small" })), h("div", { class: "flex-1 min-w-0" }, h("div", { class: "text-surface text-sm font-medium truncate" }, member.nickname || member.name))))))), h("div", { class: "chat-input-bottom-row" }, messageLimit !== null && (h("span", { class: `chat-input-char-counter ${overLimit ? 'chat-input-char-counter--over' : ''}` }, this.value.length, "/", messageLimit)), hasButton && (h("div", { class: "chat-input-translate-button-wrapper" }, this.renderTranslateButton())))), h("div", { class: "pb-1 flex items-center" }, h(ZIconButton, { variant: "text", iconName: "Send", onClick: handleSendAll, addClassIcon: "chat-input-icon" }))))), shouldRenderQuickMessageModal && (h("quick-message-modal", { isOpen: this.showQuickMessageModal, onClose: () => (this.showQuickMessageModal = false), onSendTemplate: (event) => handleSendTemplate(event.detail), onSendQuickMessageLibrary: (event) => handleSendQuickMessageLibrary(event.detail), isZignal: isZignalQuickMessage })), this.showDialogSticker && (h("dialog-sticker", { onClose: () => (this.showDialogSticker = false), onSendSticker: (event) => handleSendSticker(event.detail.packageId, event.detail.stickerId) }))));
    }
    static get is() { return "chat-input"; }
    static get originalStyleUrls() {
        return {
            "$": ["chat-input.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["chat-input.css"]
        };
    }
    static get states() {
        return {
            "value": {},
            "images": {},
            "isLoading": {},
            "isFileLoading": {},
            "isImageLoading": {},
            "isTranslated": {},
            "isTranslateLoading": {},
            "showQuickMessageModal": {},
            "hasQuickMessageModalOpened": {},
            "isQuickMessageLoading": {},
            "showDialogBill": {},
            "isDialogBillLoading": {},
            "showDialogSticker": {},
            "isExpanded": {},
            "isFocused": {},
            "groupMembers": {},
            "mentionees": {},
            "showMentionList": {},
            "mentionSearchText": {},
            "mentionStartIndex": {},
            "selectedMentionIndex": {}
        };
    }
    static get events() {
        return [{
                "method": "send",
                "name": "send",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                }
            }];
    }
    static get watchers() {
        return [{
                "propName": "showMentionList",
                "methodName": "handleShowMentionListChange"
            }];
    }
    static get listeners() {
        return [{
                "name": "focusRequested",
                "method": "onFocusRequested",
                "target": "body",
                "capture": false,
                "passive": false
            }];
    }
}
