/**
 * =========================================================================
 * PLATEFORME ECO-PANNEAU.FR - VERSION 1.0.0
 * Socle UI (4/4) - Modales, Coffre-fort et Paiement (Stripe)
 * =========================================================================
 */

// =========================================================================
// 1. WRAPPER STRIPE ELEMENTS
// =========================================================================

window.StripeElements = ({ clientSecret, onSuccess }) => {
    const stripePromise = React.useMemo(() => window.Stripe ? window.Stripe(window.ECO_CONFIG.stripePubKey) : null, []);
    
    if (!window.ReactStripe || !stripePromise) {
        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, PaymentElement, useStripe, useElements } = window.ReactStripe;

    const CheckoutForm = () => {
        const stripe = useStripe();
        const elements = useElements();
        const [error, ReactSetError] = React.useState(null);
        const [processing, setProcessing] = React.useState(false);

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

            setProcessing(true);
            const result = await stripe.confirmPayment({
                elements,
                redirect: 'if_required'
            });

            if (result.error) {
                ReactSetError(result.error.message);
                setProcessing(false);
            } else if (result.paymentIntent && result.paymentIntent.status === 'succeeded') {
                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">{error}</div>}
                <window.Button type="submit" variant="infoSolid" disabled={!stripe || processing} className="w-full mt-4 py-3 uppercase tracking-widest justify-center shadow-lg">
                    {processing ? 'Traitement en cours...' : 'Payer de manière sécurisée'}
                </window.Button>
            </form>
        );
    };

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

// =========================================================================
// 2. MODALES GÉNÉRIQUES (SPA URL LAYER 1 ET LAYER 2)
// =========================================================================

window.ModalOverlay = ({ children, zIndex = "z-[100]", onClose, preventClose = false, className = "flex items-center justify-center p-4" }) => {
    return (
        <div 
            className={`fixed inset-0 bg-slate-900/80 backdrop-blur-sm ${zIndex} animate-in fade-in duration-200 ${className}`} 
            onMouseDown={(e) => { 
                if (e.target === e.currentTarget && !preventClose && onClose) {
                    onClose(); 
                }
            }}
        >
            {children}
        </div>
    );
};

window.Modal = ({ title, type = 'info', onClose, children, preventClose = false, requireConfirm = false, zIndex = "z-[100]" }) => {
    // FACTORISATION : Utilisation des utilitaires globaux
    const { XIcon } = window.getIcons();
    const { alertParam, setAlert } = window.useUrlModal();
    
    // Le parent envoie le close, mais s'il y a un requireConfirm, on doit l'intercepter via l'URL (Layer 2)
    const handleCloseAttempt = React.useCallback(() => {
        if (requireConfirm) {
            setAlert('unsaved');
        } else {
            if (onClose) onClose();
        }
    }, [requireConfirm, onClose, setAlert]);

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

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

    // Fermeture propre via la touche Échap (Accessibilité)
    React.useEffect(() => {
        const handleEsc = (e) => { if (e.key === 'Escape' && !preventRef.current) closeRef.current(); };
        window.addEventListener('keydown', handleEsc);
        return () => window.removeEventListener('keydown', handleEsc);
    }, []);

    // Lecture de l'URL via le Hook pour afficher l'alerte d'annulation (Couche 2 / Dialog)
    const showConfirm = alertParam === 'unsaved';

    let headerBgClass = 'bg-slate-50/50';
    let headerTextClass = 'text-slate-800';
    let closeIconClass = 'text-slate-400 hover:text-blue-500 hover:bg-blue-50';

    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';
    } else {
        headerBgClass = 'bg-slate-50/50 border-b border-slate-100';
    }

    return (
        <>
            <window.ModalOverlay zIndex={zIndex} onClose={handleCloseAttempt} preventClose={preventClose}>
                <div className="bg-white rounded-3xl shadow-2xl w-full max-w-lg overflow-hidden flex flex-col max-h-[90vh] animate-in zoom-in-95 duration-200" onMouseDown={e => e.stopPropagation()}>
                    <div className={`p-5 flex justify-between items-center shrink-0 ${headerBgClass} transition-colors`}>
                        <h3 className={`font-black text-lg pr-4 ${headerTextClass}`}>{title}</h3>
                        {!preventClose && (
                            <div role="button" tabIndex={0} onClick={handleCloseAttempt} className={`p-2 rounded-xl transition shrink-0 cursor-pointer ${closeIconClass}`}>
                                <XIcon size={20} />
                            </div>
                        )}
                    </div>
                    <div className="p-5 sm:p-6 overflow-y-auto custom-scrollbar flex-1 relative">
                        {children}
                    </div>
                </div>
            </window.ModalOverlay>

            {showConfirm && window.ConfirmModal && (
                <window.ConfirmModal 
                    title="Modifications non enregistrées"
                    message="Vous avez des modifications non enregistrées. Voulez-vous vraiment annuler ? Vos modifications seront perdues."
                    confirmText="Oui, annuler"
                    cancelText="Retour"
                    isDestructive={true}
                    onConfirm={() => {
                        window.history.back(); // Enlève le paramètre d'alerte de l'URL
                        setTimeout(() => { if (onClose) onClose(); }, 50); // Laisse le temps au navigateur de nettoyer l'URL avant de fermer la modale principale
                    }}
                    onCancel={() => window.history.back()}
                    zIndex="z-[9999]"
                />
            )}
        </>
    );
};

