'use client';

import React, { useRef, useEffect, useState, useCallback, useMemo } from 'react';
import {
    Smile,
    Paperclip,
    Mic,
    Send,
    X,
    StopCircle,
    Pause,
    Play,
    LayoutTemplate,
    BookOpen,
    Plus,
} from 'lucide-react';
import { motion, AnimatePresence } from 'framer-motion';
import EmojiPicker, { Theme } from 'emoji-picker-react';
import { groupApi, type GroupParticipant, type MessageTemplate, type TemplateType } from '../services/chatApiService';
import RichMessageComposer from './RichMessageComposer';
import TemplateLibrary from './TemplateLibrary';
import ScheduleMessageModal from './ScheduleMessageModal';
import FilePreviewModal from './FilePreviewModal';

interface Message {
    id: number;
    chat_id: number;
    message_id: string;
    text: string;
    direction: 'in' | 'out';
}

interface InputBarProps {
    newMessage: string;
    onNewMessageChange: (val: string) => void;
    onSend: (e?: React.FormEvent) => void;
    onPresence: () => void;
    onSendMedia: (file: File, caption?: string) => Promise<void>;
    onSendAudio: (blob: Blob) => Promise<void>;
    replyingTo: Message | null;
    onCancelReply: () => void;
    isMobile: boolean;
    selectedChat: any;
    instanceId?: string | null;
    mentions?: string[];
    onMentionsChange?: (mentions: string[]) => void;
}

