// ECO-PANNEAU.FR - _react/admin/_admin_factures.jsx

window.pano_AdminInvoicesTab = ({ data, refreshData, showToast, setActiveTab, openLocalModal, openLocalDialog, closeCurrentLayer, activeModal, activeDialog, targetId, adminOpts, toggleDashboardPin }) => {
    const { useState, useMemo, useEffect } = React;
    
    // SÉCURITÉ ANTI-FUITE DE MÉMOIRE : Utilisation du Hook Global Zéro-Dette
    const { isMounted, safeFetch } = window.pano_useSafeFetch();
    
    // 1. - Routage Zéro-Dette et modales
    const { activeModal: urlModal, activeDialog: urlDialog, openDialog, closeCurrentLayer: urlCloseLayer } = window.pano_useUrlModal();
    
    const routerActiveDialog = activeDialog || urlDialog;
    const routerCloseLayer = closeCurrentLayer || urlCloseLayer;
    const routerOpenDialog = openLocalDialog || openDialog;

    // 2. - États Locaux et Pagination Serveur
    const [localInvoices, setLocalInvoices] = useState(data.invoices || []);
    const [hasMoreInvoices, setHasMoreInvoices] = useState((data.invoices || []).length >= 50);
    const [isLoadingMore, setIsLoadingMore] = useState(false);

    const [downloadedInvoices, setDownloadedInvoices] = useState(() => {
        try { 
            return JSON.parse(localStorage.getItem('pano_admin_downloaded_invoices') || '[]'); 
        } catch(e) { 
            if (window.pano_logFallback) window.pano_logFallback("Erreur de parsing du localStorage (pano_admin_downloaded_invoices).");
            return []; 
        }
    });

    const [isSaving, setIsSaving] = useState(false);
    const [refundTarget, setRefundTarget] = useState(null);
    const [previewConfig, setPreviewConfig] = useState(null);
    const [archiveConfig, setArchiveConfig] = useState(null);

    // États de filtrage
    const [tempClient, setTempClient] = useState('');
    const [tempKeyword, setTempKeyword] = useState('');
    const [appliedClient, setAppliedClient] = useState('');

    useEffect(() => {
        setLocalInvoices(data.invoices || []);
        setHasMoreInvoices((data.invoices || []).length >= 50);
    }, [data.invoices]);

    // Synchronisation multi-onglets pour la pastille "Non lu"
    useEffect(() => {
        const handleUpdate = () => {
            try { 
                setDownloadedInvoices(JSON.parse(localStorage.getItem('pano_admin_downloaded_invoices') || '[]')); 
            } catch(e) {}
        };
        window.addEventListener('admin_invoice_downloaded', handleUpdate);
        return () => window.removeEventListener('admin_invoice_downloaded', handleUpdate);
    }, []);

    // 3. - Icônes et Composants
    const {
        DownloadIcon, RefreshCwIcon, FileTextIcon, LoaderIcon, 
        CheckCircleIcon, ArchiveIcon, PinIcon, EyeIcon, InfoIcon, AlertTriangleIcon, UserIcon
    } = window.pano_getIcons();

    const {
        Modal, Button, CardGrid, DataCard, FormInput,
        EmptySearch, UniversalViewer, ArchiveGeneratorModal,
        SearchBar, PaginationFooter
    } = window.pano_getComponents();

    const clients = data.clients || [];

    // 4. - Filtrage Dynamique et Pagination Client
    const invoicesForSearch = useMemo(() => {
        if (!appliedClient) return localInvoices;
        const selectedClientObj = clients.find(c => c.id === appliedClient);
        return localInvoices.filter(inv => {
            if (inv.clientName === appliedClient) return true;
            if (selectedClientObj && typeof inv.clientName === 'string') {
                if (inv.clientName.includes(selectedClientObj.name)) return true;
            }
            return false;
        });
    }, [localInvoices, appliedClient, clients]);

    const { 
        searchQuery, setSearchQuery, 
        visibleCount, setVisibleCount, 
        filteredData: filteredInvoices 
    } = window.pano_useSearchAndPagination(invoicesForSearch, (inv, q) => {
        const n = window.pano_normalizeString;
        const client = clients.find(c => c.id === inv.clientName);
        const clientNameStr = n(client?.name || inv.clientName);
        const refStr = n(inv.invoice_ref || inv.invoiceNumber);
        const typeStr = n(inv.type);
        const amountStr = n(inv.amount);
        const dateStr = window.pano_formatDate ? window.pano_formatDate(inv.created_at) : new Date(String(inv.created_at || '').replace(' ', 'T')).toLocaleDateString('fr-FR');
        const panNameStr = n(inv.panneauName);
        
        return refStr.includes(q) || clientNameStr.includes(q) || typeStr.includes(q) || amountStr.includes(q) || panNameStr.includes(q) || n(dateStr).includes(q);
    });

    // 5. - Actions métier
    const handleLoadMoreInvoices = async () => {
        const d = await safeFetch(`sync/more&type=invoices&offset=${localInvoices.length}&limit=50`, { 
            method: 'GET', 
            silent: true,
            setLoading: setIsLoadingMore
        });
        
        if (!isMounted.current) return; // SÉCURITÉ : Coupe-circuit si l'onglet a été fermé

        if (d && d.status === 'success') {
            const newInvoices = d.data.invoices || [];
            setLocalInvoices(prev => {
                const combined = [...prev, ...newInvoices];
                // Dédoublonnage par sécurité
                return Array.from(new Map(combined.map(item => [item.id, item])).values());
            });
            setHasMoreInvoices(newInvoices.length === 50);
        }
    };

    const handleDownload = (invRef) => {
        if (!downloadedInvoices.includes(invRef)) {
            const newArr = [...downloadedInvoices, invRef];
            setDownloadedInvoices(newArr);
            localStorage.setItem('pano_admin_downloaded_invoices', JSON.stringify(newArr));
            window.dispatchEvent(new CustomEvent('admin_invoice_downloaded'));
        }
        // Sécurité SPA : On ouvre un nouvel onglet pour éviter de tuer React si le serveur renvoie une erreur JSON
        window.open(`${window.pano_CONFIG.apiBaseUrl}invoices/download&ref=${invRef}`, '_blank');
    };

    const handleRefund = async (e) => {
        e.preventDefault();
        const amount = parseFloat(e.target.amount.value);
        const reason = e.target.reason.value;
        const mode = e.target.mode.value;
        
        if (amount <= 0 || amount > refundTarget.maxRefundable) return showToast("Montant invalide", "error");
        
        const invRef = refundTarget.invoice.invoice_ref || refundTarget.invoice.invoiceNumber;

        const d = await safeFetch('invoices/refund', {
            body: { invoice_ref: invRef, amount, mode, reason },
            setLoading: setIsSaving,
            successMessage: "Remboursement ou avoir traité avec succès !"
        });

        if (!isMounted.current) return; // SÉCURITÉ : Coupe-circuit post-requête

        if (d) {
            routerCloseLayer();
            refreshData();
        }
    };

    const targetInvoice = routerActiveDialog === 'invoice_details' && routerDialogId ? localInvoices.find(i => (i.invoice_ref || i.invoiceNumber) === routerDialogId) : null;

    // CLASSIFICATION : URGENCE > FAVORIS > RESTE
    const pinnedIds = adminOpts?.invoices || [];

    const attentionInvoices = [];
    const pinnedInvoices = [];
    const otherInvoices = [];

    filteredInvoices.forEach(inv => {
        const invRef = inv.invoice_ref || inv.invoiceNumber;
        const isUnread = !downloadedInvoices.includes(invRef);
        const isPinned = pinnedIds.includes(invRef);

        const isArchive = String(inv.id).startsWith('arc_');
        const needsAttention = isUnread && !isArchive;

        if (needsAttention) {
            attentionInvoices.push(inv);
        } else if (isPinned) {
            pinnedInvoices.push(inv);
        } else {
            otherInvoices.push(inv);
        }
    });

    const displayedOtherInvoices = otherInvoices.slice(0, visibleCount);

    // 7. - Rendu des cartes (Factures)
    const renderInvoiceCard = (inv, keyPrefix) => {
        const client = clients.find(c => c.id === inv.clientName);
        const invRef = inv.invoice_ref || inv.invoiceNumber;
        const isArchive = String(inv.id).startsWith('arc_');
        const isUnread = !downloadedInvoices.includes(invRef) && !isArchive;
        const isPinned = pinnedIds.includes(invRef);
        const isAvoir = inv.type.includes('Avoir') || parseFloat(inv.amount) < 0;
        
        let maxRefundable = 0;
        if (!isAvoir && !isArchive) {
            const relatedAvoirs = localInvoices.filter(r => 
                (r.type.includes('Avoir') || parseFloat(r.amount) < 0) && 
                (r.type.includes(invRef))
            );
            const totalRefunded = relatedAvoirs.reduce((sum, r) => sum + Math.abs(parseFloat(r.amount)), 0);
            maxRefundable = parseFloat((parseFloat(inv.amount) - totalRefunded).toFixed(2));
        }

        return (
            <DataCard key={`${keyPrefix}_${invRef}`} className={`relative transition flex flex-col h-full min-w-0 group p-4 ${isUnread ? 'border-emerald-300 shadow-md ring-2 ring-emerald-500/20' : 'hover:border-slate-300'} ${isArchive ? 'bg-slate-50 opacity-90' : ''}`}>
                <div 
                    role="button" 
                    tabIndex={0} 
                    onClick={(e) => { e.stopPropagation(); toggleDashboardPin && toggleDashboardPin('invoices', invRef, e); }} 
                    className={`absolute top-2 right-2 z-20 p-1 cursor-pointer transition-all duration-200 ${isPinned ? 'text-amber-500 opacity-100 hover:scale-110' : 'text-slate-300 opacity-0 group-hover:opacity-100 hover:text-slate-500 hover:scale-110'}`}
                    style={{ transform: 'rotate(30deg)' }}
                    title={isPinned ? "Désépingler" : "Épingler au tableau de bord"}
                >
                    <PinIcon size={18} filled={isPinned} />
                </div>

                {isUnread && <span className="absolute -top-2 -left-2 bg-emerald-500 text-white text-[10px] font-black uppercase tracking-widest px-2 py-1 rounded-full shadow-sm z-10">Nouvelle</span>}
                {isArchive && <span className="absolute -top-2 -left-2 bg-slate-200 text-slate-500 text-[9px] font-black uppercase tracking-widest px-2 py-1 rounded-md border border-slate-300 shadow-sm z-10">Archive légale</span>}
                
                <div className="flex justify-between items-start gap-2 min-w-0">
                    <div className="min-w-0">
                        <span className="text-[10px] uppercase tracking-widest text-slate-400 font-bold block mb-1">Date</span>
                        <span className="text-sm font-bold text-slate-700">{window.pano_formatDate ? window.pano_formatDate(inv.created_at) : new Date(String(inv.created_at || '').replace(' ', 'T')).toLocaleDateString('fr-FR')}</span>
                    </div>
                    <div className="flex flex-col items-end gap-1 shrink-0 relative z-10 mr-6">
                        <div className="text-right min-w-0">
                            <span className="text-[10px] uppercase tracking-widest text-slate-400 font-bold block mb-1 break-words">Montant</span>
                            <span className={`text-sm font-black break-words ${isAvoir ? 'text-amber-600' : 'text-slate-800'}`}>{inv.amount} €</span>
                        </div>
                    </div>
                </div>
                
                {/* BLOC CENTRAL : Le nom du Panneau est mis en avant */}
                <div className="pt-2 border-t border-slate-100 flex-1 min-w-0 flex flex-col mt-2">
                    {inv.panneauName && (
                        <>
                            <span className="text-[10px] uppercase tracking-widest text-slate-400 font-bold block mb-1 break-words">Projet concerné</span>
                            <span className="text-sm font-black text-emerald-700 break-words leading-tight block mb-2">{inv.panneauName}</span>
                        </>
                    )}
                    
                    {(client?.name || inv.clientName) && (
                        <div className="flex items-center gap-1 mt-1 min-w-0">
                            <UserIcon size={10} className="text-slate-400 shrink-0" />
                            <span className={`text-xs font-bold break-words leading-tight ${isArchive ? 'text-red-500' : 'text-slate-600'}`} title={client?.name || inv.clientName}>
                                {client?.name || inv.clientName}
                            </span>
                        </div>
                    )}
                    <span className="text-[10px] font-medium text-slate-500 break-words leading-tight mt-auto pt-2 block">
                        {inv.type.replace(/\s*\(PI:[^)]+\)/, '')} (Réf. {invRef})
                    </span>
                </div>
                
                {/* ACTIONS : Masquées tant que la facture n'est pas téléchargée */}
                <div className="flex justify-end gap-2 pt-3 mt-auto border-t border-slate-100 min-w-0">
                    {!isUnread && (
                        <>
                            {!isArchive && <Button variant="secondary" shape="square" icon={InfoIcon} onClick={() => routerOpenDialog('invoice_details', invRef, false)} title="Détails" className="p-2 bg-white shadow-sm border-slate-200 shrink-0" />}
                            <Button variant="secondary" shape="square" icon={EyeIcon} onClick={() => setPreviewConfig({ url: `${window.pano_CONFIG.apiBaseUrl}invoices/download&ref=${invRef}`, name: `Facture ${invRef}` })} title="Aperçu de la facture" className="p-2 bg-white shadow-sm border-slate-200 shrink-0" />
                            
                            {!isAvoir && !isArchive && maxRefundable > 0 && (
                                <Button 
                                    variant="warning" 
                                    shape="square" 
                                    icon={RefreshCwIcon} 
                                    onClick={() => { setRefundTarget({ invoice: inv, clientName: client?.name || inv.clientName || 'Client', maxRefundable }); routerOpenDialog('refund', null, false); }} 
                                    title={`Émettre un avoir (Max: ${maxRefundable}€)`} 
                                    className="p-2 shadow-sm shrink-0" 
                                />
                            )}
                        </>
                    )}
                    <Button variant={isArchive ? "secondary" : "primary"} icon={DownloadIcon} onClick={() => handleDownload(invRef)} className="flex-1 py-2 text-xs uppercase tracking-widest justify-center shadow-md text-center">
                        {isArchive ? "Copie" : "Télécharger"}
                    </Button>
                </div>
            </DataCard>
        );
    };

    // 8. - Rendu UI
    return (
        <div className="space-y-8 animate-in fade-in slide-in-from-bottom-4 min-w-0 w-full overflow-x-hidden">
            <div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-4 w-full min-w-0">
                <div className="min-w-0">
                    <h1 className="text-3xl font-black text-slate-800 break-words">Factures et avoirs</h1>
                    <p className="text-slate-500 font-medium break-words">Retrouvez l'historique de tous les paiements et abonnements.</p>
                </div>
                
                {invoicesForSearch.length > 0 && SearchBar && (
                    <div className="relative w-full lg:w-96 flex-1 max-w-md shrink-0">
                        <SearchBar 
                            searchQuery={searchQuery} 
                            setSearchQuery={setSearchQuery} 
                            placeholder="Rechercher (Réf, Projet, Montant)..." 
                        />
                    </div>
                )}

                {/* CORRECTION SÉCURITÉ UI : Masquage conditionnel des boutons d'export */}
                {localInvoices.length > 0 && (
                    <div className="flex gap-2 shrink-0 w-full lg:w-auto">
                        <Button variant="outline" icon={ArchiveIcon} onClick={() => { setArchiveConfig({ type: 'factures' }); routerOpenDialog('archive_config', null, false); }} className="py-2.5 flex-1 lg:flex-none justify-center" title="Exporter toutes les factures en ZIP sécurisé">
                            <span className="hidden sm:inline">Export ZIP sécurisé</span>
                            <span className="sm:hidden">ZIP</span>
                        </Button>
                        <Button variant="outline" icon={DownloadIcon} onClick={() => window.open(window.pano_CONFIG.apiBaseUrl + "invoices/export_csv", '_blank')} className="py-2.5 flex-1 lg:flex-none justify-center" title="Exporter le listing tableur (CSV)">
                            Export CSV
                        </Button>
                    </div>
                )}
            </div>
            
            {localInvoices.length === 0 ? (
                <div className="p-12 text-center text-slate-500 bg-white rounded-3xl border border-slate-200 border-dashed min-w-0">
                    {FileTextIcon && <FileTextIcon size={48} className="mx-auto text-slate-300 mb-4" />}
                    <p className="font-medium break-words">Aucune facture émise ni archivée.</p>
                </div>
            ) : filteredInvoices.length === 0 ? (
                EmptySearch && <EmptySearch searchQuery={searchQuery} />
            ) : (
                <>
                    {/* A. PRIORITÉ (FACTURES NON TÉLÉCHARGÉES) */}
                    {attentionInvoices.length > 0 && (
                        <div className="mb-10 space-y-4 min-w-0 w-full">
                            <h2 className="text-lg font-black text-slate-800 flex items-center gap-2 border-b border-slate-200 pb-2 break-words">
                                <AlertTriangleIcon size={20} className="text-amber-500 shrink-0" /> Factures non téléchargées
                            </h2>
                            <CardGrid minWidth="300px">
                                {attentionInvoices.map((inv, i) => renderInvoiceCard(inv, `att_${i}`))}
                            </CardGrid>
                        </div>
                    )}

                    {/* B. FAVORIS */}
                    {pinnedInvoices.length > 0 && (
                        <div className="mb-10 space-y-4 min-w-0 w-full">
                            <h2 className="text-lg font-black text-slate-800 flex items-center gap-2 border-b border-slate-200 pb-2 break-words">
                                <PinIcon size={20} className="text-emerald-600 shrink-0" filled /> Favoris (Épinglés)
                            </h2>
                            <CardGrid minWidth="300px">
                                {pinnedInvoices.map((inv, i) => renderInvoiceCard(inv, `pin_${i}`))}
                            </CardGrid>
                        </div>
                    )}

                    {/* C. LE RESTE */}
                    {otherInvoices.length > 0 && (
                        <div className="space-y-4 min-w-0 w-full">
                            <h2 className="text-lg font-black text-slate-800 flex items-center gap-2 border-b border-slate-200 pb-2 break-words">
                                <FileTextIcon size={20} className="text-blue-600 shrink-0" /> Historique complet
                            </h2>
                            <CardGrid minWidth="300px">
                                {displayedOtherInvoices.slice(0, visibleCount).map((inv, i) => renderInvoiceCard(inv, `oth_${i}`))}
                            </CardGrid>

                            {PaginationFooter && (
                                <PaginationFooter 
                                    visibleCount={visibleCount} 
                                    setVisibleCount={setVisibleCount} 
                                    totalCount={otherInvoices.length} 
                                    itemName="factures" 
                                />
                            )}

                            {hasMoreInvoices && visibleCount >= otherInvoices.length && (
                                <div className="flex justify-center mt-4 mb-8 min-w-0">
                                    <Button variant="outline" icon={isLoadingMore ? LoaderIcon : DownloadIcon} onClick={handleLoadMoreInvoices} disabled={isLoadingMore} className="bg-white shadow-sm py-3 px-6 text-center">
                                        {isLoadingMore ? "Chargement..." : "Charger les factures plus anciennes"}
                                    </Button>
                                </div>
                            )}
                        </div>
                    )}
                </>
            )}

            {/* Modales contextuelles */}
            {routerActiveDialog === 'archive_config' && archiveConfig && ArchiveGeneratorModal && (
                <ArchiveGeneratorModal 
                    type={archiveConfig.type}
                    panelId={archiveConfig.panelId}
                    onClose={routerCloseLayer} 
                    refreshData={refreshData} 
                />
            )}

            {routerActiveDialog === 'refund' && refundTarget && Modal && (
                <Modal 
                    title={`Avoir et remboursement`} 
                    subTitle={`Réf. ${refundTarget.invoice.invoice_ref || refundTarget.invoice.invoiceNumber}`}
                    onClose={routerCloseLayer} 
                    preventClose={isSaving} 
                    actions={(close) => (
                        <>
                            <Button variant="secondary" type="button" onClick={close} disabled={isSaving} className="flex-1 py-3 justify-center text-xs">Annuler</Button>
                            <Button type="submit" form="refund-form" variant="primary" disabled={isSaving} icon={isSaving ? LoaderIcon : CheckCircleIcon} className="flex-[2] py-3 uppercase tracking-widest justify-center shadow-md text-xs">
                                Confirmer
                            </Button>
                        </>
                    )}
                >
                    <form id="refund-form" onSubmit={handleRefund} className="space-y-4 min-w-0">
                        <div className="text-xs text-slate-500 mb-2"><span className="text-red-500 font-black">*</span> Champs obligatoires</div>
                        <div className="bg-red-50 text-red-800 p-4 rounded-xl border border-red-100 text-sm mb-4 min-w-0">
                            <strong className="break-words">Règle stricte :</strong> Aucun remboursement n'est jamais accepté sauf en cas d'erreur de facturation.
                        </div>
                        <div className="bg-orange-50 text-orange-800 p-4 rounded-xl border border-orange-100 text-sm min-w-0">
                            <strong className="break-words leading-tight">Facture initiale : {refundTarget.invoice.amount} € ({refundTarget.clientName})</strong><br/>
                            
                            {parseFloat(refundTarget.invoice.amount) > refundTarget.maxRefundable && (
                                <span className="text-red-600 font-bold block mt-2 mb-2 p-2 bg-red-50 rounded-lg border border-red-200 break-words leading-tight">
                                    Attention : Des avoirs partiels ont déjà été émis pour cette facture.<br/>
                                    Reste remboursable : {refundTarget.maxRefundable} €
                                </span>
                            )}
                            
                            <p className="mt-2 break-words leading-relaxed">Générez une facture d'avoir (partielle ou totale) pour annuler comptablement cette transaction.</p>
                        </div>
                        
                        {FormInput && <FormInput label="Montant de l'avoir (€)" type="number" step="0.01" min="0.01" max={refundTarget.maxRefundable} defaultValue={refundTarget.maxRefundable} name="amount" required className="min-w-0" />}
                        
                        <div className="min-w-0">
                            <label className="block text-xs font-bold text-slate-500 uppercase mb-1 break-words">Méthode de restitution <span className="text-red-500">*</span></label>
                            <select name="mode" className="w-full border-2 border-slate-200 rounded-xl p-3 text-sm outline-none focus:border-orange-500 font-bold text-slate-700 bg-white min-w-0">
                                <option value="wallet">Crédit sur le site (avoir déduit des prochains achats)</option>
                                <option value="manual">Remboursement direct (manuel via le tableau de bord Stripe)</option>
                            </select>
                        </div>
                        
                        {FormInput && <FormInput label="Motif de l'annulation (visible sur l'avoir)" type="text" name="reason" required defaultValue="Erreur de facturation" className="min-w-0" />}
                    </form>
                </Modal>
            )}

            {routerActiveDialog === 'invoice_details' && targetInvoice && Modal && (
                <Modal 
                    title={`Détails facture - ${targetInvoice.invoice_ref || targetInvoice.invoiceNumber}`} 
                    onClose={routerCloseLayer} 
                    actions={(close) => (
                        <Button variant="primary" icon={DownloadIcon} onClick={() => { handleDownload(targetInvoice.invoice_ref || targetInvoice.invoiceNumber); close(); }} className="w-full py-3 uppercase tracking-widest justify-center shadow-md text-xs">
                            Télécharger le PDF
                        </Button>
                    )}
                >
                    <div className="space-y-4 min-w-0 overflow-x-hidden">
                        <div className="bg-slate-50 p-4 rounded-xl border border-slate-200 min-w-0">
                            <div className="grid grid-cols-2 gap-4 min-w-0">
                                <div className="min-w-0">
                                    <p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest break-words">Date d'émission</p>
                                    <p className="text-sm font-black text-slate-700 mt-1 break-words leading-tight">{window.pano_formatDate ? window.pano_formatDate(targetInvoice.created_at) : targetInvoice.created_at}</p>
                                </div>
                                <div className="min-w-0">
                                    <p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest break-words">Montant TTC</p>
                                    <p className={`text-sm font-black mt-1 break-words leading-tight ${targetInvoice.type.includes('Avoir') || parseFloat(targetInvoice.amount) < 0 ? 'text-amber-600' : 'text-slate-800'}`}>{targetInvoice.amount} €</p>
                                </div>
                                
                                {targetInvoice.panneauName && (
                                    <div className="col-span-2 min-w-0">
                                        <p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest break-words">Projet concerné</p>
                                        <p className="text-sm font-bold text-emerald-700 mt-1 break-words leading-tight">{targetInvoice.panneauName}</p>
                                    </div>
                                )}

                                <div className="col-span-2 min-w-0">
                                    <p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest break-words">Objet / Description</p>
                                    <p className="text-xs text-slate-600 mt-1 break-words leading-relaxed">{targetInvoice.type.replace(/\s*\(PI:[^)]+\)/, '')}</p>
                                </div>
                            </div>
                        </div>
                        
                        <div className="bg-blue-50 p-4 rounded-xl border border-blue-200 text-sm text-blue-800 font-medium min-w-0">
                            <p className="break-words leading-relaxed">
                                En cas de question sur cette facturation, vous pouvez contacter le support en ouvrant une conversation.
                            </p>
                        </div>
                    </div>
                </Modal>
            )}

            {previewConfig && UniversalViewer && (
                <UniversalViewer 
                    fileUrl={previewConfig.url}
                    fileType="pdf"
                    fileName={previewConfig.name}
                    positionClass="fixed"
                    useSafePdfMode={false}
                    onClose={() => setPreviewConfig(null)}
                />
            )}
        </div>
    );
};

/* EOF ========== [_react/admin/_admin_factures.jsx] */