window.ConfirmModal = ({ title, message, confirmText = "Confirmer", cancelText = "Annuler", isDestructive = false, type = 'confirm', onConfirm, onCancel, zIndex = "z-[200]" }) => {
    const { LoaderIcon } = window.getIcons();
    const [isProcessing, ReactSetIsProcessing] = React.useState(false);
    const modalType = isDestructive ? 'error' : type;

    return (
        <window.Modal title={title} type={modalType} onClose={onCancel} preventClose={isProcessing} zIndex={zIndex}>
            <div className="space-y-6">
                <p className="text-slate-600 font-medium leading-relaxed">{message}</p>
                <div className="flex gap-3 pt-2">
                    <window.Button variant="secondary" onClick={onCancel} disabled={isProcessing} className="flex-1 py-3 justify-center">
                        {cancelText}
                    </window.Button>
                    <window.Button 
                        variant={isDestructive ? 'dangerSolid' : (type === 'info' ? 'infoSolid' : (type === 'success' ? 'successSolid' : 'primary'))} 
                        onClick={async () => { ReactSetIsProcessing(true); await onConfirm(); }} 
                        disabled={isProcessing} 
                        icon={isProcessing ? LoaderIcon : null}
                        className="flex-1 py-3 uppercase tracking-widest justify-center"
                    >
                        {confirmText}
                    </window.Button>
                </div>
            </div>
        </window.Modal>
    );
};

window.PromptModal = ({ title, message, placeholder = "", confirmText = "Valider", cancelText = "Annuler", type = 'confirm', onConfirm, onCancel, zIndex = "z-[200]" }) => {
    const { LoaderIcon } = window.getIcons();
    const [val, setVal] = React.useState('');
    const [isProcessing, setIsProcessing] = React.useState(false);

    return (
        <window.Modal title={title} type={type} onClose={onCancel} preventClose={isProcessing} zIndex={zIndex}>
            <form onSubmit={async (e) => { e.preventDefault(); setIsProcessing(true); await onConfirm(val); }} 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">{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 
                />
                <div className="flex gap-3 pt-2 border-t border-slate-100">
                    <window.Button variant="secondary" type="button" onClick={onCancel} disabled={isProcessing} className="flex-1 py-3 justify-center">
                        {cancelText}
                    </window.Button>
                    <window.Button 
                        type="submit" 
                        variant={type === 'error' ? 'dangerSolid' : (type === 'info' ? 'infoSolid' : 'primary')} 
                        disabled={isProcessing || !val.trim()} 
                        icon={isProcessing ? LoaderIcon : null}
                        className="flex-1 py-3 uppercase tracking-widest justify-center"
                    >
                        {confirmText}
                    </window.Button>
                </div>
            </form>
        </window.Modal>
    );
};

window.PasswordPromptModal = ({ title = "Confirmation de sécurité", desc, onConfirm, onCancel, isSaving }) => {
    const { LoaderIcon } = window.getIcons();
    const [pwd, setPwd] = React.useState('');

    return (
        <window.Modal title={title} type="confirm" onClose={onCancel} zIndex="z-[250]" preventClose={isSaving}>
            <div className="text-sm text-slate-600 mb-6 font-medium leading-relaxed">{desc}</div>
            <form onSubmit={(e) => {
                e.preventDefault();
                if(pwd) onConfirm(pwd);
            }}>
                <input 
                    name="pwd"
                    type="password" 
                    autoFocus 
                    required 
                    placeholder="Mot de passe admin / connexion..." 
                    value={pwd}
                    onChange={e => setPwd(e.target.value)}
                    className="w-full border-2 border-slate-200 rounded-xl p-3 text-sm focus:border-emerald-500 outline-none transition mb-4" 
                />
                <window.Button type="submit" variant="dark" disabled={isSaving || !pwd} icon={isSaving ? LoaderIcon : null} className="w-full py-3 uppercase tracking-widest justify-center">
                    Confirmer l'action
                </window.Button>
            </form>
        </window.Modal>
    );
};

