/**
 * =========================================================================
 * PLATEFORME ECO-PANNEAU.FR - VERSION 1.0.0
 * Socle Messagerie (2/3) - Moteur d'échange (ChatBox et Upload)
 * =========================================================================
 */

const { useState, useEffect, useRef, useCallback } = React;

// -------------------------------------------------------------------------
// COMPOSANT : CONTENEUR DE TCHAT (MOTEUR D'ÉCRITURE ET UPLOAD)
// -------------------------------------------------------------------------

window.pano_ChatBox = ({ messages, currentUserRole, panneauId, refreshData, onSend, clientName, settings = {}, themeColor = '#059669', readOnly = false }) => {
    const routerActiveDialog = new URLSearchParams(window.location.search).get('dialog');
    const routerCloseLayer = () => window.history.back();
    const routerOpenDialog = (type) => {
        const u = new URL(window.location);
        u.searchParams.set('dialog', type);
        window.history.pushState({ dialog: type }, '', u);
        window.dispatchEvent(new Event('popstate'));
    };

    const [forceRender, setForceRender] = useState(0);
    useEffect(() => {
        const onPop = () => setForceRender(prev => prev + 1);
        window.addEventListener('popstate', onPop);
        return () => window.removeEventListener('popstate', onPop);
    }, []);

    const { ArrowUpIcon, ArrowDownIcon, ArrowLeftIcon, LoaderIcon, ImageIcon, FileTextIcon, PaperclipIcon, DownloadIcon, XIcon } = window.pano_getIcons();
    const Button = window.pano_Button;
    const ModerationModal = window.pano_ModerationModal;
    const PdfFullViewer = window.pano_PdfFullViewer;
    const MessageBubble = window.pano_MessageBubble; // Récupéré de _socle_messagerie_ui.jsx

    const containerRef = useRef(null);
    const textareaRef = useRef(null);
    const [draft, setDraft] = useState('');
    const [sending, setSending] = useState(false);
    const [selectedFiles, setSelectedFiles] = useState([]);
    const [fileError, setFileError] = useState('');
    const [isAtBottom, setIsAtBottom] = useState(true);
    const [isDragging, setIsDragging] = useState(false);
    const [dragCounter, setDragCounter] = useState(0);
    
    const [moderationWarning, setModerationWarning] = useState(null);
    const [viewingAttachment, setViewingAttachment] = useState(null);

    const isAtBottomRef = useRef(true);

    useEffect(() => {
        isAtBottomRef.current = isAtBottom;
    }, [isAtBottom]);

    useEffect(() => {
        if (routerActiveDialog !== 'view_attachment') setViewingAttachment(null);
        if (routerActiveDialog !== 'moderation_warning') setModerationWarning(null);
    }, [routerActiveDialog]);

    useEffect(() => {
        if (textareaRef.current) {
            textareaRef.current.style.height = 'auto';
            textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;
        }
    }, [draft]);

    useEffect(() => { 
        const authorRole = currentUserRole === 'admin' ? 'Admin' : 'Client';
        const unread = messages.filter(m => !m.resolved && m.author !== authorRole);
        
        if (unread.length > 0 && currentUserRole !== 'public' && currentUserRole !== 'riverain' && !readOnly) { 
            window.pano_apiFetch('interactions/read', { 
                body: { panneauId, author: authorRole } 
            }).then((d) => { 
                if(d && refreshData) {
                    refreshData(true); 
                }
            }); 
            
            if (window.Notification && Notification.permission === 'granted' && localStorage.getItem('eco_push_enabled') === 'true') {
                const latestMsgId = unread[0].id || unread[0].created_at; 
                const lastNotified = sessionStorage.getItem('last_notified_msg_' + panneauId);
                
                if (lastNotified !== latestMsgId) {
                    new Notification("eco-panneau.fr", { body: "Nouveau message reçu.", icon: "/favicon.svg" });
                    sessionStorage.setItem('last_notified_msg_' + panneauId, latestMsgId);
                }
            }
        }
    }, [messages, panneauId, currentUserRole, refreshData, readOnly]);

    const handleScroll = useCallback(() => {
        if (!containerRef.current) return;
        const { scrollTop, scrollHeight, clientHeight } = containerRef.current;
        const isBottom = scrollHeight - scrollTop - clientHeight < 50;
        setIsAtBottom(isBottom);
    }, []);

    const scrollToBottom = useCallback((smooth = true) => {
        if (containerRef.current) {
            containerRef.current.scrollTo({ 
                top: containerRef.current.scrollHeight, 
                behavior: smooth ? 'smooth' : 'auto' 
            });
        }
    }, []);

    const handleImageLoad = useCallback(() => {
        if (isAtBottomRef.current) {
            scrollToBottom(true);
        }
    }, [scrollToBottom]);

    useEffect(() => {
        const timer = setTimeout(() => scrollToBottom(false), 100);
        return () => clearTimeout(timer);
    }, [scrollToBottom]);

    useEffect(() => {
        if (isAtBottom) {
            scrollToBottom(true);
        }
    }, [messages.length, isAtBottom, scrollToBottom]);

    const addFiles = (fileList) => {
        setFileError('');
        const validTypes = ['image/jpeg', 'image/png', 'image/webp', 'application/pdf'];
        const files = Array.from(fileList).filter(f => validTypes.includes(f.type));
        
        if (files.length === 0) return;

        if (selectedFiles.length + files.length > 20) {
            setFileError("Maximum 20 fichiers autorisés par message.");
            return;
        }
        
        const validFiles = [];
        for (let f of files) {
            if (f.size > 5 * 1024 * 1024) {
                setFileError("Un ou plusieurs fichiers dépassent 5 Mo.");
                return;
            }
            validFiles.push(f);
        }
        setSelectedFiles(prev => [...prev, ...validFiles]);
    };

    const handleFileChange = (e) => {
        addFiles(e.target.files);
        e.target.value = null;
    };

    const handlePaste = (e) => {
        if (readOnly) return;
        if (e.clipboardData && e.clipboardData.files && e.clipboardData.files.length > 0) {
            addFiles(e.clipboardData.files);
        }
    };

    const handleDragEnter = (e) => {
        if (readOnly) return;
        e.preventDefault(); e.stopPropagation();
        setDragCounter(prev => prev + 1);
        setIsDragging(true);
    };

    const handleDragLeave = (e) => {
        if (readOnly) return;
        e.preventDefault(); e.stopPropagation();
        setDragCounter(prev => {
            const nc = prev - 1;
            if (nc === 0) setIsDragging(false);
            return nc;
        });
    };

    const handleDragOver = (e) => { if (readOnly) return; e.preventDefault(); e.stopPropagation(); };

    const handleDrop = (e) => {
        if (readOnly) return;
        e.preventDefault(); e.stopPropagation();
        setDragCounter(0);
        setIsDragging(false);
        if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length > 0) {
            addFiles(e.dataTransfer.files);
        }
    };

    const removeFile = (index) => {
        const newFiles = [...selectedFiles];
        newFiles.splice(index, 1);
        setSelectedFiles(newFiles);
    };

    const executeSend = async (isPendingControl = false) => {
        setSending(true);
        let finalDraft = draft.trim();
        
        for (let file of selectedFiles) {
            const fileType = file.type.includes('pdf') ? 'pdf' : 'image';
            try {
                const isPublic = currentUserRole === 'public' || currentUserRole === 'riverain';
                const fileId = await window.pano_uploadFile(file, fileType, null, isPublic, false, null, panneauId);
                finalDraft += `\n[ATTACHMENT:${fileId}:${fileType}]`;
            } catch(err) {
                setFileError("Erreur lors de l'upload : " + err.message);
                setSending(false);
                return;
            }
        }

        if (onSend) await onSend(finalDraft, isPendingControl);
        
        setDraft(''); 
        setSelectedFiles([]);
        setSending(false);
        setTimeout(() => scrollToBottom(true), 50);
    };

    const handleInitialSend = (e) => {
        if (e && e.preventDefault) e.preventDefault(); 
        if (!draft.trim() && selectedFiles.length === 0) return;
        
        if (currentUserRole === 'public' || currentUserRole === 'riverain') {
            const word = window.pano_checkForBlacklist ? window.pano_checkForBlacklist(draft, settings) : null;
            if (word) { 
                setModerationWarning(word); 
                routerOpenDialog('moderation_warning');
                return; 
            }
        }
        executeSend(false);
    };

    const triggerViewAttachment = (att) => {
        setViewingAttachment(att);
        routerOpenDialog('view_attachment');
    };

    return (
        <div 
            className="flex flex-col h-full bg-slate-50 relative overflow-hidden rounded-b-3xl xl:rounded-b-none xl:rounded-br-3xl"
            onDragEnter={handleDragEnter}
            onDragLeave={handleDragLeave}
            onDragOver={handleDragOver}
            onDrop={handleDrop}
        >
            {isDragging && !readOnly && (
                <div className="absolute inset-0 z-[100] bg-emerald-500/20 backdrop-blur-sm border-4 border-emerald-500 border-dashed rounded-2xl flex flex-col items-center justify-center pointer-events-none">
                    <div className="bg-white p-6 rounded-2xl shadow-xl flex flex-col items-center text-center">
                        <ArrowUpIcon size={48} className="text-emerald-500 mb-4 animate-bounce" />
                        <span className="text-xl font-black text-slate-800">Déposez vos fichiers ici</span>
                        <span className="text-sm font-bold text-slate-500 mt-2">Images et PDF acceptés (max 20)</span>
                    </div>
                </div>
            )}

            {routerActiveDialog === 'moderation_warning' && moderationWarning && ModerationModal && (
                <ModerationModal word={moderationWarning} onModify={routerCloseLayer} onRequestControl={() => { routerCloseLayer(); setTimeout(() => executeSend(true), 100); }} />
            )}

            {routerActiveDialog === 'view_attachment' && viewingAttachment && (
                <div className="fixed inset-0 z-[999999] bg-slate-900/95 backdrop-blur-sm flex flex-col animate-in fade-in duration-200" onMouseDown={routerCloseLayer}>
                    <div className="flex justify-between items-center p-4 bg-slate-900/50 text-white shrink-0 border-b border-white/10" onMouseDown={e => e.stopPropagation()}>
                        <Button variant="ghost" onClick={routerCloseLayer} className="text-white hover:bg-white/10 border-none">
                            <ArrowLeftIcon size={18}/> <span className="ml-2">Retour</span>
                        </Button>
                        <a href={`${window.pano_CONFIG.apiBaseUrl}file/download&type=${viewingAttachment.type}&id=${viewingAttachment.id}`} download className="flex items-center gap-2 px-4 py-2 bg-emerald-600 hover:bg-emerald-700 text-white rounded-xl transition text-sm font-bold shadow-lg cursor-pointer">
                            <DownloadIcon size={18}/> <span className="hidden sm:inline">Télécharger</span>
                        </a>
                    </div>
                    <div className="flex-1 flex flex-col items-center justify-center p-2 sm:p-4 min-h-0 relative w-full" onMouseDown={e => e.stopPropagation()}>
                        {viewingAttachment.type === 'image' && (
                            <img src={`${window.pano_CONFIG.apiBaseUrl}file/download&type=image&id=${viewingAttachment.id}`} className="max-w-full max-h-full object-contain rounded-xl shadow-2xl shrink-0" alt="Aperçu" />
                        )}
                        {viewingAttachment.type === 'pdf' && PdfFullViewer && (
                            <PdfFullViewer id={viewingAttachment.id} />
                        )}
                    </div>
                </div>
            )}

            <div ref={containerRef} onScroll={handleScroll} className="flex-1 min-h-0 overflow-y-auto p-4 flex flex-col custom-scrollbar relative">
                {messages.map((msg) => {
                    const isMe = (currentUserRole === 'admin' && msg.authorType === 'Admin') || 
                                 (currentUserRole === 'client' && msg.authorType === 'Client') || 
                                 (currentUserRole === 'public' && msg.authorType !== 'Admin' && msg.authorType !== 'Client' && msg.authorType !== 'Système' && msg.authorType !== 'Systeme');

                    let displayAuthor = msg.author;
                    if (panneauId === 'CONTACT_PUBLIC') {
                        if (msg.authorType === 'Admin' || msg.author === 'Admin') displayAuthor = 'Service client';
                        else if (msg.authorType === 'Système' || msg.authorType === 'Systeme' || msg.author === 'Système' || msg.author === 'Systeme') displayAuthor = 'Système';
                        else displayAuthor = isMe ? 'Vous' : `Visiteur ${msg.author}`;
                    } else {
                        if (msg.authorType === 'Admin' || msg.author === 'Admin') displayAuthor = 'Support';
                        else if (msg.authorType === 'Client' || msg.author === 'Client') displayAuthor = isMe ? 'Vous' : msg.author; 
                        else if (msg.authorType === 'Système' || msg.authorType === 'Systeme' || msg.author === 'Système' || msg.author === 'Systeme') displayAuthor = 'Système';
                        else displayAuthor = isMe ? 'Vous' : 'Riverain';
                    }

                    return <MessageBubble key={msg.id} msg={msg} isMe={isMe} displayAuthor={displayAuthor} onImageLoad={handleImageLoad} onViewAttachment={triggerViewAttachment} />;
                })}

                {messages.length === 0 && <div className="text-center text-slate-400 text-sm font-medium italic my-auto">Aucun message.</div>}
            </div>

            {!isAtBottom && messages.length > 0 && (
                <div className="absolute bottom-24 left-0 right-0 flex justify-center pointer-events-none z-10">
                    <div role="button" tabIndex={0} onClick={() => scrollToBottom(true)} className="bg-slate-800/90 backdrop-blur text-white px-4 py-2 rounded-full shadow-lg text-xs font-bold pointer-events-auto hover:bg-slate-900 transition flex items-center gap-2 animate-in fade-in slide-in-from-bottom-2 cursor-pointer">
                        <ArrowDownIcon size={14}/> Nouveaux messages
                    </div>
                </div>
            )}
            
            {readOnly ? (
                <div className="flex flex-col w-full bg-slate-50 border-t border-slate-200 shrink-0 z-20 transition-colors rounded-b-3xl xl:rounded-b-none xl:rounded-br-3xl p-5 text-center text-slate-500">
                    <p className="font-bold text-sm">Mode lecture seule</p>
                    <p className="text-xs mt-1">Vous n'avez pas les droits requis pour envoyer des messages dans cette conversation.</p>
                </div>
            ) : (
                <div className="flex flex-col w-full bg-white border-t border-slate-200 shrink-0 z-20 transition-colors rounded-b-3xl xl:rounded-b-none xl:rounded-br-3xl">
                    {fileError && <p className="text-xs font-bold text-red-500 px-4 pt-2">{fileError}</p>}
                    
                    {selectedFiles.length > 0 && (
                        <div className="px-4 py-2 mt-2 mx-2 bg-slate-50 border border-slate-200 rounded-xl flex flex-col gap-2 max-h-32 overflow-y-auto custom-scrollbar">
                            {selectedFiles.map((f, i) => (
                                <div key={i} className="flex items-center justify-between shrink-0">
                                    <span className="text-xs font-bold text-slate-600 flex items-center gap-2">
                                        {f.type.includes('pdf') ? <FileTextIcon size={14}/> : <ImageIcon size={14}/>}
                                        <span className="truncate max-w-[200px]">{f.name}</span>
                                    </span>
                                    <Button variant="danger" shape="round" onClick={() => removeFile(i)} disabled={sending} className="p-1.5 shadow-none" icon={XIcon} title="Supprimer la pièce jointe" />
                                </div>
                            ))}
                        </div>
                    )}
                    
                    <form onSubmit={handleInitialSend} className="p-3 flex gap-2 shrink-0 items-end">
                        <label className="cursor-pointer p-3 text-slate-500 hover:text-slate-800 rounded-xl transition bg-slate-50 border border-slate-100 shadow-sm flex items-center justify-center" style={(!sending && selectedFiles.length < 20) ? { color: themeColor } : {}} title="Joindre des photos ou des PDF (max 20)">
                            <PaperclipIcon size={20} />
                            <input type="file" multiple className="hidden" accept="image/jpeg, image/png, image/webp, application/pdf" disabled={sending || selectedFiles.length >= 20} onChange={handleFileChange} />
                        </label>
                        <textarea 
                            ref={textareaRef}
                            value={draft} 
                            onChange={e => setDraft(e.target.value)} 
                            onPaste={handlePaste}
                            onKeyDown={(e) => {
                                if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {
                                    e.preventDefault();
                                    if (!sending && (draft.trim() || selectedFiles.length > 0)) {
                                        handleInitialSend(e);
                                    }
                                }
                            }}
                            placeholder="Écrire une réponse... (Ctrl+Entrée pour envoyer)" 
                            disabled={sending} 
                            rows="1" 
                            className="flex-1 border-2 border-slate-100 rounded-xl px-4 py-3 outline-none focus:border-slate-300 text-sm transition resize-none custom-scrollbar max-h-32 overflow-hidden" 
                        />
                        <Button 
                            onClick={handleInitialSend} 
                            disabled={sending || (!draft.trim() && selectedFiles.length === 0)}
                            className="text-white p-3 shadow-sm shrink-0 border-none"
                            style={{ backgroundColor: themeColor }}
                            shape="square"
                            title="Envoyer le message"
                        >
                            {sending ? <LoaderIcon className="animate-spin w-5 h-5"/> : <ArrowUpIcon size={20} />}
                        </Button>
                    </form>
                </div>
            )}
        </div>
    );
};

/* EOF ========== [_react/_socle_messagerie_chatbox.jsx] */