// ECO-PANNEAU.FR - _react/ui/_ui_modals.jsx

// 1. - GESTIONNAIRE GLOBAL DE Z-INDEX
window.pano_getNextModalZIndex = () => {
    if (typeof window.pano_modalZIndexCounter === 'undefined') {
        window.pano_modalZIndexCounter = 99000;
    }
    window.pano_modalZIndexCounter += 10;
    return window.pano_modalZIndexCounter;
};

// 2. - WRAPPER STRIPE ELEMENTS (PAIEMENT)
const StripeCheckoutForm = ({ onSuccess }) => {
    const { PaymentElement, useStripe, useElements } = window.ReactStripe;
    const stripe = useStripe();
    const elements = useElements();
    const [error, ReactSetError] = React.useState(null);
    const [processing, setProcessing] = React.useState(false);
    const [isValidating, setIsValidating] = React.useState(false);

    // SÉCURITÉ ANTI-FUITE DE MÉMOIRE (Zéro-Dette)
    const isMounted = React.useRef(true);
    React.useEffect(() => {
        return () => {
            isMounted.current = false;
        };
    }, []);

    const { Button } = window.pano_getComponents();

    const handleSubmit = async (event) => {
        event.preventDefault();
        if (!stripe || !elements) return;

        setProcessing(true);
        const result = await stripe.confirmPayment({
            elements,
            confirmParams: {
                return_url: window.location.origin + window.location.pathname + '?tab=panneaux&payment_success=true'
            },
            redirect: 'if_required'
        });

        if (!isMounted.current) return; // SÉCURITÉ : Coupe-circuit (Le client a fermé la modale pendant le traitement Stripe)

        if (result.error) {
            ReactSetError(result.error.message);
            setProcessing(false);
            setIsValidating(false);
        } else if (result.paymentIntent && result.paymentIntent.status === 'succeeded') {
            setIsValidating(true);
            onSuccess(result.paymentIntent.id);
        }
    };

    return (
        <form onSubmit={handleSubmit} className="space-y-4">
            <PaymentElement />
            {error && <div className="text-red-500 text-sm font-bold bg-red-50 p-3 rounded-xl border border-red-200 break-words">{error}</div>}
            <Button type="submit" variant="infoSolid" disabled={!stripe || processing || isValidating} className="w-full mt-4 py-3 uppercase tracking-widest justify-center shadow-lg">
                {isValidating ? 'Validation de la commande...' : (processing ? 'Paiement en cours...' : 'Payer de manière sécurisée')}
            </Button>
        </form>
    );
};

window.pano_StripeElements = ({ clientSecret, onSuccess }) => {
    const stripePromise = React.useMemo(() => window.Stripe ? window.Stripe(window.pano_CONFIG.stripePubKey) : null, []);
    
    if (!window.ReactStripe || !stripePromise) {
        if (window.pano_logFallback) window.pano_logFallback("Échec du chargement du module de paiement Stripe (Erreur réseau ou bloqueur).");
        return <div className="text-red-500 font-bold p-4 text-center bg-red-50 border border-red-200 rounded-xl">Erreur : Le module de paiement sécurisé est indisponible.</div>;
    }
    
    const { Elements } = window.ReactStripe;

    return (
        <Elements stripe={stripePromise} options={{ clientSecret }}>
            <StripeCheckoutForm onSuccess={onSuccess} />
        </Elements>
    );
};

// 3. - MODALES GÉNÉRIQUES (SMART MODAL)

window.pano_ModalOverlay = ({ children, onClose, preventClose = false, className = "flex items-center justify-center p-4", positionClass = "fixed" }) => {
    const [zIdx] = React.useState(() => window.pano_getNextModalZIndex());
    
    const overlayContent = (
        <div 
            className={`${positionClass} inset-0 bg-slate-900/80 backdrop-blur-sm animate-in fade-in duration-200 ${className}`} 
            style={{ zIndex: zIdx }}
            onMouseDown={(e) => { 
                if (e.target === e.currentTarget && !preventClose && onClose) {
                    onClose(e); 
                }
            }}
        >
            {children}
        </div>
    );
    
    return (positionClass === 'absolute' || !window.ReactDOM) ? overlayContent : window.ReactDOM.createPortal(overlayContent, document.body);
};