// =========================================================================
// 3. COMPOSANTS GLOBAUX DU COFFRE-FORT
// =========================================================================

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

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

    const typeLabel = doc.type === 'image' ? 'IMG' : 'PDF';
    const srcUrl = doc.type === 'image' 
        ? `?api=file/download&type=image&id=${doc.id}&private=1&retry=${retryCount}`
        : `?api=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 size={32}/>
                    <span className="text-[9px] font-bold mt-1 text-slate-400 uppercase tracking-widest">{typeLabel}</span>
                    {status === 'loading' && <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={() => setStatus('loaded')}
                onError={handleError} 
            />
        </div>
    );
};

window.VaultDocumentViewer = ({ viewingDoc, setViewingDoc }) => {
    const { ArrowLeftIcon, DownloadIcon, FileIcon } = window.getIcons();
    if (!viewingDoc) return null;
    
    const numPages = viewingDoc.numPages || 1;
    const pages = Array.from({ length: numPages }, (_, i) => i + 1);

    const VaultPageImage = ({ src, alt }) => {
        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" onClick={e => e.stopPropagation()}>
                    <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} 
                onClick={e => e.stopPropagation()} 
                onError={() => setError(true)}
            />
        );
    };

    return (
        <div className="fixed inset-0 z-[999999] bg-slate-900/95 backdrop-blur-sm flex flex-col animate-in fade-in duration-200" onClick={() => setViewingDoc(null)}>
            <div className="flex justify-between items-center p-4 bg-slate-900/50 text-white shrink-0 border-b border-white/10" onClick={e => e.stopPropagation()}>
                <div role="button" tabIndex={0} onClick={() => setViewingDoc(null)} className="flex items-center gap-2 px-2 sm:px-4 py-2 hover:bg-white/10 rounded-xl transition text-sm font-bold cursor-pointer shrink-0">
                    <ArrowLeftIcon size={18}/> <span className="hidden sm:inline">Retour</span>
                </div>
                
                <div className="flex-1 px-4 text-center truncate font-bold text-sm sm:text-base text-slate-200" title={viewingDoc.name}>
                    {viewingDoc.name}
                </div>

                <a href={`?api=file/download&type=${viewingDoc.type}&id=${viewingDoc.id}&private=1`} download className="flex items-center gap-2 px-3 sm:px-4 py-2 bg-emerald-600 hover:bg-emerald-700 rounded-xl transition text-sm font-bold shadow-lg cursor-pointer shrink-0">
                    <DownloadIcon size={18}/> <span className="hidden sm:inline">Original</span>
                </a>
            </div>
            
            <div className="flex-1 flex flex-col items-center justify-start p-4 sm:p-8 min-h-0 relative w-full overflow-y-auto custom-scrollbar gap-6" onClick={() => setViewingDoc(null)}>
                {viewingDoc.type === 'image' ? (
                    <VaultPageImage src={`?api=file/download&type=image&id=${viewingDoc.id}&private=1`} alt={viewingDoc.name} />
                ) : (
                    <>
                        {pages.map(p => (
                            <VaultPageImage key={p} src={`?api=file/download&type=pdf&id=${viewingDoc.id}&preview=1&page=${p}&private=1`} alt={`Page ${p}`} />
                        ))}
                        {numPages === 50 && (
                            <div className="w-full max-w-4xl text-center py-6 bg-slate-800/50 rounded-xl border border-white/10 text-slate-300 font-medium shrink-0 mb-8 mt-2 shadow-inner" onClick={e => e.stopPropagation()}>
                                L'aperçu en ligne est limité aux 50 premières pages.<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>
    );
};

window.UploadErrorsModal = ({ errors, onClose, zIndex = "z-[350]" }) => {
    const Modal = window.Modal || (() => null);
    const Button = window.Button || (() => null);
    if (!errors || errors.length === 0) return null;

    return (
        <Modal title="Rapport d'importation" type="warning" onClose={onClose} zIndex={zIndex}>
            <p className="text-sm text-slate-600 mb-4">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 truncate 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">{e.reason}</span>
                    </div>
                ))}
            </div>
            <div className="mt-6 pt-4 border-t border-slate-100 flex justify-end">
                <Button variant="secondary" onClick={onClose} className="w-full py-3 justify-center">Fermer</Button>
            </div>
        </Modal>
    );
};

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