// ECO-PANNEAU.FR - __react/socle/_socle_messagerie_public.jsx

const { useState, useEffect, useRef } = React;

// 1. - COMPOSANT PRINCIPAL : FORMULAIRE DE PREMIER CONTACT (OTP)
const BasePublicContactForm = ({ panneauId, showToast, onSuccess, isPreview, hideAttachments = false, settings = {}, themeColor = '#059669' }) => {
    
    // SÉCURITÉ ANTI-FUITE DE MÉMOIRE : Utilisation du Hook Global Zéro-Dette
    const { isMounted, safeFetch } = window.pano_useSafeFetch();

    // 1.1 - Gestion des modales et boîtes de dialogue via l'URL
    const { activeDialog: routerActiveDialog, openDialog: routerOpenDialog, closeCurrentLayer: routerCloseLayer } = window.pano_useUrlModal();

    // 1.2 - Récupération dynamique des composants et icônes
    const {
        ArrowUpIcon, LoaderIcon, MessageSquareIcon, FileTextIcon, 
        ImageIcon, PaperclipIcon, MailIcon, XIcon
    } = window.pano_getIcons();

    const { Button, ModerationModal, Modal } = window.pano_getComponents();

    // 1.3 - États locaux
    const [submitting, setSubmitting] = useState(false);
    const [uploadProgress, setUploadProgress] = useState('');
    
    // Honeypot : Décalage de 10s pour ne pas bloquer l'auto-remplissage rapide du navigateur client
    const [mountTime] = useState(Math.floor(Date.now() / 1000) - 10);
    
    const [email, setEmail] = useState('');
    const [hpText, setHpText] = useState('');
    const [message, setMessage] = useState('');
    
    const [selectedFiles, setSelectedFiles] = useState([]);
    const [isDragging, setIsDragging] = useState(false);
    const [dragCounter, setDragCounter] = useState(0);
    const textareaRef = useRef(null);

    // États de vérification OTP
    const [verificationState, setVerificationState] = useState('idle'); // idle, requesting, verifying, verifying_alert
    const [verifySession, setVerifySession] = useState('');
    const [verifyCode, setVerifyCode] = useState('');
    const [targetEmail, setTargetEmail] = useState('');
    
    // États d'alertes gérés par l'URL
    const [moderationWarning, setModerationWarning] = useState(null);

    // 2. - CYCLE DE VIE ET EFFETS
    useEffect(() => {
        if (routerActiveDialog !== 'verify_email') setVerificationState('idle');
        if (routerActiveDialog !== 'moderation_warning') setModerationWarning(null);
    }, [routerActiveDialog]);

    // Redimensionnement automatique de la zone de saisie
    useEffect(() => {
        if (textareaRef.current) {
            textareaRef.current.style.height = ''; 
            const scrollH = textareaRef.current.scrollHeight;
            const clientH = textareaRef.current.clientHeight;
            
            if (scrollH > clientH) {
                textareaRef.current.style.height = `${scrollH}px`;
            }
        }
    }, [message]);

    // 3. - GESTION DES FICHIERS JOINTS
    const addFiles = (fileList) => {
        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) {
            if (showToast) showToast("Format de fichier non supporté. Veuillez utiliser un PDF ou une image.", "error");
            return;
        }

        // Limitation stricte à 1 fichier dans la messagerie (Sécurité Zéro-Trust)
        if (files.length > 1 || selectedFiles.length >= 1) {
            if (showToast) showToast("Un seul fichier autorisé par message.", "error");
            return;
        }
        
        const file = files[0];
        if (file.size > 5 * 1024 * 1024) {
            if (showToast) showToast("Le fichier dépasse la limite de 5 Mo.", "error");
            return;
        }
        
        setSelectedFiles([file]);
    };

    const handleFileChange = (e) => { addFiles(e.target.files); e.target.value = null; };
    const handlePaste = (e) => { if (!hideAttachments && e.clipboardData && e.clipboardData.files && e.clipboardData.files.length > 0) addFiles(e.clipboardData.files); };
    const handleDragEnter = (e) => { if (hideAttachments) return; e.preventDefault(); e.stopPropagation(); setDragCounter(prev => prev + 1); setIsDragging(true); };
    const handleDragLeave = (e) => { if (hideAttachments) return; e.preventDefault(); e.stopPropagation(); setDragCounter(prev => { const nc = prev - 1; if (nc === 0) setIsDragging(false); return nc; }); };
    const handleDragOver = (e) => { if (hideAttachments) return; e.preventDefault(); e.stopPropagation(); };
    
    const handleDrop = (e) => {
        if (hideAttachments) 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);
    };

    // 4. - SÉCURITÉ ET SOUMISSION DU MESSAGE
    const executeSubmit = async (authorEmail, existingToken, session, code, isPendingControl = false) => {
        setSubmitting(true);
        setUploadProgress('');
        let finalDetail = message.trim();
        
        if (!hideAttachments) {
            for (let file of selectedFiles) {
                if (!isMounted.current) return; // SÉCURITÉ

                const fileType = file.type.includes('pdf') ? 'pdf' : 'image';
                try {
                    const fileId = await window.pano_uploadFile(
                        file, 
                        fileType, 
                        (msg, percent) => {
                            if (!isMounted.current) return; // SÉCURITÉ
                            if (percent < 100) setUploadProgress(`${percent}%`);
                            else setUploadProgress('Finalisation...');
                        }, 
                        true, 
                        false, 
                        null, 
                        panneauId
                    );
                    
                    if (!isMounted.current) return; // SÉCURITÉ

                    const actualId = fileId.id || fileId;
                    const actualNumPages = fileId.numPages || 1;
                    finalDetail += `\n[ATTACHMENT:${actualId}:${fileType}:${actualNumPages}]`;
                } catch(err) {
                    if (!isMounted.current) return; // SÉCURITÉ
                    if (showToast) showToast("Erreur lors de l'envoi de la pièce jointe : " + err.message, 'error');
                    setSubmitting(false);
                    setUploadProgress('');
                    return;
                }
            }
        }

        if (!isMounted.current) return; // SÉCURITÉ

        // CORRECTION : Déclaration explicite du destinataire pour forcer la notification du serveur
        const isPublic = panneauId === 'CONTACT_PUBLIC';

        const payload = { 
            panneauId, 
            detail: finalDetail, 
            author: authorEmail,
            authorType: isPublic ? 'Public' : 'Riverain',
            targetEmail: isPublic ? 'Admin' : 'Client',
            type: isPublic ? 'support' : 'message',
            isAlert: isPendingControl ? 2 : 0, 
            hp_text: hpText, 
            hp_time: mountTime,
            verification_token: existingToken,
            verify_session: session,
            verify_code: code
        };
        
        const d = await safeFetch('interactions', {
            body: payload, 
            setLoading: setSubmitting,
            successMessage: "Votre message a été envoyé avec succès.",
            errorMessage: "Erreur lors de l'envoi"
        });
        
        if (!isMounted.current) return; // SÉCURITÉ : Coupe-circuit

        if (d) {
            if (d.data && d.data.verification_token) {
                localStorage.setItem('pano_riverain_token_' + authorEmail, d.data.verification_token);
            }
            setMessage(''); setSelectedFiles([]); setVerificationState('idle'); setVerifyCode(''); setUploadProgress('');
            if (onSuccess) onSuccess();
        } else {
            if (existingToken) {
                localStorage.removeItem('pano_riverain_token_' + authorEmail);
            }
            setVerificationState('idle');
            setUploadProgress('');
        }
    };

    const startVerificationFlow = (isPendingControl = false) => {
        if (!email.trim()) {
            if (showToast) showToast("Veuillez saisir une adresse e-mail.", "error");
            return;
        }
        setTargetEmail(email.trim());
        
        const existingToken = localStorage.getItem('pano_riverain_token_' + email.trim());
        if (existingToken) {
            executeSubmit(email.trim(), existingToken, null, null, isPendingControl);
            return;
        }

        setVerificationState('requesting');
        safeFetch('interactions/verify_request', {
            body: { email: email.trim() },
            setLoading: setSubmitting,
            successMessage: "Un code a été envoyé à votre adresse e-mail.",
            errorMessage: "Veuillez patienter avant de demander un nouveau code."
        }).then(d => {
            if (!isMounted.current) return; // SÉCURITÉ : Coupe-circuit

            if (d && d.data && d.data.verify_session) {
                setVerifySession(d.data.verify_session);
                setVerificationState(isPendingControl ? 'verifying_alert' : 'verifying');
                routerOpenDialog('verify_email');
            } else {
                setVerificationState('idle');
            }
        });
    };

    const handleInitialSubmit = (e) => {
        if (e && e.preventDefault) e.preventDefault(); 
        if (isPreview) {
            if (showToast) showToast("Ceci est un aperçu interactif. La messagerie n'est pas fonctionnelle ici.", "info");
            return;
        }

        if (window.pano_checkForBlacklist) {
            const word = window.pano_checkForBlacklist(message, settings);
            if (word) { 
                setModerationWarning(word); 
                routerOpenDialog('moderation_warning');
                return; 
            }
        } else {
            if (window.pano_logFallback) window.pano_logFallback("Bouclier sémantique introuvable. Modération ignorée sur BasePublicContactForm.");
        }
        
        if (panneauId === 'CONTACT_PUBLIC') {
            if (!email.trim()) {
                if (showToast) showToast("Veuillez saisir une adresse e-mail.", "error");
                return;
            }
            const existingToken = localStorage.getItem('pano_riverain_token_' + email.trim());
            executeSubmit(email.trim(), existingToken, null, null, false);
        } else {
            startVerificationFlow(false);
        }
    };

    // 5. - RENDU UI
    return (
        <form onSubmit={handleInitialSubmit} onDragEnter={handleDragEnter} onDragLeave={handleDragLeave} onDragOver={handleDragOver} onDrop={handleDrop} className="space-y-3 flex flex-col min-h-full p-2 relative overflow-x-hidden">
            {isDragging && !hideAttachments && (
                <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 break-words">Relâchez votre fichier ici</span>
                        <span className="text-sm font-bold text-slate-500 mt-2 break-words">Image ou PDF (1 max)</span>
                    </div>
                </div>
            )}

            {routerActiveDialog === 'moderation_warning' && moderationWarning && ModerationModal && (
                <ModerationModal word={moderationWarning} onModify={routerCloseLayer} onRequestControl={() => { 
                    routerCloseLayer(); 
                    setTimeout(() => {
                        if (panneauId === 'CONTACT_PUBLIC') {
                            const existingToken = localStorage.getItem('pano_riverain_token_' + email.trim());
                            executeSubmit(email.trim(), existingToken, null, null, true);
                        } else {
                            startVerificationFlow(true);
                        }
                    }, 100); 
                }} />
            )}

            {routerActiveDialog === 'verify_email' && verificationState.startsWith('verifying') && Modal && (
                <Modal 
                    title="Vérification de l'e-mail" 
                    onClose={routerCloseLayer} 
                    preventClose={submitting} 
                    maxWidth="max-w-md"
                    actions={(close) => (
                        <>
                            <Button variant="secondary" type="button" onClick={close} disabled={submitting} className="flex-1 py-3 justify-center text-xs">Annuler</Button>
                            <Button variant="primary" type="submit" form="otp-verify-form" disabled={verifyCode.length !== 6 || submitting} className="flex-[2] py-3 justify-center shadow-md text-xs uppercase tracking-widest text-center">
                                {submitting ? <LoaderIcon className="animate-spin w-5 h-5"/> : 'Valider'}
                            </Button>
                        </>
                    )}
                >
                    <form id="otp-verify-form" onSubmit={(e) => {
                        e.preventDefault();
                        routerCloseLayer();
                        setTimeout(() => executeSubmit(targetEmail, null, verifySession, verifyCode, verificationState === 'verifying_alert'), 100);
                    }} className="flex flex-col items-center text-center">
                        <MailIcon size={32} className="text-emerald-600 mb-3" />
                        <p className="text-sm text-slate-600 mb-6 leading-relaxed break-words">Un code à 6 chiffres a été envoyé à <strong className="break-all">{targetEmail}</strong>. Veuillez le saisir pour confirmer que cette adresse vous appartient.</p>
                        <input type="text" value={verifyCode} onChange={e => setVerifyCode(e.target.value.replace(/\D/g, '').slice(0, 6))} className="w-full border-2 border-slate-200 rounded-xl p-3 text-center text-3xl tracking-[0.25em] font-black outline-none focus:border-emerald-500 mb-2" placeholder="000000" autoFocus />
                    </form>
                </Modal>
            )}

            <input type="text" value={hpText} onChange={e => setHpText(e.target.value)} style={{ position: 'absolute', left: '-9999px' }} tabIndex="-1" autoComplete="new-password" />
            <input type="hidden" name="hp_time" value={mountTime} />

            <input name="email" type="email" value={email} onChange={e => setEmail(e.target.value)} required placeholder="Votre e-mail (pour recevoir la réponse)" disabled={verificationState === 'requesting' || submitting} className="w-full border-2 rounded-xl p-3 text-sm outline-none transition shrink-0 border-slate-200 focus:border-slate-800 disabled:opacity-50 min-w-0" />
            
            {hideAttachments && selectedFiles.length > 0 && (
                <div className="bg-white border border-slate-200 rounded-xl p-2 flex flex-col gap-2 max-h-32 overflow-y-auto custom-scrollbar shrink-0 mt-2">
                    {selectedFiles.map((f, i) => (
                        <div key={i} className="bg-slate-50 p-2 rounded-xl border border-slate-200 flex items-center justify-between shadow-sm shrink-0 min-w-0">
                            <span className="text-xs font-bold text-slate-600 flex items-center gap-2 min-w-0 flex-1 pr-2">
                                {f.type.includes('pdf') ? <FileTextIcon size={16} className="shrink-0"/> : <ImageIcon size={16} className="shrink-0"/>}
                                <span className="break-all leading-tight">{f.name}</span>
                            </span>
                            <Button variant="danger" shape="round" onClick={() => { if(!submitting) removeFile(i); }} disabled={submitting} icon={XIcon} className="p-1.5 shadow-none border-none hover:bg-red-100 shrink-0" title="Supprimer la pièce jointe" />
                        </div>
                    ))}
                </div>
            )}

            <textarea 
                ref={textareaRef} 
                name="detail" 
                value={message} 
                onChange={(e) => setMessage(e.target.value)} 
                onPaste={handlePaste} 
                onKeyDown={(e) => {
                    if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {
                        e.preventDefault();
                        if (!(submitting || verificationState === 'requesting' || (hideAttachments ? !message.trim() : (selectedFiles.length === 0 && !message.trim())))) {
                            handleInitialSubmit(e);
                        }
                    }
                }}
                required={hideAttachments || selectedFiles.length === 0} 
                disabled={verificationState === 'requesting' || submitting}
                placeholder="Votre message... (Ctrl+Entrée pour envoyer, coller ou glisser des images est accepté)" 
                className="w-full border-2 rounded-xl p-3 text-sm outline-none transition resize-none flex-1 border-slate-200 focus:border-slate-800 overflow-y-auto custom-scrollbar min-h-[120px] disabled:opacity-50 break-words">
            </textarea>
            
            {!hideAttachments && selectedFiles.length > 0 && (
                <div className="bg-white border border-slate-200 rounded-xl p-2 flex flex-col gap-2 max-h-32 overflow-y-auto custom-scrollbar shrink-0 mt-2">
                    {selectedFiles.map((f, i) => (
                        <div key={i} className="bg-slate-50 p-2 rounded-xl border border-slate-200 flex items-center justify-between shadow-sm shrink-0 min-w-0">
                            <span className="text-xs font-bold text-slate-600 flex items-center gap-2 min-w-0 flex-1 pr-2">
                                {f.type.includes('pdf') ? <FileTextIcon size={16} className="shrink-0"/> : <ImageIcon size={16} className="shrink-0"/>}
                                <span className="break-all leading-tight">{f.name}</span>
                            </span>
                            <Button variant="danger" shape="round" onClick={() => { if(!submitting) removeFile(i); }} disabled={submitting} icon={XIcon} className="p-1.5 shadow-none border-none hover:bg-red-100 shrink-0" title="Supprimer la pièce jointe" />
                        </div>
                    ))}
                </div>
            )}
            
            <div className="flex gap-2 items-center shrink-0 mt-1">
                {!hideAttachments && (
                    <label className={`cursor-pointer w-[46px] h-[46px] rounded-xl transition shadow-sm flex items-center justify-center shrink-0 border ${submitting || verificationState === 'requesting' || selectedFiles.length >= 1 ? 'bg-slate-50 border-slate-100 text-slate-400 opacity-50' : 'bg-white border-slate-200 hover:bg-slate-50'}`} style={(!submitting && verificationState !== 'requesting' && selectedFiles.length < 1) ? { color: themeColor } : {}} title="Joindre une photo ou un PDF (1 max)">
                        <PaperclipIcon size={20} />
                        <input type="file" className="hidden" accept="image/jpeg, image/png, image/webp, application/pdf" disabled={submitting || verificationState === 'requesting' || selectedFiles.length >= 1} onChange={handleFileChange} />
                    </label>
                )}
                <Button 
                    type="submit" 
                    disabled={submitting || verificationState === 'requesting' || (hideAttachments ? !message.trim() : (selectedFiles.length === 0 && !message.trim()))} 
                    className="flex-1 h-[46px] text-white font-black uppercase tracking-widest text-xs transition shadow-md border-none justify-center" 
                    style={{ backgroundColor: themeColor }}
                >
                    {submitting || verificationState === 'requesting' ? (
                        uploadProgress ? <span className="text-[10px] font-black">{uploadProgress}</span> : <LoaderIcon className="animate-spin w-4 h-4"/>
                    ) : <><MessageSquareIcon size={14}/> Envoyer</>}
                </Button>
            </div>
        </form>
    );
};

window.pano_PublicContactForm = (props) => {
    return (
        <div className="flex flex-col h-full relative overflow-x-hidden">
            <BasePublicContactForm {...props} />
        </div>
    );
};

/* EOF ========== [__react/socle/_socle_messagerie_public.jsx] */