window.pano_Modal = ({ 
    title, 
    subTitle,
    type = 'default', 
    onClose, 
    children, 
    preventClose = false, 
    requireConfirm = false, 
    maxWidth = "max-w-lg", 
    positionClass = "fixed",
    tabs = [],
    activeTab,
    onTabChange,
    actions,
    onSave,
    formId,
    isDirty = false,
    isSaving = false,
    saveText = "Enregistrer",
    savedText = "À jour",
    cancelText = "Annuler"
}) => {
    const [zIdx] = React.useState(() => window.pano_getNextModalZIndex());

    const { XIcon, SaveIcon, LoaderIcon, CheckCircleIcon } = window.pano_getIcons();
    const { Button } = window.pano_getComponents();
    
    const { alertParam, setAlert, closeCurrentLayer } = window.pano_useUrlModal ? window.pano_useUrlModal() : {};

    const scrollRef = React.useRef(null);

    const effectiveRequireConfirm = requireConfirm || isDirty;
    const effectivePreventClose = preventClose || isSaving;

    React.useEffect(() => {
        if (scrollRef.current) {
            scrollRef.current.scrollTop = 0;
        }
    }, [activeTab]);

    const handleCloseAttempt = React.useCallback((e) => {
        if (effectiveRequireConfirm) {
            if (setAlert) setAlert('unsaved', false);
        } else {
            if (onClose) onClose(e);
        }
    }, [effectiveRequireConfirm, onClose, setAlert]);

    const preventRef = React.useRef(effectivePreventClose);
    const closeRef = React.useRef(handleCloseAttempt);

    React.useEffect(() => { 
        preventRef.current = effectivePreventClose; 
        closeRef.current = handleCloseAttempt; 
    }, [effectivePreventClose, handleCloseAttempt]);

    React.useEffect(() => {
        const handleEsc = (e) => { if (e.key === 'Escape' && !preventRef.current) closeRef.current(e); };
        window.addEventListener('keydown', handleEsc);
        return () => window.removeEventListener('keydown', handleEsc);
    }, []);

    const showConfirm = effectiveRequireConfirm && alertParam === 'unsaved';

    let headerBgClass = 'bg-slate-50 border-b border-slate-200';
    let headerTextClass = 'text-slate-800';
    let closeIconClass = 'text-slate-400 hover:text-slate-600 hover:bg-slate-200';

    if (type === 'success') {
        headerBgClass = 'bg-emerald-50 border-b border-emerald-100'; headerTextClass = 'text-emerald-900'; closeIconClass = 'text-emerald-500 hover:text-emerald-700 hover:bg-emerald-100';
    } else if (type === 'info') {
        headerBgClass = 'bg-blue-50 border-b border-blue-100'; headerTextClass = 'text-blue-900'; closeIconClass = 'text-blue-500 hover:text-blue-700 hover:bg-blue-100';
    } else if (type === 'error') {
        headerBgClass = 'bg-red-50 border-b border-red-100'; headerTextClass = 'text-red-900'; closeIconClass = 'text-red-500 hover:text-red-700 hover:bg-red-100';
    } else if (type === 'warning') {
        headerBgClass = 'bg-orange-50 border-b border-orange-100'; headerTextClass = 'text-orange-900'; closeIconClass = 'text-orange-500 hover:text-orange-700 hover:bg-orange-100';
    } else if (type === 'confirm' || type === 'black') {
        headerBgClass = 'bg-slate-900 border-b border-slate-900'; headerTextClass = 'text-white'; closeIconClass = 'text-slate-400 hover:text-white hover:bg-slate-800';
    }

    if (showConfirm) {
        const confirmContent = (
            <div className={`${positionClass} inset-0 z-[1100] flex items-center justify-center p-4 bg-slate-900/80 backdrop-blur-sm animate-in fade-in duration-200`}>
                <div className="bg-white rounded-3xl w-full max-w-sm shadow-2xl p-6 flex flex-col animate-in zoom-in-95 duration-200">
                    <h3 className="font-black text-lg text-slate-800 mb-2">Modifications non enregistrées</h3>
                    <p className="text-sm text-slate-600 mb-6 font-medium">Vous avez des modifications en cours. Êtes-vous sûr de vouloir fermer sans sauvegarder ?</p>
                    <div className="flex gap-2 w-full">
                        <Button variant="secondary" onClick={(e) => {
                            if (closeCurrentLayer) closeCurrentLayer();
                        }} className="flex-1 py-3 justify-center text-xs">Annuler</Button>
                        <Button variant="dangerSolid" onClick={(e) => {
                            if (closeCurrentLayer) closeCurrentLayer();
                            setTimeout(() => { if (onClose) onClose(e); }, 50); 
                        }} className="flex-[1.5] py-3 justify-center text-xs shadow-md">Fermer sans sauvegarder</Button>
                    </div>
                </div>
            </div>
        );
        return (positionClass === 'absolute' || !window.ReactDOM) ? confirmContent : window.ReactDOM.createPortal(confirmContent, document.body);
    }

    const modalContent = (
        <div 
            className={`${positionClass} inset-0 bg-slate-900/80 backdrop-blur-sm animate-in fade-in duration-200 flex items-center justify-center p-4`} 
            style={{ zIndex: zIdx }}
            onMouseDown={(e) => { 
                if (e.target === e.currentTarget && !preventRef.current) closeRef.current(e); 
            }}
        >
            <div className={`bg-white rounded-3xl shadow-2xl w-full ${maxWidth} flex flex-col max-h-[95dvh] animate-in zoom-in-95 duration-200`} onMouseDown={e => e.stopPropagation()}>
                <div className={`p-5 flex justify-between items-center shrink-0 rounded-t-3xl ${headerBgClass} transition-colors`}>
                    <div>
                        <h3 className={`font-black text-lg pr-4 break-words leading-tight ${headerTextClass}`}>{title}</h3>
                        {subTitle && <p className={`text-xs font-medium mt-1 break-words ${type === 'confirm' || type === 'black' ? 'text-slate-400' : 'text-slate-500'}`}>{subTitle}</p>}
                    </div>
                    {!effectivePreventClose && (
                        <Button 
                            variant="ghost" 
                            shape="square"
                            icon={XIcon} 
                            onClick={handleCloseAttempt} 
                            disabled={effectivePreventClose}
                            className={`border-none shadow-none shrink-0 p-2 ${closeIconClass}`} 
                            title="Fermer" 
                        />
                    )}
                </div>
                
                {tabs && tabs.length > 0 && (
                    <div className={`flex flex-wrap gap-x-2 gap-y-2 border-b border-slate-200 shrink-0 px-4 sm:px-6 pt-2 ${headerBgClass} transition-colors`}>
                        {tabs.map(t => (
                            <div 
                                role="button" 
                                tabIndex={0} 
                                key={t.id} 
                                onClick={() => onTabChange && onTabChange(t.id)} 
                                className={`px-4 py-3 text-sm font-bold whitespace-nowrap border-b-2 transition cursor-pointer select-none ${activeTab === t.id ? 'border-emerald-600 text-emerald-700' : 'border-transparent text-slate-500 hover:text-slate-800'}`}
                            >
                                {t.label}
                            </div>
                        ))}
                    </div>
                )}

                <div ref={scrollRef} className={`p-5 sm:p-6 overflow-y-auto custom-scrollbar flex-1 min-h-0 relative break-words ${actions || onSave || formId ? '' : 'rounded-b-3xl'}`}>
                    {children}
                </div>

                {(actions || onSave || formId) && (
                    <div className="p-4 border-t border-slate-200 bg-white shrink-0 rounded-b-3xl flex justify-between items-center flex-wrap gap-3 mt-auto">
                        {actions ? (
                            typeof actions === 'function' ? actions(handleCloseAttempt) : actions
                        ) : (
                            <>
                                <Button 
                                    variant="secondary" 
                                    type="button" 
                                    onClick={handleCloseAttempt} 
                                    disabled={effectivePreventClose} 
                                    className="flex-1 py-3 justify-center text-xs"
                                >
                                    {cancelText}
                                </Button>
                                <Button 
                                    type={formId ? "submit" : "button"} 
                                    form={formId}
                                    onClick={!formId ? onSave : undefined}
                                    variant={isDirty ? "primary" : "secondary"} 
                                    disabled={!isDirty || effectivePreventClose} 
                                    icon={effectivePreventClose ? LoaderIcon : (isDirty ? SaveIcon : CheckCircleIcon)}
                                    className="flex-[2] py-3 uppercase tracking-widest justify-center shadow-md text-xs transition-all duration-300"
                                >
                                    {effectivePreventClose ? "Enregistrement..." : (isDirty ? saveText : savedText)}
                                </Button>
                            </>
                        )}
                    </div>
                )}
            </div>
        </div>
    );

    return (positionClass === 'absolute' || !window.ReactDOM) ? modalContent : window.ReactDOM.createPortal(modalContent, document.body);
};