const InputBar: React.FC<InputBarProps> = ({
    newMessage,
    onNewMessageChange,
    onSend,
    onPresence,
    onSendMedia,
    onSendAudio,
    replyingTo,
    onCancelReply,
    isMobile,
    selectedChat,
    instanceId,
    mentions = [],
    onMentionsChange,
}) => {
    const textareaRef = useRef<HTMLTextAreaElement>(null);
    const fileInputRef = useRef<HTMLInputElement>(null);
    const [showEmojiPicker, setShowEmojiPicker]             = useState(false);
    const [showAttachMenu, setShowAttachMenu]               = useState(false);
    const [previewFile, setPreviewFile]                     = useState<File | null>(null);
    const attachMenuRef = useRef<HTMLDivElement>(null);
    const [showRichComposer, setShowRichComposer]           = useState(false);
    const [showTemplateLibrary, setShowTemplateLibrary]     = useState(false);
    const [richInitialPayload, setRichInitialPayload]       = useState<Record<string, unknown> | undefined>();
    const [richInitialType, setRichInitialType]             = useState<TemplateType | undefined>();
    const [showScheduleModal, setShowScheduleModal]         = useState(false);
    const [schedulingPayload, setSchedulingPayload]         = useState<Record<string, unknown>>({});
    const [schedulingType, setSchedulingType]               = useState<TemplateType>('TEXT');
    const emojiPickerRef = useRef<HTMLDivElement>(null);

    // ── Mention autocomplete state ──────────────────────────────────────
    const [mentionQuery, setMentionQuery] = useState<string | null>(null);
    const [mentionIndex, setMentionIndex] = useState(0);
    const [participants, setParticipants] = useState<GroupParticipant[]>([]);
    const participantsCache = useRef<Record<string, GroupParticipant[]>>({});
    const mentionDropdownRef = useRef<HTMLDivElement>(null);

    const isGroupChat = selectedChat?.remote_jid?.endsWith('@g.us') || selectedChat?.jid?.endsWith('@g.us');
    const groupJid = selectedChat?.remote_jid || selectedChat?.jid;

    // Fetch group participants when group chat is selected
    useEffect(() => {
        if (!isGroupChat || !instanceId || !groupJid) {
            setParticipants([]);
            return;
        }
        if (participantsCache.current[groupJid]) {
            setParticipants(participantsCache.current[groupJid]);
            return;
        }
        groupApi.getParticipants(instanceId, groupJid)
            .then((data) => {
                participantsCache.current[groupJid] = data.participants;
                setParticipants(data.participants);
            })
            .catch(() => setParticipants([]));
    }, [isGroupChat, instanceId, groupJid]);

    // Filter participants by mention query
    const filteredParticipants = useMemo(() => {
        if (mentionQuery === null || !isGroupChat) return [];
        const q = mentionQuery.toLowerCase();
        // Only show participants that have a displayable name or phone
        return participants.filter((p) => {
            const label = p.name || p.phone || '';
            if (!label) return false;
            return q === '' || label.toLowerCase().includes(q);
        }).slice(0, 8);
    }, [mentionQuery, participants, isGroupChat]);

    // Detect @ trigger in text
    const detectMentionQuery = useCallback((text: string, cursorPos: number) => {
        if (!isGroupChat) { setMentionQuery(null); return; }
        const before = text.slice(0, cursorPos);
        const atMatch = before.match(/@([^\s@]*)$/);
        if (atMatch) {
            setMentionQuery(atMatch[1]);
            setMentionIndex(0);
        } else {
            setMentionQuery(null);
        }
    }, [isGroupChat]);

    const selectMention = useCallback((participant: GroupParticipant) => {
        const textarea = textareaRef.current;
        if (!textarea) return;
        const cursorPos = textarea.selectionStart;
        const before = newMessage.slice(0, cursorPos);
        const after = newMessage.slice(cursorPos);
        const atIdx = before.lastIndexOf('@');
        if (atIdx === -1) return;

        const displayName = participant.name || participant.phone;
        const replacement = `@${displayName} `;
        const newText = before.slice(0, atIdx) + replacement + after;

        onNewMessageChange(newText);
        setMentionQuery(null);

        // Add JID to mentions list
        if (onMentionsChange && !mentions.includes(participant.jid)) {
            onMentionsChange([...mentions, participant.jid]);
        }

        // Restore cursor
        requestAnimationFrame(() => {
            if (textareaRef.current) {
                const newCursorPos = atIdx + replacement.length;
                textareaRef.current.selectionStart = newCursorPos;
                textareaRef.current.selectionEnd = newCursorPos;
                textareaRef.current.focus();
            }
        });
    }, [newMessage, onNewMessageChange, mentions, onMentionsChange]);

    // Audio recording states
    const [isRecording, setIsRecording] = useState(false);
    const [isPaused, setIsPaused] = useState(false);
    const [recordingDuration, setRecordingDuration] = useState(0);
    const [micError, setMicError] = useState<string | null>(null);
    const mediaRecorderRef = useRef<MediaRecorder | null>(null);
    const audioChunksRef = useRef<Blob[]>([]);
    const timerRef = useRef<NodeJS.Timeout | null>(null);

    // navigator.mediaDevices só existe em contextos seguros (HTTPS ou localhost)
    const micAvailable = typeof window !== 'undefined' && !!window.isSecureContext && !!navigator.mediaDevices?.getUserMedia;

    // Auto-expand textarea
    useEffect(() => {
        if (textareaRef.current) {
            textareaRef.current.style.height = 'auto';
            textareaRef.current.style.height = `${Math.min(textareaRef.current.scrollHeight, 150)}px`;
        }
    }, [newMessage]);

    // Close emoji picker and attach menu on click outside
    useEffect(() => {
        const handleClickOutside = (event: MouseEvent) => {
            if (emojiPickerRef.current && !emojiPickerRef.current.contains(event.target as Node)) {
                setShowEmojiPicker(false);
            }
            if (attachMenuRef.current && !attachMenuRef.current.contains(event.target as Node)) {
                setShowAttachMenu(false);
            }
        };
        document.addEventListener('mousedown', handleClickOutside);
        return () => document.removeEventListener('mousedown', handleClickOutside);
    }, []);

    const handleKeyDown = (e: React.KeyboardEvent) => {
        // Mention dropdown navigation
        if (mentionQuery !== null && filteredParticipants.length > 0) {
            if (e.key === 'ArrowDown') {
                e.preventDefault();
                setMentionIndex((prev) => (prev + 1) % filteredParticipants.length);
                return;
            }
            if (e.key === 'ArrowUp') {
                e.preventDefault();
                setMentionIndex((prev) => (prev - 1 + filteredParticipants.length) % filteredParticipants.length);
                return;
            }
            if (e.key === 'Enter' || e.key === 'Tab') {
                e.preventDefault();
                selectMention(filteredParticipants[mentionIndex]);
                return;
            }
            if (e.key === 'Escape') {
                e.preventDefault();
                setMentionQuery(null);
                return;
            }
        }

        if (e.key === 'Enter' && !e.shiftKey) {
            e.preventDefault();
            onSend();
        }
    };

    const onEmojiClick = (emojiData: any) => {
        onNewMessageChange(newMessage + emojiData.emoji);
        // Do not close picker, common UX allows multiple emojis
    };

    const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        const file = e.target.files?.[0];
        if (file) {
            setPreviewFile(file);
            if (fileInputRef.current) fileInputRef.current.value = '';
        }
    };

    const handlePreviewConfirm = async (file: File, caption: string) => {
        await onSendMedia(file, caption);
        setPreviewFile(null);
    };

    const handlePreviewCancel = () => setPreviewFile(null);

    const startRecording = async () => {
        if (!micAvailable) {
            setMicError('Áudio requer HTTPS. Acesse via https:// para gravar.');
            setTimeout(() => setMicError(null), 4000);
            return;
        }
        setMicError(null);
        try {
            const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
            const mediaRecorder = new MediaRecorder(stream);
            mediaRecorderRef.current = mediaRecorder;
            audioChunksRef.current = [];

            mediaRecorder.ondataavailable = (event) => {
                if (event.data.size > 0) {
                    audioChunksRef.current.push(event.data);
                }
            };

            mediaRecorder.onstop = async () => {
                const mimeType = mediaRecorder.mimeType || 'audio/webm'
                const audioBlob = new Blob(audioChunksRef.current, { type: mimeType });
                await onSendAudio(audioBlob);
                stream.getTracks().forEach(track => track.stop());
            };

            mediaRecorder.start();
            setIsRecording(true);
            setIsPaused(false);
            setRecordingDuration(0);
            timerRef.current = setInterval(() => {
                setRecordingDuration(prev => prev + 1);
            }, 1000);
        } catch (err: any) {
            const denied = err?.name === 'NotAllowedError' || err?.name === 'PermissionDeniedError';
            const msg = denied
                ? 'Permissão de microfone negada.'
                : 'Não foi possível acessar o microfone.';
            setMicError(msg);
            setTimeout(() => setMicError(null), 4000);
        }
    };

    const togglePause = () => {
        const mr = mediaRecorderRef.current
        if (!mr) return
        if (isPaused) {
            mr.resume()
            setIsPaused(false)
            timerRef.current = setInterval(() => setRecordingDuration(prev => prev + 1), 1000)
        } else {
            mr.pause()
            setIsPaused(true)
            if (timerRef.current) clearInterval(timerRef.current)
        }
    }

    const stopRecording = () => {
        if (mediaRecorderRef.current && isRecording) {
            // Se estava pausado, retoma antes de parar para capturar o último chunk
            if (isPaused && mediaRecorderRef.current.state === 'paused') {
                mediaRecorderRef.current.resume()
            }
            mediaRecorderRef.current.stop();
            setIsRecording(false);
            setIsPaused(false);
            if (timerRef.current) clearInterval(timerRef.current);
        }
    };

    const handleTemplateSelect = (template: MessageTemplate) => {
        setRichInitialPayload(template.payload)
        setRichInitialType(template.type)
        setShowRichComposer(true)
    }

    const handleScheduleFromComposer = (type: TemplateType, payload: Record<string, unknown>) => {
        setSchedulingType(type)
        setSchedulingPayload(payload)
        setShowRichComposer(false)
        setShowScheduleModal(true)
    }

    const formatDuration = (seconds: number) => {
        const mins = Math.floor(seconds / 60);
        const secs = seconds % 60;
        return `${mins}:${secs.toString().padStart(2, '0')}`;
    };

    return (
        <>
        <div className="relative z-20">
            {/* Hidden File Input */}
            <input
                type="file"
                className="hidden"
                ref={fileInputRef}
                onChange={handleFileChange}
            />

            {/* Emoji Picker Popover */}
            <AnimatePresence>
                {showEmojiPicker && (
                    <motion.div
                        ref={emojiPickerRef}
                        initial={{ opacity: 0, y: 10, scale: 0.95 }}
                        animate={{ opacity: 1, y: 0, scale: 1 }}
                        exit={{ opacity: 0, y: 10, scale: 0.95 }}
                        className="absolute bottom-20 left-4 z-50 shadow-2xl rounded-2xl overflow-hidden border border-gray-100"
                    >
                        <EmojiPicker
                            onEmojiClick={onEmojiClick}
                            autoFocusSearch={false}
                            theme={Theme.LIGHT}
                            width={320}
                            height={400}
                        />
                    </motion.div>
                )}
            </AnimatePresence>

            {/* Reply Preview */}
            <AnimatePresence>
                {replyingTo && (
                    <motion.div
                        initial={{ opacity: 0, y: 20 }}
                        animate={{ opacity: 1, y: 0 }}
                        exit={{ opacity: 0, y: 20 }}
                        className="mx-4 mb-2 bg-white/80 backdrop-blur-sm border-l-[4px] border-[#00a884] rounded-lg px-4 py-3 flex items-start justify-between gap-4 shadow-sm"
                    >
                        <div className="min-w-0">
                            <div className="text-[12px] font-medium text-[#00a884] mb-1">
                                {replyingTo.direction === 'out' ? 'Respondendo a você' : 'Respondendo ao contato'}
                            </div>
                            <div className="text-sm text-gray-500 font-medium truncate italic">
                                {replyingTo.text || 'Anexo/Mídia'}
                            </div>
                        </div>
                        <button
                            type="button"
                            className="bg-gray-100 hover:bg-gray-200 text-gray-500 p-1 rounded-full transition-colors"
                            onClick={onCancelReply}
                        >
                            <X className="w-3.5 h-3.5 stroke-[3px]" />
                        </button>
                    </motion.div>
                )}
            </AnimatePresence>

            {/* Mic error banner */}
            <AnimatePresence>
                {micError && (
                    <motion.div
                        initial={{ opacity: 0, y: 6 }}
                        animate={{ opacity: 1, y: 0 }}
                        exit={{ opacity: 0, y: 6 }}
                        transition={{ duration: 0.18 }}
                        className="mx-4 mb-1 px-3 py-2 bg-amber-50 border border-amber-200 rounded-lg flex items-center gap-2"
                    >
                        <Mic className="w-3.5 h-3.5 text-amber-500 flex-shrink-0" />
                        <span className="text-xs text-amber-700">{micError}</span>
                    </motion.div>
                )}
            </AnimatePresence>

            {/* Main Input Bar */}
            <div className="min-h-[62px] px-4 py-2 bg-transparent flex items-center gap-2 shrink-0">
                {!isRecording ? (
                    <>
                        <div className="flex items-center gap-1">
                            {/* Grupo flutuante: + expande Anexar / Templates / Mensagem Rica */}
                            <div className="relative" ref={attachMenuRef}>
                                <button
                                    onClick={() => setShowAttachMenu(v => !v)}
                                    className={`p-2 rounded-full transition-all active:scale-95 ${showAttachMenu ? 'bg-[#00a884] text-white' : 'hover:bg-black/10 text-[#54656f]'}`}
                                    title="Mais opções"
                                >
                                    <motion.div
                                        animate={{ rotate: showAttachMenu ? 45 : 0 }}
                                        transition={{ duration: 0.18 }}
                                    >
                                        <Plus className="w-[26px] h-[26px]" />
                                    </motion.div>
                                </button>

                                <AnimatePresence>
                                    {showAttachMenu && (
                                        <motion.div
                                            initial={{ opacity: 0, y: 8, scale: 0.92 }}
                                            animate={{ opacity: 1, y: 0, scale: 1 }}
                                            exit={{ opacity: 0, y: 8, scale: 0.92 }}
                                            transition={{ duration: 0.15 }}
                                            className="absolute bottom-full left-0 mb-2 flex flex-col items-center gap-1 bg-white rounded-2xl shadow-2xl border border-gray-100 py-2 px-1.5"
                                        >
                                            {/* Anexar arquivo */}
                                            <button
                                                onClick={() => { fileInputRef.current?.click(); setShowAttachMenu(false); }}
                                                className="p-2.5 hover:bg-[#f0f2f5] rounded-xl transition-all text-[#54656f] active:scale-95 group relative"
                                                title="Anexar arquivo"
                                            >
                                                <Paperclip className="w-[22px] h-[22px] rotate-45" />
                                                <span className="absolute left-full ml-2 whitespace-nowrap text-xs bg-[#111b21] text-white px-2 py-1 rounded-lg opacity-0 group-hover:opacity-100 pointer-events-none transition-opacity">
                                                    Anexar
                                                </span>
                                            </button>

                                            {/* Biblioteca de templates */}
                                            <button
                                                onClick={() => { setShowTemplateLibrary(true); setShowAttachMenu(false); }}
                                                className="p-2.5 hover:bg-[#f0f2f5] rounded-xl transition-all text-[#54656f] active:scale-95 group relative"
                                                title="Templates salvos"
                                            >
                                                <BookOpen className="w-[22px] h-[22px]" />
                                                <span className="absolute left-full ml-2 whitespace-nowrap text-xs bg-[#111b21] text-white px-2 py-1 rounded-lg opacity-0 group-hover:opacity-100 pointer-events-none transition-opacity">
                                                    Templates
                                                </span>
                                            </button>

                                            {/* Mensagem rica */}
                                            <button
                                                onClick={() => { setRichInitialPayload(undefined); setRichInitialType(undefined); setShowRichComposer(true); setShowAttachMenu(false); }}
                                                className="p-2.5 hover:bg-[#f0f2f5] rounded-xl transition-all text-[#54656f] active:scale-95 group relative"
                                                title="Mensagem rica"
                                            >
                                                <LayoutTemplate className="w-[22px] h-[22px]" />
                                                <span className="absolute left-full ml-2 whitespace-nowrap text-xs bg-[#111b21] text-white px-2 py-1 rounded-lg opacity-0 group-hover:opacity-100 pointer-events-none transition-opacity">
                                                    Mensagem Rica
                                                </span>
                                            </button>
                                        </motion.div>
                                    )}
                                </AnimatePresence>
                            </div>

                            {/* Emoji — mantém no lugar */}
                            <button
                                onClick={() => setShowEmojiPicker(!showEmojiPicker)}
                                className={`p-2 hover:bg-black/10 rounded-full transition-all active:scale-95 ${showEmojiPicker ? 'text-[#00a884]' : 'text-[#54656f]'}`}
                                title="Emojis"
                            >
                                <Smile className="w-[26px] h-[26px]" />
                            </button>
                        </div>

                        <div className="flex-1 relative">
                            {/* Mention Autocomplete Dropdown */}
                            <AnimatePresence>
                                {mentionQuery !== null && filteredParticipants.length > 0 && (
                                    <motion.div
                                        ref={mentionDropdownRef}
                                        initial={{ opacity: 0, y: 6 }}
                                        animate={{ opacity: 1, y: 0 }}
                                        exit={{ opacity: 0, y: 6 }}
                                        transition={{ duration: 0.12 }}
                                        className="absolute bottom-full left-0 right-0 mb-1 bg-white rounded-lg shadow-xl border border-gray-200 max-h-[240px] overflow-y-auto z-50"
                                    >
                                        {filteredParticipants.map((p, i) => (
                                            <button
                                                key={p.jid}
                                                type="button"
                                                className={`w-full px-3 py-2 flex items-center gap-2 text-left text-sm hover:bg-[#f0f2f5] transition-colors ${
                                                    i === mentionIndex ? 'bg-[#e9edef]' : ''
                                                }`}
                                                onMouseDown={(e) => {
                                                    e.preventDefault();
                                                    selectMention(p);
                                                }}
                                                onMouseEnter={() => setMentionIndex(i)}
                                            >
                                                <div className="w-7 h-7 rounded-full bg-[#dfe5e7] flex items-center justify-center text-xs font-bold text-[#54656f] shrink-0">
                                                    {(p.name || p.phone || '?')[0].toUpperCase()}
                                                </div>
                                                <div className="min-w-0">
                                                    <div className="font-medium text-[#111b21] truncate">{p.name || p.phone}</div>
                                                    {p.name && <div className="text-[11px] text-[#667781] truncate">+{p.phone}</div>}
                                                </div>
                                                {p.admin && (
                                                    <span className="ml-auto text-[10px] bg-[#e7f8f2] text-[#00a884] px-1.5 py-0.5 rounded font-medium shrink-0">
                                                        {p.admin === 'superadmin' ? 'Admin' : 'Admin'}
                                                    </span>
                                                )}
                                            </button>
                                        ))}
                                    </motion.div>
                                )}
                            </AnimatePresence>

                            <label htmlFor="message-textarea" className="sr-only">Digite sua mensagem</label>
                            <textarea
                                id="message-textarea"
                                name="message-textarea"
                                ref={textareaRef}
                                rows={1}
                                placeholder="Digite uma mensagem"
                                className="w-full px-3 py-2.5 bg-white rounded-lg text-[15px] text-[#111b21] border-none focus:ring-0 focus:outline-none placeholder:text-[#667781] resize-none shadow-sm transition-all overflow-hidden leading-[1.4]"
                                value={newMessage}
                                onChange={(e) => {
                                    onNewMessageChange(e.target.value);
                                    onPresence();
                                    detectMentionQuery(e.target.value, e.target.selectionStart);
                                }}
                                onKeyDown={handleKeyDown}
                            />
                        </div>

                        <div className="transition-all flex items-center">
                            {newMessage.trim() ? (
                                <motion.button
                                    initial={{ scale: 0.5, opacity: 0 }}
                                    animate={{ scale: 1, opacity: 1 }}
                                    onClick={() => onSend()}
                                    className="p-2 text-[#54656f] hover:bg-black/10 rounded-full transition-all active:scale-90"
                                >
                                    <Send className="w-[26px] h-[26px]" />
                                </motion.button>
                            ) : (
                                <button
                                    onClick={startRecording}
                                    title={!micAvailable ? 'Requer HTTPS para gravar áudio' : 'Gravar áudio'}
                                    className={`p-2 rounded-full transition-all active:scale-90 ${
                                        !micAvailable
                                            ? 'text-[#aab7bf] cursor-not-allowed opacity-50'
                                            : 'hover:bg-black/10 text-[#54656f]'
                                    }`}
                                >
                                    <Mic className="w-[26px] h-[26px]" />
                                </button>
                            )}
                        </div>
                    </>
                ) : (
                    <div className={`flex-1 flex items-center justify-between rounded-2xl px-4 py-2 border shadow-inner ${isPaused ? 'bg-amber-50/70 border-amber-200' : 'bg-red-50/50 border-red-100'}`}>
                        {/* Indicador + tempo */}
                        <div className="flex items-center gap-3">
                            {isPaused ? (
                                <div className="w-3 h-3 bg-amber-400 rounded-full" />
                            ) : (
                                <div className="w-3 h-3 bg-red-500 rounded-full animate-ping" />
                            )}
                            <span className={`text-sm font-bold tracking-wider ${isPaused ? 'text-amber-600' : 'text-red-600'}`}>
                                {isPaused ? 'PAUSADO' : 'GRAVANDO'} {formatDuration(recordingDuration)}
                            </span>
                        </div>
                        {/* Controles */}
                        <div className="flex items-center gap-1.5">
                            {/* Cancelar */}
                            <button
                                onClick={() => {
                                    const mr = mediaRecorderRef.current
                                    if (mr) {
                                        mr.onstop = null;
                                        mr.stream?.getTracks().forEach(t => t.stop());
                                        if (mr.state !== 'inactive') mr.stop();
                                        setIsRecording(false);
                                        setIsPaused(false);
                                        if (timerRef.current) clearInterval(timerRef.current);
                                    }
                                }}
                                className="p-2 hover:bg-red-100 rounded-full text-red-400 transition-colors"
                                title="Cancelar"
                            >
                                <X className="w-5 h-5" />
                            </button>
                            {/* Pause / Resume */}
                            <button
                                onClick={togglePause}
                                className="p-2 hover:bg-black/10 rounded-full text-[#54656f] transition-colors"
                                title={isPaused ? 'Continuar gravação' : 'Pausar gravação'}
                            >
                                {isPaused
                                    ? <Play className="w-5 h-5 fill-current text-amber-500" />
                                    : <Pause className="w-5 h-5 fill-current" />
                                }
                            </button>
                            {/* Parar e Enviar */}
                            <button
                                onClick={stopRecording}
                                className="p-2 bg-red-500 hover:bg-red-600 text-white rounded-full transition-all shadow-md active:scale-90"
                                title="Parar e Enviar"
                            >
                                <StopCircle className="w-5 h-5 fill-current" />
                            </button>
                        </div>
                    </div>
                )}
            </div>
        </div>

            {/* ── Modal de preview de arquivo ─────────────────────── */}
            <FilePreviewModal
                file={previewFile}
                onConfirm={handlePreviewConfirm}
                onCancel={handlePreviewCancel}
            />

            {/* ── Modais de mensagem rica ────────────────────────────── */}
            <RichMessageComposer
                isOpen={showRichComposer}
                onClose={() => setShowRichComposer(false)}
                instanceId={instanceId ?? null}
                jid={selectedChat?.remote_jid ?? selectedChat?.jid ?? ''}
                onSent={() => setShowRichComposer(false)}
                onSchedule={handleScheduleFromComposer}
                initialPayload={richInitialPayload}
                initialType={richInitialType}
            />

            <TemplateLibrary
                isOpen={showTemplateLibrary}
                onClose={() => setShowTemplateLibrary(false)}
                onSelect={handleTemplateSelect}
            />

            <ScheduleMessageModal
                isOpen={showScheduleModal}
                onClose={() => setShowScheduleModal(false)}
                payload={schedulingPayload}
                messageType={schedulingType}
                onSaved={() => setShowScheduleModal(false)}
            />
        </>
    );
};

export default InputBar;