window.pano_ConfirmModal = ({ title, message, confirmText = "Confirmer", cancelText = "Annuler", isDestructive = false, type = 'confirm', onConfirm, onCancel, positionClass = "fixed" }) => {
    const { LoaderIcon } = window.pano_getIcons();
    const { Button, Modal } = window.pano_getComponents();
    const [isProcessing, ReactSetIsProcessing] = React.useState(false);
    const modalType = isDestructive ? 'error' : type;

    // SÉCURITÉ ANTI-GEL INFNI
    const isMounted = React.useRef(true);
    React.useEffect(() => {
        return () => { isMounted.current = false; };
    }, []);

    return (
        <Modal 
            title={title} 
            type={modalType} 
            onClose={onCancel} 
            preventClose={isProcessing} 
            positionClass={positionClass}
            actions={(close) => (
                <>
                    <Button variant="secondary" onClick={(e) => close(e)} disabled={isProcessing} className="flex-1 py-3 justify-center">
                        {cancelText}
                    </Button>
                    <Button 
                        variant={isDestructive ? 'dangerSolid' : (type === 'info' ? 'infoSolid' : (type === 'success' ? 'successSolid' : 'primary'))} 
                        onClick={async (e) => { 
                            ReactSetIsProcessing(true); 
                            try {
                                await onConfirm(e); 
                            } finally {
                                if (isMounted.current) ReactSetIsProcessing(false);
                            }
                        }} 
                        disabled={isProcessing} 
                        icon={isProcessing ? LoaderIcon : null}
                        className="flex-[2] py-3 uppercase tracking-widest justify-center shadow-md text-xs"
                    >
                        {confirmText}
                    </Button>
                </>
            )}
        >
            <div className="space-y-6">
                <p className="text-slate-600 font-medium leading-relaxed break-words">{message}</p>
            </div>
        </Modal>
    );
};

window.pano_PromptModal = ({ title, message, placeholder = "", confirmText = "Valider", cancelText = "Annuler", type = 'confirm', onConfirm, onCancel, positionClass = "fixed" }) => {
    const { LoaderIcon } = window.pano_getIcons();
    const { Button, Modal } = window.pano_getComponents();
    const [val, setVal] = React.useState('');
    const [isProcessing, setIsProcessing] = React.useState(false);

    // SÉCURITÉ ANTI-GEL INFNI
    const isMounted = React.useRef(true);
    React.useEffect(() => {
        return () => { isMounted.current = false; };
    }, []);

    return (
        <Modal 
            title={title} 
            type={type} 
            onClose={onCancel} 
            preventClose={isProcessing} 
            positionClass={positionClass}
            actions={(close) => (
                <>
                    <Button variant="secondary" type="button" onClick={(e) => close(e)} disabled={isProcessing} className="flex-1 py-3 justify-center">
                        {cancelText}
                    </Button>
                    <Button 
                        type="submit" 
                        form="prompt-form"
                        variant={type === 'error' ? 'dangerSolid' : (type === 'info' ? 'infoSolid' : 'primary')} 
                        disabled={isProcessing || !val.trim()} 
                        icon={isProcessing ? LoaderIcon : null}
                        className="flex-[2] py-3 uppercase tracking-widest justify-center shadow-md text-xs"
                    >
                        {confirmText}
                    </Button>
                </>
            )}
        >
            <form id="prompt-form" onSubmit={async (e) => { 
                e.preventDefault(); 
                setIsProcessing(true); 
                try {
                    await onConfirm(val, e); 
                } finally {
                    if (isMounted.current) setIsProcessing(false);
                }
            }} className="space-y-6">
                <div className="text-xs text-slate-500 mb-2"><span className="text-red-500 font-black">*</span> Champs obligatoires</div>
                <p className="text-slate-600 font-medium leading-relaxed break-words">{message}</p>
                <input 
                    type="text" 
                    value={val} 
                    onChange={e => setVal(e.target.value)} 
                    placeholder={placeholder} 
                    className="w-full border-2 border-slate-200 rounded-xl p-3 focus:border-emerald-500 outline-none transition font-bold" 
                    autoFocus 
                    required 
                />
            </form>
        </Modal>
    );
};

window.pano_PasswordPromptModal = ({ title = "Confirmation de sécurité", desc, onConfirm, onCancel, isSaving, positionClass = "fixed" }) => {
    const { LoaderIcon } = window.pano_getIcons();
    const { Button, Modal, FormInput } = window.pano_getComponents();
    const [pwd, setPwd] = React.useState('');

    // CORRECTION UX/SÉCURITÉ : Surlignement en rouge de la clé AES si elle est demandée
    const formatDesc = (text) => {
        if (!text) return null;
        if (text.includes('AES_KEY_CONFIRM')) {
            const parts = text.split('AES_KEY_CONFIRM');
            return (
                <>
                    {parts[0]}
                    <span className="bg-red-100 text-red-700 font-black px-1.5 py-0.5 rounded uppercase tracking-widest mx-1 border border-red-200 select-all">
                        AES_KEY_CONFIRM
                    </span>
                    {parts[1]}
                </>
            );
        }
        return text;
    };

    return (
        <Modal 
            title={title} 
            type="confirm" 
            onClose={onCancel} 
            preventClose={isSaving} 
            positionClass={positionClass}
            actions={(close) => (
                <Button type="submit" form="pwd-prompt-form" variant="dark" disabled={isSaving || !pwd} icon={isSaving ? LoaderIcon : null} className="w-full py-3 uppercase tracking-widest justify-center shadow-md text-xs">
                    Confirmer l'action
                </Button>
            )}
        >
            <div className="text-sm text-slate-600 mb-6 font-medium leading-relaxed break-words">
                {formatDesc(desc)}
            </div>
            <form id="pwd-prompt-form" onSubmit={(e) => {
                e.preventDefault();
                if(pwd) onConfirm(pwd, e);
            }}>
                <FormInput 
                    name="pwd"
                    type="password" 
                    autoFocus 
                    required 
                    placeholder={desc?.includes('AES_KEY_CONFIRM') ? "Collez votre clé sécurisée ici..." : "Mot de passe admin / connexion..."} 
                    value={pwd}
                    onChange={e => setPwd(e.target.value)}
                />
            </form>
        </Modal>
    );
};

window.pano_UploadErrorsModal = ({ errors, onClose }) => {
    const { Button, Modal } = window.pano_getComponents();

    if (!errors || errors.length === 0) return null;

    return (
        <Modal 
            title="Rapport d'importation" 
            type="warning" 
            onClose={onClose} 
            actions={(close) => (
                <Button variant="secondary" onClick={close} className="w-full py-3 justify-center">Fermer</Button>
            )}
        >
            <p className="text-sm text-slate-600 mb-4 break-words">Certains fichiers ont été ignorés lors de la sélection ou du transfert :</p>
            <div className="space-y-2 max-h-[40vh] overflow-y-auto custom-scrollbar bg-slate-50 p-2 rounded-xl border border-slate-200">
                {errors.map((e, i) => (
                    <div key={i} className="bg-white p-3 rounded-lg border border-slate-200 shadow-sm flex flex-col sm:flex-row sm:justify-between gap-2 sm:items-center">
                        <span className="text-xs font-bold text-slate-700 break-words leading-tight flex-1" title={e.file}>{e.file}</span>
                        <span className="text-[10px] font-black text-red-600 uppercase tracking-widest bg-red-50 px-2 py-1 rounded shrink-0 text-center break-words">{e.reason}</span>
                    </div>
                ))}
            </div>
        </Modal>
    );
};

// 4. - LECTEURS ET VISIONNEUSES DE DOCUMENTS

window.pano_VaultDocumentThumbnail = ({ doc }) => {
    const { FileIcon, LoaderIcon } = window.pano_getIcons();
    const [status, setStatus] = React.useState('loading'); 
    const [retryCount, setRetryCount] = React.useState(0);

    // SÉCURITÉ ANTI-FUITE DE MÉMOIRE
    const isMounted = React.useRef(true);
    React.useEffect(() => {
        return () => { isMounted.current = false; };
    }, []);

    const handleError = () => {
        if (retryCount < 5) {
            setTimeout(() => {
                if (isMounted.current) {
                    setRetryCount(prev => prev + 1);
                    setStatus('loading');
                }
            }, 1000 + (retryCount * 500));
        } else {
            if (isMounted.current) setStatus('error');
        }
    };

    const typeLabel = doc.type === 'image' ? 'IMG' : 'PDF';
    const srcUrl = doc.type === 'image' 
        ? `${window.pano_CONFIG.apiBaseUrl}file/download&type=image&id=${doc.id}&preview=1&private=1&retry=${retryCount}`
        : `${window.pano_CONFIG.apiBaseUrl}file/download&type=pdf&id=${doc.id}&preview=1&page=0&private=1&retry=${retryCount}`;

    return (
        <div className="relative w-full h-full flex items-center justify-center">
            {(status === 'loading' || status === 'error') && (
                <div className="absolute inset-0 flex flex-col items-center justify-center text-slate-300 bg-slate-50 z-10 rounded-xl">
                    {FileIcon && <FileIcon size={32}/>}
                    <span className="text-[9px] font-bold mt-1 text-slate-400 uppercase tracking-widest">{typeLabel}</span>
                    {status === 'loading' && LoaderIcon && <LoaderIcon size={14} className="animate-spin absolute top-2 right-2 text-slate-400" />}
                </div>
            )}
            <img 
                src={srcUrl} 
                className={`max-h-full max-w-full object-contain transition-opacity duration-300 z-20 relative ${status === 'loaded' ? 'opacity-100' : 'opacity-0'}`} 
                alt={doc.name || "Aperçu"} 
                onLoad={() => { if(isMounted.current) setStatus('loaded'); }}
                onError={handleError} 
            />
        </div>
    );
};

const VaultPageImage = ({ src, alt }) => {
    const { FileIcon } = window.pano_getIcons();
    const [error, setError] = React.useState(false);

    if (error) {
        return (
            <div className="w-full max-w-4xl rounded-xl shadow-inner bg-slate-50 shrink-0 min-h-[200px] flex flex-col items-center justify-center text-slate-400 border border-slate-200" onMouseDown={e => e.stopPropagation()}>
                {FileIcon && <FileIcon size={48} className="mb-4 opacity-30" />}
                <p className="font-bold text-sm">Aperçu web indisponible</p>
                <p className="text-xs mt-1 text-center px-4">Le document a été sauvegardé brut. Veuillez télécharger le fichier original pour le visualiser.</p>
            </div>
        );
    }

    return (
        <img 
            src={src} 
            className="w-full max-w-4xl rounded-xl shadow-2xl bg-white shrink-0 min-h-[200px] object-contain" 
            alt={alt} 
            onMouseDown={e => e.stopPropagation()} 
            onError={() => setError(true)}
        />
    );
};

window.pano_UniversalViewer = ({ fileId, fileUrl, fileType, fileName, numPages = 1, isPrivate = false, useSafePdfMode = false, positionClass = "fixed", onClose }) => {
    const [zIdx] = React.useState(() => window.pano_getNextModalZIndex());
    const { ArrowLeftIcon, DownloadIcon } = window.pano_getIcons();
    const { Button, PdfFullViewer } = window.pano_getComponents();

    const privateParam = isPrivate ? '&private=1' : '';
    const downloadUrl = fileUrl || `${window.pano_CONFIG.apiBaseUrl}file/download&type=${fileType}&id=${fileId}${privateParam}`;
    const imageUrl = fileUrl || `${window.pano_CONFIG.apiBaseUrl}file/download&type=image&id=${fileId}${privateParam}`;

    const handleBackgroundClick = (e) => {
        if (e.target === e.currentTarget) onClose(e);
    };

    const safeNumPages = Math.min(numPages, 20); 
    const pages = Array.from({ length: safeNumPages }, (_, i) => i + 1);

    const viewerContent = (
        <div className={`${positionClass} inset-0 bg-slate-900/95 backdrop-blur-xl flex flex-col animate-in fade-in duration-200 isolate`} style={{ zIndex: zIdx }} onMouseDown={handleBackgroundClick}>
            <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="secondary" 
                    shape="square"
                    icon={ArrowLeftIcon} 
                    onClick={onClose} 
                    className="shadow-md shrink-0 p-3" 
                    title="Retour"
                />
                
                <div className="flex-1 px-4 text-center break-words leading-tight font-bold text-sm sm:text-base text-slate-200" title={fileName || 'Document'}>
                    {fileName || 'Document'}
                </div>

                <a 
                    href={downloadUrl} 
                    download 
                    className="flex items-center justify-center p-3 bg-emerald-600 hover:bg-emerald-700 rounded-xl transition shadow-lg cursor-pointer text-white shrink-0 aspect-square" 
                    title="Télécharger l'original"
                >
                    {DownloadIcon && <DownloadIcon size={20}/>}
                </a>
            </div>
            
            <div className={`flex-1 flex flex-col items-center justify-start min-h-0 relative w-full ${useSafePdfMode ? 'p-4 sm:p-8 overflow-y-auto custom-scrollbar gap-6' : 'p-2 sm:p-4'}`} onMouseDown={handleBackgroundClick}>
                {fileType === 'image' && (
                    <img src={imageUrl} alt={fileName || "Aperçu"} className="max-w-full max-h-full object-contain rounded-xl shadow-2xl shrink-0" onMouseDown={e => e.stopPropagation()} />
                )}
                
                {fileType === 'pdf' && !useSafePdfMode && PdfFullViewer && (
                    <PdfFullViewer id={fileId} url={fileUrl} numPages={numPages} isPrivate={isPrivate} onBackgroundClick={onClose} />
                )}
                
                {fileType === 'pdf' && !useSafePdfMode && !PdfFullViewer && (
                    <div className="text-white flex h-full items-center justify-center font-bold break-words text-center">Le lecteur PDF est introuvable.</div>
                )}
                
                {fileType === 'pdf' && useSafePdfMode && (
                    <>
                        {pages.map(p => (
                            <VaultPageImage key={p} src={`${window.pano_CONFIG.apiBaseUrl}file/download&type=pdf&id=${fileId}&preview=1&page=${p}${privateParam}`} alt={`Page ${p}`} />
                        ))}
                        {numPages > 20 && (
                            <div className="w-full max-w-4xl text-center py-6 bg-slate-800/80 rounded-xl border border-slate-700 text-slate-300 font-medium shrink-0 mb-8 mt-2 shadow-inner px-4 break-words" onMouseDown={e => e.stopPropagation()}>
                                L'aperçu en ligne est limité aux 20 premières pages pour des raisons de performance.<br/>
                                <span className="text-emerald-400 font-bold">Veuillez télécharger le document original pour le consulter en intégralité.</span>
                            </div>
                        )}
                    </>
                )}
            </div>
        </div>
    );

    return (positionClass === 'absolute' || !window.ReactDOM) ? viewerContent : window.ReactDOM.createPortal(viewerContent, document.body);
};

/* EOF ========== [_react/ui/_ui_modals.jsx] */