import { useState, useEffect, useRef, useCallback, useMemo } from 'react';
import { useAuth } from '../context/AuthContext';
import { RoleSwitcherSidebar } from '../components/RoleSwitcher';
import { ThemeToggleButton } from '../context/ThemeContext';
import NouvelleNote from './NouvelleNote';
import VerificateurFinanceLight from './VerificateurFinanceLight'; 
import NDFChatbot from './NdfChatbot';
import PresidentValidation from './PresidentValidation';
import QRCode from 'react-qr-code';



import {
    LayoutDashboard, PlusCircle, FileText, CheckSquare, History,
    CreditCard, User, LogOut, Receipt, Upload, Send,
    ClipboardList, ShieldCheck, Eye,
} from 'lucide-react';

const API = '';

// ── FORMATTERS ─────────────────────────────────────────
const fmt = (n: number) =>
    new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR' }).format(n || 0);

// ── HELPERS TVA ────────────────────────────────────────
function getHT(ttc: number, taux: number) {
    if (!taux) return ttc;
    return parseFloat((ttc / (1 + taux / 100)).toFixed(2));
}
function getMontantTVA(ttc: number, taux: number) {
    return parseFloat((ttc - getHT(ttc, taux)).toFixed(2));
}

// ── NORMALISATION STATUT ──────────────────────────────
const normalizeStatut = (s?: string) =>
    s?.trim().toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '') ?? '';
// ── Cache client pour les fichiers proxy (évite de re-télécharger) ──
const clientProxyCache = new Map<string, string>(); // url SP → objectURL blob

const proxyUrl = (url: string) => {
    if (!url) return url;
    // ✅ Évite le double encodage
    if (url.includes('/api/proxy-pdf')) return url;
    if (url.includes('sharepoint.com') || url.includes('.sharepoint.'))
        return `${API}/api/proxy-pdf?url=${encodeURIComponent(url)}`;
    return url;
};

// ── INTERFACES ─────────────────────────────────────────
interface Note {
    id: number;
    reference?: string;
    libelle?: string;
    categorie?: string;
    date?: string;
    montant?: number;
    statut?: string;
    collaborateur?: string;
    collaborateurEmail?: string;
    departement?: string;
    campus?: string;
    societe?: string;   
    justificatif?: string;
    sharepointUrl?: string;
    fichiers?: string;
    participants?: string;
    nombreParticipants?: number;
    validateurN1Id?: number;
    
    nomValidateurN1?: string;
 
    nomVerificateur?: string;
    datePaiement?: string;
    moisPaiement?: number;
    anneePaiement?: number;
    commentaireN1?: string;

    commentaireVerification?: string;
    dateVerification?: string;
    motifRefus?: string;
    montantHT?: number;
    tauxTVA?: number;
    km?: number;
    indemniteKm?: number;
    lignesJson?: string;
    montantTTC?: number;
    sharepointFiles?: { fileName: string; uploadUrl: string }[];
    description?: string;
    DateModification?: string;
    dateXml?: string;
}

interface HistoriquePaiement {
    id: number;
    reference: string;
    libelle: string;
    montant: number;
    datePaiement: string;
    collaborateur: string;
    campus?: string;
    societe?: string;
    date?: string;
    categorie?: string;
    lignesJson?: string;
    indemniteKm?: number;
    km?: number;
    statut?: string;
    banque?: string;
}
interface Profile {
    prenom?: string; nom?: string; email?: string;
    role?: string; departement?: string; campus?: string; poste?: string;
    TypeContrat?: string; DateEntree?: string; societe?: string;
    adresse_rue?: string; adresse_cp?: string;
    adresse_ville?: string; adresse_pays?: string;
}

interface Categorie {
    id: number;
    Nom: string;
    Detail?: string;
    Icone?: string;
    PlafondParPersonne?: number;
    DescriptionPlafond?: string;
}

interface TauxTVA {
    taux: number;
    libelle: string;
    categorie: string | null;
}

interface Notification {
    id: number;
    Type: string;
    Titre: string;
    Message: string;
    NoteDeFraisId?: number;
    Lu: boolean;
    DateCreation: string;
}

interface Participant {
    nom: string;
    prenom: string;
    societe?: string;
}

interface Exception {
    id: number;
    reference?: string;
    montant?: number;
    libelle?: string;
    collaborateur?: string;
    email?: string;
    Motif?: string;
    Statut?: string;
    DateDemande?: string;
}

interface PaiementConfig {
    JourPaiement: number;
}

interface HistoriqueValidation {
    id: number;
    reference: string;
    libelle: string;
    montant: number;
    categorie: string;
    collaborateur: string;
    departement?: string;
    campus?: string;
    Niveau: string;
    Action: string;
    Commentaire?: string;
    MotifRefus?: string;
    NouveauStatut: string;
    DateAction: string;
}

// ── LIGNE NOTE (multi-dépenses) ────────────────────────
interface LigneNote {
    idTemp: string;
    date: string;
    categorie: string;
    libelle: string;
    montant: string;
    tvaItems: { taux: string; montantTTC: string }[];
    tauxTVA?: string;
    km: string;
    chevaux: string;
    description: string;
    files: File[];
    participants: Participant[];
    nombreParticipants: string;
    qrLink: string | null;
    qrUploaded: boolean;
    qrNoteRef: string;
    qrFiles?: { fileName: string; uploadUrl: string }[]  // ← ajouter cette ligne
}

const newLigne = (date: string): LigneNote => ({
    idTemp: crypto.randomUUID(),
    date,
    categorie: '',
    libelle: '',
    montant: '',
    tvaItems: [{ taux: '', montantTTC: '' }],
    tauxTVA: '',
    km: '',
    chevaux: '7',
    description: '',
    files: [],
    participants: [{ nom: '', prenom: '', societe: '' }],
    nombreParticipants: '',
    qrLink: null,
    qrUploaded: false,
    qrNoteRef: '',
});

const BAREME_KM: Record<number, { t1: number; t2_a: number; t2_b: number; t3: number; label: string }> = {
    3: { t1: 0.529, t2_a: 0.316, t2_b: 1061, t3: 0.369, label: '3 CV et moins' },
    4: { t1: 0.606, t2_a: 0.340, t2_b: 1330, t3: 0.408, label: '4 CV' },
    5: { t1: 0.636, t2_a: 0.356, t2_b: 1391, t3: 0.427, label: '5 CV' },
    6: { t1: 0.665, t2_a: 0.374, t2_b: 1457, t3: 0.448, label: '6 CV' },
    7: { t1: 0.697, t2_a: 0.394, t2_b: 1512, t3: 0.470, label: '7 CV et plus' },
};

const BAREME_KM_DASHBOARD = [
    { cv: 3, label: "3 CV et moins", t1: 0.529 },
    { cv: 4, label: "4 CV", t1: 0.606 },
    { cv: 5, label: "5 CV", t1: 0.636 },
    { cv: 6, label: "6 CV", t1: 0.665 },
    { cv: 7, label: "7 CV et plus", t1: 0.697 },
];


function getIndemniteKm(kmTotal: number, chevaux: number | string): number {
    const cv = Math.min(Math.max(parseInt(String(chevaux)) || 7, 3), 7) as keyof typeof BAREME_KM;
    const b = BAREME_KM[cv];
    if (kmTotal <= 0) return 0;
    if (kmTotal <= 5000) return parseFloat((kmTotal * b.t1).toFixed(2));
    if (kmTotal <= 20000) return parseFloat((kmTotal * b.t2_a + b.t2_b).toFixed(2));
    return parseFloat((kmTotal * b.t3).toFixed(2));
}
// Ajoute cette fonction en haut du Dashboard
const normalizeCampus = (campus?: string): string => {
    if (!campus) return campus || '';
    const c = campus.toUpperCase();
    if (c.includes('SQY')) return 'SQY';
    if (c.includes('CGY') || c.includes('CERGY')) return 'CGY';
    if (c.includes('MRS') || c.includes('MARSEILLE')) return 'MRS';
    if (c.includes('NTE') || c.includes('NANTES')) return 'NTE';
    return campus;
};

// ── STYLES ─────────────────────────────────────────────
const inputStyle: React.CSSProperties = {
    width: '100%', padding: '10px 14px',
    border: '1.5px solid var(--border-input)', borderRadius: 8,
    background: 'var(--bg-input)', fontFamily: '"Inter","Segoe UI",sans-serif',
    fontSize: 14, color: 'var(--text-primary)', outline: 'none',
    boxSizing: 'border-box', transition: 'border-color 0.2s',
};

const inputSm: React.CSSProperties = {
    ...inputStyle,
    padding: '9px 12px',
    fontSize: 13,
    background: 'var(--bg-input-sm)',
};

const labelStyle: React.CSSProperties = {
    display: 'block', fontSize: 12, fontWeight: 700,
    color: 'var(--text-secondary)', textTransform: 'uppercase',
    letterSpacing: '0.6px', marginBottom: 6,
};

const labelSm: React.CSSProperties = {
    ...labelStyle,
    fontSize: 10,
    color: 'var(--text-muted)',
    marginBottom: 4,
};

const cardStyle: React.CSSProperties = {
    background: 'var(--bg-card)', borderRadius: 16,
    border: '1px solid var(--border-card)',
    boxShadow: 'var(--shadow-card)',
    overflow: 'hidden',
};

const btnPrimary: React.CSSProperties = {
    display: 'flex', alignItems: 'center', gap: 8,
    padding: '11px 22px',
    background: 'linear-gradient(135deg,#6366f1,#4f46e5)',
    color: '#fff', border: 'none', borderRadius: 10,
    cursor: 'pointer', fontFamily: '"Inter","Segoe UI",sans-serif',
    fontSize: 14, fontWeight: 600,
    boxShadow: '0 4px 14px rgba(99,102,241,.4)',
    whiteSpace: 'nowrap',
};

const btnSuccess: React.CSSProperties = {
    padding: '7px 16px', background: '#dcfce7', color: '#15803d',
    border: '1px solid #bbf7d0', borderRadius: 7, cursor: 'pointer',
    fontFamily: 'inherit', fontSize: 13, fontWeight: 600,
};

const btnDanger: React.CSSProperties = {
    padding: '7px 16px', background: '#fee2e2', color: '#dc2626',
    border: '1px solid #fecaca', borderRadius: 7, cursor: 'pointer',
    fontFamily: 'inherit', fontSize: 13, fontWeight: 600,
};

const btnPurple: React.CSSProperties = {
    padding: '8px 18px',
    background: 'linear-gradient(135deg,#7c3aed,#6d28d9)',
    color: '#fff', border: 'none', borderRadius: 8,
    cursor: 'pointer', fontFamily: 'inherit', fontSize: 13, fontWeight: 700,
    boxShadow: '0 4px 12px rgba(124,58,237,.3)',
};

// ── TAG STATUT ─────────────────────────────────────────
const tagStatut = (statut: string) => {
    const map: Record<string, { bg: string; color: string; label: string }> = {
        'enattente': { bg: '#fef9c3', color: '#a16207', label: 'En attente' },
        'en_attente': { bg: '#fef9c3', color: '#a16207', label: 'En attente' },
        'en attente': { bg: '#fef9c3', color: '#a16207', label: 'En attente' },
        'validn1': { bg: '#dbeafe', color: '#1d4ed8', label: 'Valide N1' },
        'validen1': { bg: '#dbeafe', color: '#1d4ed8', label: 'Valide N1' },
        'valide_n1': { bg: '#dbeafe', color: '#1d4ed8', label: 'Valide N1' },
       
        'approuve': { bg: '#dcfce7', color: '#15803d', label: 'Approuve' },
        'verifie': { bg: '#ede9fe', color: '#7c3aed', label: 'Vérifié' },
        'paiementenattente': { bg: '#fef9c3', color: '#b45309', label: 'Paiement en attente' },
        'paiement_en_attente': { bg: '#fef9c3', color: '#b45309', label: 'Paiement en attente' },
        'payee': { bg: '#f0fdf4', color: '#16a34a', label: 'Payee' },
        'refuse': { bg: '#fee2e2', color: '#dc2626', label: 'Refusee' },
        'refus': { bg: '#fee2e2', color: '#dc2626', label: 'Refusee' },
        'brouillon': { bg: '#f1f5f9', color: 'var(--text-secondary)', label: 'Brouillon' },
        'valide': { bg: '#dcfce7', color: '#15803d', label: 'Valide' },
        'non_conforme_verif': { bg: '#fff7ed', color: '#c2410c', label: 'Justificatif non conforme' },
        'refuse_verif': { bg: '#fee2e2', color: '#dc2626', label: 'Refusée par Finance' },
        'refuse_verif_archive': { bg: '#f1f5f9', color: '#64748b', label: 'Refusée Finance (archivée)' },
        'non_conforme_archive': { bg: '#f1f5f9', color: '#64748b', label: 'Non conforme (archivée)' },
        'refuse_archive': { bg: '#f1f5f9', color: '#64748b', label: 'Refusée (archivée)' },
    };
    
    const key = normalizeStatut(statut);
    const s = map[key] ?? map['brouillon'];
    return (
        <span style={{
            display: 'inline-block', fontSize: 11, fontWeight: 700,
            padding: '3px 10px', borderRadius: 20, whiteSpace: 'nowrap',
            background: s.bg, color: s.color
        }}>
            {s.label}
        </span>
    );
};

// ── STATUT STEPPER ─────────────────────────────────────
const StatutStepper = ({ statut }: { statut: string }) => {
    const s = normalizeStatut(statut);

    const steps = [
        { key: 'enattente', label: 'Soumise', icon: '📋' },
        { key: 'validen1', label: 'Validation', icon: '✅' },
        
        { key: 'approuve', label: 'Approuvée', icon: '🎉' },
        { key: 'verifie', label: 'Vérifiée', icon: '🔍' },
        { key: 'paiementenattente', label: 'En att. paiement', icon: '⏳' },
        { key: 'payee', label: 'Payée', icon: '💶' },
    ];

    const getActiveIndex = () => {
        if (s === 'refuse' || s === 'refus') return -1;
        if (s === 'refuse_verif') return -1;  // ✅ AJOUT
        if (s === 'payee') return 6;
        if (s === 'paiementenattente' || s === 'paiement_en_attente') return 5;
        if (s === 'verifie') return 4;
        if (s === 'approuve') return 3;
      
        if (['validen1', 'valide_n1', 'validn1'].includes(s)) return 1;
        if (s === 'non_conforme_verif') return -1;
        return 0;
    };

    const active = getActiveIndex();

    if (active === -1) {
        const isNonConforme = s === 'non_conforme_verif';
        const isRefuseVerif = s === 'refuse_verif';
        return (
            <div style={{
                display: 'flex', alignItems: 'center', gap: 10,
                padding: '10px 16px',
                background: isNonConforme ? '#fff7ed' : '#fef2f2',
                border: `1.5px solid ${isNonConforme ? '#fed7aa' : '#fecaca'}`,
                borderRadius: 12, marginBottom: 16,
            }}>
                <span style={{ fontSize: 18 }}>{isNonConforme ? '⚠️' : '❌'}</span>
                <div>
                    <div style={{ fontSize: 13, fontWeight: 700, color: isNonConforme ? '#c2410c' : '#dc2626' }}>
                        {isNonConforme
                            ? 'Justificatif non conforme — action requise'
                            : isRefuseVerif
                                ? 'Note refusée par la Finance — corrections requises'
                                : 'Note refusée'}
                    </div>
                    <div style={{ fontSize: 11, color: isNonConforme ? '#ea580c' : '#ef4444' }}>
                        {isNonConforme
                            ? 'Le vérificateur Finance a signalé un justificatif non conforme. Contactez votre responsable.'
                            : isRefuseVerif
                                ? 'Le vérificateur Finance a refusé certaines lignes. Corrigez-les puis resoumettez.'
                                : 'Consultez le motif de refus ci-dessous'}
                    </div>
                </div>
            </div>
        );
    }
    

    return (
        <div style={{
            padding: '14px 20px', background: 'var(--bg-card)',
            border: '1px solid var(--border-card)', borderRadius: 14,
            marginBottom: 16, overflowX: 'auto',
        }}>
            <div style={{ display: 'flex', alignItems: 'center', minWidth: 420 }}>
                {steps.map((step, i) => {
                    const isDone = i < active;
                    const isCurrent = i === active;
                    return (
                        <div key={step.key} style={{ display: 'flex', alignItems: 'center', flex: i < steps.length - 1 ? 1 : 0 }}>
                            <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6 }}>
                                <div style={{
                                    width: 34, height: 34, borderRadius: '50%',
                                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                                    fontSize: isCurrent ? 16 : 13,
                                    background: isDone ? '#dcfce7' : isCurrent ? 'linear-gradient(135deg,#6366f1,#4f46e5)' : 'var(--bg-input)',
                                    color: isDone ? '#15803d' : isCurrent ? '#fff' : 'var(--text-muted)',
                                    border: isCurrent ? '2px solid #4f46e5' : isDone ? '2px solid #86efac' : '2px solid var(--border-input)',
                                    boxShadow: isCurrent ? '0 0 0 4px rgba(99,102,241,0.15)' : 'none',
                                    flexShrink: 0, transition: 'all 0.3s',
                                }}>
                                    {isDone ? '✓' : step.icon}
                                </div>
                                <span style={{
                                    fontSize: 9, fontWeight: isCurrent ? 700 : 500,
                                    color: isDone ? '#15803d' : isCurrent ? '#4f46e5' : 'var(--text-muted)',
                                    whiteSpace: 'nowrap', textAlign: 'center',
                                }}>
                                    {step.label}
                                </span>
                            </div>
                            {i < steps.length - 1 && (
                                <div style={{
                                    flex: 1, height: 3, marginBottom: 22, marginLeft: 4, marginRight: 4,
                                    borderRadius: 99,
                                    background: i < active ? 'linear-gradient(90deg,#86efac,#4ade80)' : 'var(--border-input)',
                                    transition: 'background 0.3s',
                                }} />
                            )}
                        </div>
                    );
                })}
            </div>
        </div>
    );
};

// ── NOTES TABLE ────────────────────────────────────────
const NotesTable = ({ notes }: { notes: Note[] }) => {
    if (!notes.length) return (
        <div style={{ padding: '48px 24px', textAlign: 'center', color: 'var(--text-muted)' }}>
            <p style={{ fontSize: 14 }}>Aucune note de frais</p>
        </div>
    );

    const getJustificatifUrl = (note: Note) => {
        try {
            const isKmOnly = note.lignesJson
                ? JSON.parse(note.lignesJson || '[]').every((l: any) =>
                    (l.categorie || '').toLowerCase().includes('kilom') &&
                    parseFloat(l.montant || 0) === 0)
                : (note.km ?? 0) > 0 && parseFloat(String(note.montantTTC || 0)) === 0;
            if (isKmOnly) return 'KILOMETRIQUE';
        } catch { }

        let files: { fileName: string; uploadUrl: string }[] = note.sharepointFiles || [];
        if (!files.length && note.fichiers) {
            try { files = JSON.parse(note.fichiers); } catch { files = []; }
        }
        if (!Array.isArray(files)) files = [];

        const s = normalizeStatut(note.statut || '');

        // Priorité 1 : recap-paiement (note payée)
        if (s === 'payee') {
            const file = files.find(f => f.fileName.includes('recap-paiement'));
            if (file) return { url: file.uploadUrl, label: '💶 Récap paiement', color: '#15803d', bg: '#f0fdf4', border: '#86efac' };
        }

        // Priorité 2 : recap complet régénéré (_recap.pdf) — toutes étapes
        const recapFinal = files
            .filter(f => {
                const n = (f.fileName || '').toLowerCase();
                return n.includes('_recap.pdf') && !n.includes('recap-paiement');
            })
            .sort((a, b) => (b.fileName || '').localeCompare(a.fileName || '')) // le plus récent
        [0];

        if (recapFinal) {
            const label = s === 'verifie' ? '🔍 Récap vérifié'
                : ['approuve', 'paiementenattente', 'paiement_en_attente'].includes(s) ? '✅ Récap approuvé'
                    : ['validen1', 'valide_n1', 'validen2', 'valide_n2'].includes(s) ? '📋 Récap validé'
                        : '📋 Récap complet';
            const color = s === 'verifie' ? '#7c3aed'
                : ['approuve', 'paiementenattente', 'paiement_en_attente'].includes(s) ? '#059669'
                    : '#6366f1';
            const bg = s === 'verifie' ? '#ede9fe'
                : ['approuve', 'paiementenattente', 'paiement_en_attente'].includes(s) ? '#dcfce7'
                    : '#eef2ff';
            const border = s === 'verifie' ? '#c4b5fd'
                : ['approuve', 'paiementenattente', 'paiement_en_attente'].includes(s) ? '#6ee7b7'
                    : '#c7d2fe';
            return { url: recapFinal.uploadUrl, label, color, bg, border };
        }

        // Fallback : soumission si pas encore de recap régénéré
        const file = files.find(f => f.fileName.includes('resoumission'))
            || files.find(f => f.fileName.includes('soumission'));
        if (!file) return null;
        return { url: file.uploadUrl, label: '📋 Fiche soumission', color: '#6366f1', bg: '#eef2ff', border: '#c7d2fe' };
    };
    return (
        <div style={{ overflowX: 'auto' }}>
            <table style={{ width: '100%', borderCollapse: 'collapse', minWidth: 700 }}>
                <thead>
                    <tr style={{ background: 'var(--bg-thead)' }}>
                        {['Reference', 'Libelle', 'Categorie', 'Date', 'Montant TTC', 'Statut', 'Justificatif'].map(h => (
                            <th key={h} style={{
                                padding: '10px 16px', textAlign: 'left', fontSize: 11,
                                fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase',
                                letterSpacing: '0.6px', borderBottom: '1px solid var(--border-divider)'
                            }}>{h}</th>
                        ))}
                    </tr>
                </thead>
                <tbody>
                    {notes.map((n, i) => (
                        <tr key={i} style={{ borderTop: '1px solid var(--border-divider)' }}>
                            <td style={{ padding: '13px 16px', color: '#6366f1', fontWeight: 700, fontFamily: 'monospace', fontSize: 12 }}>
                                {n.reference || `#${n.id}`}
                            </td>
                            <td style={{ padding: '13px 16px', fontWeight: 600, fontSize: 13, color: 'var(--text-primary)' }}>
                                {n.libelle || '-'}
                                {n.km && <span style={{ marginLeft: 6, fontSize: 10, background: '#ede9fe', color: '#7c3aed', padding: '1px 6px', borderRadius: 4 }}>{n.km} km</span>}
                            </td>
                            <td style={{ padding: '13px 16px', fontSize: 13, color: 'var(--text-secondary)' }}>{n.categorie || '-'}</td>
                            <td style={{ padding: '13px 16px', fontSize: 12, color: 'var(--text-muted)' }}>
                                {n.date ? new Date(n.date).toLocaleDateString('fr-FR') : '-'}
                            </td>
                            <td style={{ padding: '13px 16px', fontWeight: 800, fontSize: 14, color: 'var(--text-primary)' }}>{fmt(n.montant || 0)}</td>
                            <td style={{ padding: '13px 16px' }}>{tagStatut(n.statut || 'brouillon')}</td>
                            <td style={{ padding: '13px 16px' }}>
                                {(() => {
                                    const result = getJustificatifUrl(n);
                                    if (result === 'KILOMETRIQUE') return (
                                        <span style={{ color: '#7c3aed', fontSize: 12, fontWeight: 600 }}>🚗 Kilométrique</span>
                                    );
                                    if (!result) return (
                                        <span style={{ color: '#cbd5e1', fontSize: 12 }}>—</span>
                                    );
                                    return (
                                        <a href={result.url} target="_blank" rel="noreferrer" style={{
                                            display: 'inline-flex', alignItems: 'center', gap: 4,
                                            padding: '4px 10px', background: result.bg,
                                            border: `1px solid ${result.border}`, borderRadius: 20,
                                            color: result.color, fontSize: 11, fontWeight: 700,
                                            textDecoration: 'none', whiteSpace: 'nowrap',
                                        }}>
                                            {result.label}
                                        </a>
                                    );
                                })()}
                            </td>
                        </tr>
                    ))}
                </tbody>
            </table>
        </div>
    );
};

const UrlPreviewPopup = ({ item, onClose }: { item: { url: string; name: string } | null; onClose: () => void }) => {
    const [blobUrl, setBlobUrl] = useState<string | null>(null);
    const [error, setError] = useState(false);

    useEffect(() => {
        if (!item) return;
        setBlobUrl(null);
        setError(false);

        // ✅ Vérifier le cache client d'abord
        if (clientProxyCache.has(item.url)) {
            setBlobUrl(clientProxyCache.get(item.url)!);
            return;
        }

        // Télécharger et mettre en cache
        fetch(item.url)
            .then(r => {
                if (!r.ok) throw new Error(`HTTP ${r.status}`);
                return r.blob();
            })
            .then(blob => {
                const url = URL.createObjectURL(blob);
                clientProxyCache.set(item.url, url);
                setBlobUrl(url);
            })
            .catch(() => setError(true));
    }, [item?.url]);

    if (!item) return null;
    const isPDF = /\.pdf$/i.test(item.name);
    const isImage = /\.(jpg|jpeg|png|gif|webp)$/i.test(item.name);

    return (
        <div onClick={onClose} style={{
            position: 'fixed', inset: 0, zIndex: 10000,
            background: 'rgba(0,0,0,0.8)', display: 'flex',
            alignItems: 'center', justifyContent: 'center', backdropFilter: 'blur(6px)'
        }}>
            <div onClick={e => e.stopPropagation()} style={{
                background: '#fff', borderRadius: 16,
                boxShadow: '0 32px 100px rgba(0,0,0,.5)',
                width: isPDF ? 860 : 'auto', maxWidth: '94vw', maxHeight: '94vh',
                display: 'flex', flexDirection: 'column', overflow: 'hidden'
            }}>
                {/* Header */}
                <div style={{
                    display: 'flex', alignItems: 'center', justifyContent: 'space-between',
                    padding: '14px 20px', background: 'linear-gradient(135deg,#6366f1,#4f46e5)', flexShrink: 0
                }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 10, minWidth: 0 }}>
                        <span style={{ fontSize: 20, flexShrink: 0 }}>{isPDF ? '📄' : isImage ? '🖼️' : '📎'}</span>
                        <div style={{ color: '#fff', fontWeight: 700, fontSize: 13, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                            {item.name}
                        </div>
                    </div>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexShrink: 0, marginLeft: 16 }}>
                        {blobUrl && (
                            <a href={blobUrl} download={item.name} style={{
                                padding: '6px 14px', background: 'rgba(255,255,255,0.2)',
                                border: '1px solid rgba(255,255,255,0.35)', borderRadius: 8,
                                color: '#fff', fontSize: 12, fontWeight: 600, textDecoration: 'none', whiteSpace: 'nowrap'
                            }}>⬇ Télécharger</a>
                        )}
                        <button onClick={onClose} style={{
                            background: 'rgba(255,255,255,0.2)', border: 'none', borderRadius: 8,
                            width: 36, height: 36, cursor: 'pointer', color: '#fff', fontSize: 20,
                            display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0
                        }}>✕</button>
                    </div>
                </div>

                {/* Corps */}
                <div style={{
                    flex: 1, overflow: 'auto', display: 'flex',
                    alignItems: 'center', justifyContent: 'center',
                    padding: isPDF ? 0 : 24, background: '#f1f5f9',
                    minHeight: 300, position: 'relative'
                }}>
                    <style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>

                    {/* Spinner */}
                    {!blobUrl && !error && (
                        <div style={{ textAlign: 'center', color: '#6b7280' }}>
                            <div style={{
                                width: 40, height: 40, border: '3px solid #e5e7eb',
                                borderTop: '3px solid #6366f1', borderRadius: '50%',
                                animation: 'spin 0.8s linear infinite', margin: '0 auto 12px'
                            }} />
                            <div style={{ fontSize: 13 }}>Chargement…</div>
                        </div>
                    )}

                    {/* Erreur */}
                    {error && (
                        <div style={{ textAlign: 'center', padding: 32 }}>
                            <div style={{ fontSize: 40, marginBottom: 12 }}>⚠️</div>
                            <div style={{ fontSize: 14, color: '#dc2626', fontWeight: 600 }}>
                                Impossible de charger le fichier
                            </div>
                            <a href={item.url} target="_blank" rel="noreferrer" style={{
                                display: 'inline-block', marginTop: 12, padding: '10px 20px',
                                background: '#6366f1', color: '#fff', borderRadius: 8,
                                textDecoration: 'none', fontSize: 13, fontWeight: 600
                            }}>Ouvrir directement →</a>
                        </div>
                    )}

                    {/* PDF via blob */}
                    {blobUrl && isPDF && (
                        <iframe
                            src={blobUrl}
                            style={{ width: '100%', height: '80vh', border: 'none' }}
                            title={item.name}
                        />
                    )}

                    {/* Image via blob */}
                    {blobUrl && isImage && (
                        <img
                            src={blobUrl}
                            alt={item.name}
                            style={{ maxWidth: '85vw', maxHeight: '78vh', objectFit: 'contain', borderRadius: 10 }}
                        />
                    )}

                    {/* Autre type */}
                    {blobUrl && !isPDF && !isImage && (
                        <div style={{ textAlign: 'center', padding: 48 }}>
                            <div style={{ fontSize: 56, marginBottom: 20 }}>📎</div>
                            <a href={blobUrl} download={item.name} style={{
                                padding: '12px 24px', background: 'linear-gradient(135deg,#6366f1,#4f46e5)',
                                color: '#fff', borderRadius: 10, textDecoration: 'none', fontWeight: 700, fontSize: 14
                            }}>Télécharger le fichier</a>
                        </div>
                    )}
                </div>
            </div>
        </div>
    );
};

// ── DETAIL LIGNES HELPER ───────────────────────────────
const LignesDetail = ({
    note,
    tarifKm,
    onPreview,
}: {
    note: Note;
    tarifKm: number;
    onPreview: (url: string, name: string) => void;
}) => {
    let lignesData: any[] = [];
    try { if (note.lignesJson) lignesData = JSON.parse(note.lignesJson); } catch { }
    if (!lignesData.length) return null;

    let fichiersTous: { fileName?: string; uploadUrl?: string }[] = [];
    if (note.sharepointFiles && note.sharepointFiles.length > 0) fichiersTous = note.sharepointFiles;
    else if (note.fichiers) { try { fichiersTous = JSON.parse(note.fichiers); } catch { } }

   const EXCLUS_SYSTEME = [
            '_soumission.pdf',
            '_resoumission.pdf', 
            '_recap.pdf',
            '-signe-approuve.pdf',
            '-signe-refuse.pdf',
            '-verifie.pdf',
            '-verifie-proratise.pdf',
            'recap-paiement.pdf',
        ];


    const totalNote = note.montant || 0;
    //const [previewLoading, setPreviewLoading] = useState<string | null>(null);

    // ── ÉTAPE 1 : résoudre les fichiers de chaque ligne ──────────────────
    const lignesResolues = lignesData.map((l: any) => {
        // APRÈS — les km peuvent avoir des justificatifs (facultatifs)
        const isKm = (l.categorie || '').toLowerCase().includes('kilom');

        // Ne pas ignorer les qrFiles même pour les km
      const fichiersKm: { fileName: string; uploadUrl: string }[] = (l.qrFiles || []).filter(
          (f: any) => !EXCLUS_SYSTEME.some(kw => (f.fileName || '').toLowerCase().endsWith(kw))
      );

        if (isKm) return { ...l, _resolvedFiles: fichiersKm };

        // Fichiers stockés directement dans qrFiles de la ligne
      const fichiersLigne: { fileName: string; uploadUrl: string }[] = (l.qrFiles || []).filter(
          (f: any) => !EXCLUS_SYSTEME.some(kw => (f.fileName || '').toLowerCase().endsWith(kw))
      );
        // Fichiers trouvés via qrNoteRef dans fichiersTous
        const qrRef: string = l.qrNoteRef || '';
        const fichiersQR = qrRef
            ? fichiersTous.filter(f =>
                !EXCLUS_SYSTEME.some(kw => (f.fileName || '').toLowerCase().includes(kw)) &&
                ((f.fileName && f.fileName.includes(qrRef)) ||
                    (f.uploadUrl && f.uploadUrl.includes(qrRef)))
            )
            : [];

        // Fusion sans doublons
        const tousFichiers = [
            ...fichiersLigne,
            ...fichiersQR.filter(fq => !fichiersLigne.some(fl => fl.uploadUrl === fq.uploadUrl)),
        ].filter((f, idx, arr) => arr.findIndex(x => x.uploadUrl === f.uploadUrl) === idx);

        return { ...l, _resolvedFiles: tousFichiers };
    });

    // ── ÉTAPE 2 : tous les fichiers non-système de la note ──
  const tousFichiersNonSysteme = fichiersTous.filter(f => {
      const n = (f.fileName || '').toLowerCase();
      return !EXCLUS_SYSTEME.some(kw => n.endsWith(kw));
  }).filter((f, idx, arr) => arr.findIndex(x => x.uploadUrl === f.uploadUrl) === idx);

    // Fichiers orphelins = non assignés à aucune ligne
    const urlsDejaAssignees = new Set(
        lignesResolues.flatMap((l: any) => (l._resolvedFiles || []).map((f: any) => f.uploadUrl))
    );

    const fichiersOrphelins = tousFichiersNonSysteme.filter(f =>
        !urlsDejaAssignees.has(f.uploadUrl)
    );

    // ── ÉTAPE 3 : distribuer aux lignes sans fichiers ──
    const indicesLignesSansFichiers = lignesResolues
        .map((l: any, i: number) => ({ l, i }))
        .filter(({ l }) =>
            !(l.categorie || '').toLowerCase().includes('kilom') &&
            l._resolvedFiles.length === 0
        )
        .map(({ i }) => i);

    const distributionOrphelins: Record<number, typeof tousFichiersNonSysteme> = {};

    if (indicesLignesSansFichiers.length > 0) {
        if (fichiersOrphelins.length > 0) {
            if (indicesLignesSansFichiers.length === 1) {
                // Une seule ligne sans fichier → tous les orphelins
                distributionOrphelins[indicesLignesSansFichiers[0]] = fichiersOrphelins;
            } else {
                // Plusieurs lignes sans fichier → 1 orphelin par ligne séquentiellement
                let pool = [...fichiersOrphelins];
                indicesLignesSansFichiers.forEach(idx => {
                    if (pool.length > 0) {
                        distributionOrphelins[idx] = [pool.shift()!];
                    }
                });
            }
        }
    }

    return (
        <div style={{ marginBottom: 20 }}>
            <div style={{
                display: 'flex', alignItems: 'center', gap: 10, marginBottom: 12,
                paddingBottom: 10, borderBottom: '2px solid var(--border-divider)',
            }}>
                <div style={{
                    width: 28, height: 28, borderRadius: 8,
                    background: 'linear-gradient(135deg,#6366f1,#4f46e5)',
                    display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
                }}>
                    <span style={{ fontSize: 13 }}>📋</span>
                </div>
                <div>
                    <div style={{ fontSize: 12, fontWeight: 800, color: 'var(--text-primary)', textTransform: 'uppercase', letterSpacing: '0.7px' }}>
                        Dépenses déclarées
                    </div>
                    <div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 1 }}>
                        {lignesData.length} dépense{lignesData.length > 1 ? 's' : ''} · total {fmt(totalNote)}
                    </div>
                </div>
            </div>

            <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                {lignesResolues.map((l: any, i: number) => {
                    const isKm = (l.categorie || '').toLowerCase().includes('kilom');
                    const isRepas = (l.categorie || '').toLowerCase().includes('repas');
                    const km = parseFloat(l.km) || 0;
                    const montant = isKm
                        ? parseFloat((km * tarifKm).toFixed(2))
                        : parseFloat(l.montant) || 0;
                    const taux = parseFloat(l.tauxTVA) || 0;
                    const ht = (!isKm && taux > 0) ? getHT(montant, taux) : null;
                    const tva = (!isKm && taux > 0) ? getMontantTVA(montant, taux) : null;

                    const accent = isKm ? '#7c3aed' : isRepas ? '#d97706' : '#6366f1';
                    const icone = isKm ? '🚗' : isRepas ? '🍽️' : '📋';

                    // ── Fichiers finaux pour cette ligne ──────────────────
                    const tousFichiers = [
                        ...(l._resolvedFiles || []),
                        ...(distributionOrphelins[i] || []),
                    ].filter((f, idx, arr) => arr.findIndex(x => x.uploadUrl === f.uploadUrl) === idx);

                    // ── Badge conformité ──────────────────────────────────
                    const nonConformes: any[] = (note as any).nonConformes || [];
                    const ncLigne = nonConformes.find((nc: any) =>
                        tousFichiers.some(f => f.fileName === nc.fileName) ||
                        (nc.ligneIndex !== undefined && nc.ligneIndex === i)
                    );
                    const conformiteStatut: 'ok' | 'nok' | 'pending' | 'km' =
                        isKm ? 'km' :
                            ncLigne ? 'nok' :
                                tousFichiers.length > 0 ? 'ok' :
                                    'pending';

                    const conformiteBadge = {
                        ok: { bg: '#dcfce7', color: '#15803d', label: '✅ Conforme', border: '#86efac' },
                        nok: { bg: '#fee2e2', color: '#dc2626', label: '❌ Non conforme', border: '#fca5a5' },
                        pending: { bg: '#fef3c7', color: '#b45309', label: '⚠️ Sans justif', border: '#fde68a' },
                        km: { bg: '#ede9fe', color: '#7c3aed', label: '🚗 Kilométrique', border: '#c4b5fd' },
                    }[conformiteStatut];

                    return (
                        <div key={i} style={{
                            border: `1.5px solid ${accent}33`,
                            borderLeft: `4px solid ${accent}`,
                            borderRadius: 10,
                            background: 'var(--bg-card)',
                            overflow: 'hidden',
                        }}>
                            <div style={{
                                display: 'flex', alignItems: 'center', justifyContent: 'space-between',
                                padding: '9px 14px',
                                background: `${accent}0d`,
                                borderBottom: `1px solid ${accent}22`,
                                flexWrap: 'wrap', gap: 8,
                            }}>
                                <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                                    <div style={{
                                        width: 22, height: 22, borderRadius: '50%',
                                        background: accent, color: '#fff',
                                        fontSize: 10, fontWeight: 800,
                                        display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
                                    }}>{i + 1}</div>
                                    <span style={{ fontSize: 12, fontWeight: 700, color: accent }}>
                                        {icone} {l.categorie || 'Dépense'}
                                    </span>
                                </div>
                                <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
                                    <span style={{
                                        fontSize: 10, fontWeight: 700,
                                        padding: '3px 9px', borderRadius: 20,
                                        background: conformiteBadge.bg,
                                        color: conformiteBadge.color,
                                        border: `1px solid ${conformiteBadge.border}`,
                                    }}>
                                        {conformiteBadge.label}
                                    </span>
                                    <span style={{ fontSize: 14, fontWeight: 900, color: accent }}>
                                        {fmt(montant)}
                                    </span>
                                </div>
                            </div>

                            <div style={{ padding: '10px 14px' }}>
                                {/* ── Ligne titre + date + boutons Voir ── */}
                                <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 6, gap: 8 }}>
                                    <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--text-primary)', flex: 1, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                                        {l.libelle || '—'}
                                    </div>
                                    <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexShrink: 0 }}>
                                        {/* Boutons Voir inline */}
                                        {tousFichiers.length > 0 && tousFichiers.map((f: any, fi: number) => {
                                            const isImage = /\.(jpg|jpeg|png|gif|webp)$/i.test(f.fileName || '');
                                            const isPdf = /\.pdf$/i.test(f.fileName || '');
                                            return (
                                                <button
                                                    key={fi}
                                                    onClick={() => {
                                                        const url = f.uploadUrl || '';
                                                        const proxied = url.includes('sharepoint') || url.includes('.sharepoint.') 
                                                            ? proxyUrl(url) 
                                                            : url;
                                                        onPreview(proxied, f.fileName || `Fichier ${fi + 1}`);
                                                    }}
                                                 
                                                    title={f.fileName || `Justificatif ${fi + 1}`}
                                                    style={{
                                                        display: 'inline-flex', alignItems: 'center', gap: 4,
                                                        padding: '4px 10px', background: accent,
                                                        border: 'none', borderRadius: 20,
                                                        cursor: 'pointer', fontFamily: 'inherit',
                                                        fontSize: 11, fontWeight: 700, color: '#fff',
                                                        transition: 'opacity 0.15s', flexShrink: 0,
                                                    }}
                                                >
                                                    {isImage ? '🖼️' : isPdf ? '📄' : '📎'} Voir
                                                </button>
                                            );
                                        })}
                                        <div style={{ fontSize: 11, color: 'var(--text-muted)', whiteSpace: 'nowrap' }}>
                                            {l.date ? new Date(l.date).toLocaleDateString('fr-FR') : '—'}
                                        </div>
                                    </div>
                                </div>

                                <div style={{ display: 'flex', flexWrap: 'wrap', gap: 5, marginBottom: 8 }}>
                                    {/* badges TVA etc — inchangés */}
                                </div>

                                {/* ── Nuits hébergement ── */}
                                {(l.categorie || '').toLowerCase().includes('hebergement') && l.nuits && parseInt(l.nuits) > 0 && (() => {
                                    const montant = parseFloat(l.montant) || 0;
                                    const nuits = parseInt(l.nuits);
                                    const parNuit = nuits > 0 && montant > 0 ? montant / nuits : 0;
                                    return (
                                        <div style={{
                                            display: 'inline-flex', alignItems: 'center', gap: 8,
                                            background: '#ede9fe', border: '1px solid #c4b5fd',
                                            borderRadius: 8, padding: '5px 12px', marginBottom: 8,
                                            fontSize: 12, color: '#7c3aed', fontWeight: 700,
                                        }}>
                                            🌙 {nuits} nuit{nuits > 1 ? 's' : ''}
                                            {parNuit > 0 && (
                                                <span style={{ fontWeight: 400, color: '#6d28d9', fontSize: 11 }}>
                                                    · {new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR' }).format(parNuit)}/nuit
                                                </span>
                                            )}
                                        </div>
                                    );
                                })()}

                                {l.description && (
                                    <div style={{ fontSize: 11, color: 'var(--text-muted)', fontStyle: 'italic', marginBottom: 8 }}>
                                        💬 {l.description}
                                    </div>
                                )}

                                {ncLigne && (
                                    <div style={{
                                        fontSize: 11, color: '#dc2626', fontWeight: 600,
                                        background: '#fef2f2', border: '1px solid #fecaca',
                                        borderRadius: 6, padding: '6px 10px', marginBottom: 8,
                                    }}>
                                        ⚠️ Non conforme : {ncLigne.motif}
                                    </div>
                                )}

                                {isKm && tousFichiers.length === 0 && (
                                    <div style={{
                                        display: 'flex', alignItems: 'center', gap: 8,
                                        padding: '8px 12px',
                                        background: '#ede9fe', border: '1px solid #c4b5fd',
                                        borderRadius: 8, fontSize: 11, color: '#7c3aed', fontWeight: 600,
                                    }}>
                                        🚗 Aucun justificatif requis pour les frais kilométriques
                                    </div>
                                )}

                                {/* Message sans justif — seulement si pas km et pas de fichiers */}
                                {!isKm && tousFichiers.length === 0 && (
                                    <div style={{
                                        display: 'flex', alignItems: 'center', gap: 8,
                                        padding: '8px 12px',
                                        background: '#fef2f2', border: '1px dashed #fca5a5',
                                        borderRadius: 8, fontSize: 11, color: '#dc2626', fontWeight: 600,
                                    }}>
                                        ⚠️ Aucun justificatif joint pour cette dépense
                                    </div>
                                )}
                            </div>
                        </div>
                    );
                })}
            </div>

            {lignesData.length > 1 && (
                <div style={{
                    marginTop: 10, padding: '11px 16px',
                    background: 'linear-gradient(90deg,#eef2ff,#f0fdf4)',
                    border: '1px solid #c7d2fe', borderRadius: 10,
                    display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                }}>
                    <span style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-secondary)', textTransform: 'uppercase', letterSpacing: '0.5px' }}>
                        Total — {lignesData.length} dépenses
                    </span>
                    <span style={{ fontSize: 16, fontWeight: 900, color: 'var(--text-primary)' }}>
                        {fmt(totalNote)}
                    </span>
                </div>
            )}
        </div>
    );
};


// ══════════════════════════════════════════════════════════════════════════════
// COMPOSANT 2 : FichiersGlobaux
// Affiche UNIQUEMENT les documents officiels :
//   - En attente / Validé N1/N2 → fiche de soumission
//   - Approuvé / Payé           → PDF signé approuvé
// ══════════════════════════════════════════════════════════════════════════════
const FichiersGlobaux = ({
    note,
    onPreview,
    proxyFn,
}: {
    note: Note;
    onPreview: (url: string, name: string) => void;
    proxyFn: (url: string) => string;
}) => {
    // Récupérer tous les fichiers
    let fichiers: { fileName?: string; uploadUrl?: string }[] = [];
    if (note.sharepointFiles && note.sharepointFiles.length > 0) fichiers = note.sharepointFiles;
    else if (note.fichiers) { try { fichiers = JSON.parse(note.fichiers); } catch { } }
    if (!fichiers.length && note.sharepointUrl) {
        fichiers = [{ fileName: 'Justificatif', uploadUrl: note.sharepointUrl }];
    }

    const statut = (note.statut || '').trim().toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '');
    const isApprouve = ['approuve', 'verifie', 'paiementenattente', 'paiement_en_attente', 'payee'].includes(statut);

    // Sélection du document officiel selon l'état
    // Approuvé/Payé → chercher le PDF signé approuvé ou le récap paiement
    // Soumis/En attente → chercher la fiche de soumission ou le récap
  const trouverFichierOfficiel = () => {
            if (isApprouve) {
                const n = (f: any) => (f.fileName || '').toLowerCase();
                return (
                    fichiers.find(f => n(f).includes('recap-paiement')) ||
                    fichiers.find(f => n(f).endsWith('-verifie-proratise.pdf')) ||
                    fichiers.find(f => n(f).endsWith('-signe-approuve.pdf')) ||
                    fichiers.find(f => n(f).endsWith('-signeapprouve.pdf')) ||
                    fichiers.find(f => n(f).endsWith('-signe_approuve.pdf')) ||
                    fichiers.find(f => n(f).endsWith('_recap.pdf') && !n(f).includes('recap-paiement')) ||
                    null
                );
            } else {
                return null;
            }
        };

    const fichierOfficiel = trouverFichierOfficiel();

    // Libellés contextuels selon le statut
    const getLabelOfficiel = () => {
        // ✅ Détecter si c'est un PDF proratisé
        const estProratise = fichierOfficiel && 
            (fichierOfficiel.fileName || '').toLowerCase().includes('verifie-proratise');

        if (['payee'].includes(statut)) return { 
            icon: '💶', label: 'Récap de paiement', 
            desc: 'Document officiel — note payée', 
            accent: '#15803d', bg: '#f0fdf4', border: '#86efac' 
        };
        if (estProratise) return { 
            icon: '✂️', label: 'PDF vérifié — montant ajusté', 
            desc: 'Certains repas ont été plafonnés à 25€/pers. par la Finance', 
            accent: '#d97706', bg: '#fffbeb', border: '#fde68a' 
        };
        if (['approuve', 'verifie', 'paiementenattente', 'paiement_en_attente'].includes(statut)) return { 
            icon: '✅', label: 'PDF approuvé', 
            desc: 'Signé par le validateur', 
            accent: '#7c3aed', bg: '#ede9fe', border: '#c4b5fd' 
        };
        return { 
            icon: '📋', label: 'Fiche de soumission', 
            desc: 'Récapitulatif soumis pour validation', 
            accent: '#6366f1', bg: '#eef2ff', border: '#c7d2fe' 
        };
    };

    const infoOfficiel = getLabelOfficiel();

    // Vérifier si c'est kilométrique pur (aucun fichier attendu)
    let lignesData: any[] = [];
    try { if (note.lignesJson) lignesData = JSON.parse(note.lignesJson); } catch { }
    const isKmPur = lignesData.length > 0
        ? lignesData.every((l: any) => (l.categorie || '').toLowerCase().includes('kilom'))
        : (note.km ?? 0) > 0 && parseFloat(String(note.montantTTC || 0)) === 0;

    return (
        <div style={{ marginBottom: 20 }}>
            {/* ── En-tête section ── */}
            <div style={{
                display: 'flex', alignItems: 'center', gap: 10, marginBottom: 12,
                paddingBottom: 10, borderBottom: '2px solid var(--border-divider)',
            }}>
                <div style={{
                    width: 28, height: 28, borderRadius: 8,
                    background: isApprouve
                        ? 'linear-gradient(135deg,#10b981,#059669)'
                        : 'linear-gradient(135deg,#6366f1,#4f46e5)',
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                    flexShrink: 0,
                }}>
                    <span style={{ fontSize: 13 }}>{isApprouve ? '✅' : '📎'}</span>
                </div>
                <div>
                    <div style={{ fontSize: 12, fontWeight: 800, color: 'var(--text-primary)', textTransform: 'uppercase', letterSpacing: '0.7px' }}>
                        Document officiel
                    </div>
                    <div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 1 }}>
                        {isApprouve ? 'Récapitulatif validé par la hiérarchie' : 'Fiche récapitulative de soumission'}
                    </div>
                </div>
            </div>

            {/* ── Fichier officiel ── */}
            {fichierOfficiel ? (
                <button
                    onClick={() => onPreview(proxyFn(fichierOfficiel.uploadUrl!), fichierOfficiel.fileName || 'Document officiel')}
                    onMouseEnter={() => {
                        const proxied = proxyFn(fichierOfficiel.uploadUrl!);
                        if (!clientProxyCache.has(proxied)) {
                            fetch(proxied).then(r => r.blob()).then(blob => {
                                clientProxyCache.set(proxied, URL.createObjectURL(blob));
                            }).catch(() => { });
                        }
                    }}
                    style={{
                        display: 'flex', alignItems: 'center', gap: 12,
                        padding: '14px 16px', width: '100%',
                        background: infoOfficiel.bg,
                        border: `1.5px solid ${infoOfficiel.border}`,
                        borderRadius: 10, cursor: 'pointer',
                        fontFamily: 'inherit', textAlign: 'left',
                        transition: 'all 0.15s',
                    }}
                   
                    onMouseLeave={e => (e.currentTarget.style.transform = 'none')}
                >
                    {/* Icône */}
                    <div style={{
                        width: 40, height: 40, borderRadius: 10,
                        background: infoOfficiel.accent, flexShrink: 0,
                        display: 'flex', alignItems: 'center', justifyContent: 'center',
                        fontSize: 18,
                    }}>
                        {infoOfficiel.icon}
                    </div>

                    {/* Texte */}
                    <div style={{ flex: 1, minWidth: 0 }}>
                        <div style={{ fontSize: 13, fontWeight: 700, color: infoOfficiel.accent }}>
                            {infoOfficiel.label}
                        </div>
                        <div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 2 }}>
                            {infoOfficiel.desc}
                        </div>
                        <div style={{
                            fontSize: 10, color: infoOfficiel.accent, marginTop: 3,
                            overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                        }}>
                            {fichierOfficiel.fileName}
                        </div>
                    </div>

                    {/* Bouton voir */}
                    <span style={{
                        fontSize: 11, fontWeight: 700, color: '#fff',
                        background: infoOfficiel.accent,
                        padding: '6px 14px', borderRadius: 20, flexShrink: 0,
                    }}>
                        👁 Voir
                    </span>
                </button>
            ) : isKmPur ? (
                <div style={{
                    display: 'flex', alignItems: 'center', gap: 10, padding: '12px 16px',
                    background: '#ede9fe', border: '1px solid #c4b5fd', borderRadius: 10,
                    fontSize: 12, color: '#7c3aed', fontWeight: 600,
                }}>
                    🚗 Note kilométrique — aucun justificatif global requis
                </div>
            ) : null}
        </div>
    );
};

const InlinePreviewViewer = ({ item }: { item: { url: string; name: string } }) => {
    const [blobUrl, setBlobUrl] = useState<string | null>(
        clientProxyCache.get(item.url) || null
    );

    useEffect(() => {
        if (clientProxyCache.has(item.url)) {
            setBlobUrl(clientProxyCache.get(item.url)!);
            return;
        }
        // ✅ Utilise item.url directement (après redirection ou cache CDN)
        fetch(item.url)
            .then(r => {
                if (!r.ok) throw new Error(`HTTP ${r.status}`);
                return r.blob();
            })
            .then(blob => {
                const url = URL.createObjectURL(blob);
                clientProxyCache.set(item.url, url);
                setBlobUrl(url);
            })
            .catch(() => { });
    }, [item.url]);

    const isPDF = /\.pdf$/i.test(item.name);
    const isImage = /\.(jpg|jpeg|png|gif|webp)$/i.test(item.name);

    if (!blobUrl) return (
        <div style={{ textAlign: 'center', color: 'var(--text-muted)' }}>
            <div style={{ width: 32, height: 32, border: '3px solid #e5e7eb', borderTop: '3px solid #6366f1', borderRadius: '50%', animation: 'spin 0.8s linear infinite', margin: '0 auto 10px' }} />
            <div style={{ fontSize: 12 }}>Chargement...</div>
        </div>
    );
    if (isPDF) return <iframe src={blobUrl} style={{ width: '100%', height: '100%', border: 'none' }} title={item.name} />;
    if (isImage) return <img src={blobUrl} alt={item.name} style={{ maxWidth: '100%', maxHeight: '100%', objectFit: 'contain', padding: 12 }} />;
    return (
        <div style={{ textAlign: 'center', color: 'var(--text-muted)', padding: 24 }}>
            <div style={{ fontSize: 32, marginBottom: 8 }}>📎</div>
            <a href={blobUrl} download={item.name} style={{ padding: '8px 16px', background: '#6366f1', color: '#fff', borderRadius: 8, textDecoration: 'none', fontSize: 12, fontWeight: 600 }}>Télécharger</a>
        </div>
    );
};

// ══════════════════════════════════════════════════════
// MAIN COMPONENT
// ══════════════════════════════════════════════════════
const Dashboard = (): JSX.Element => {
    const { user, logout, isValidateur, isFinance, isSuperUser, isVerificateurFinance, isValidateurFinance } = useAuth();
    const isPresident = user?.roles?.includes('President') ?? false;

    // ── Rôles nouveaux ──────────────────────────────────
  
    const canValidate = isValidateur;
    const isRHAdmin = isFinance;
       
    const [section, setSection] = useState('accueil');
    const [notes, setNotes] = useState<Note[]>([]);
    const [pending, setPending] = useState<Note[]>([]);
    const [profile, setProfile] = useState<Profile | null>(null);
    const [inlinePreview, setInlinePreview] = useState<{ url: string; name: string } | null>(null);
    const [notesEnAttentePresident, setNotesEnAttentePresident] = useState<Note[]>([]);
  
    const [adresseForm, setAdresseForm] = useState({
        adresse_rue: '', adresse_cp: '', adresse_ville: '', adresse_pays: 'France', societe: ''
    });
    const [ancienneNoteComparaison, setAncienneNoteComparaison] = useState<Note | null>(null);

    const [vehicule, setVehicule] = useState<{
        chevaux: number;
        marque: string;
        modele: string;
        immatriculation: string;
    } | null>(null);
    const [vehiculeEditing, setVehiculeEditing] = useState(false);
    const [vehiculeForm, setVehiculeForm] = useState({
        chevaux: 5, marque: "", modele: "", immatriculation: ""
    });
    const [vehiculeSaving, setVehiculeSaving] = useState(false);
    const [vehiculeError, setVehiculeError] = useState("");



    const [filtresDisponibles, setFiltresDisponibles] = useState<{
        campus: string[];
        societes: string[];
        societeParCampus: Record<string, string[]>;  // ← ajouter
    }>({ campus: [], societes: [], societeParCampus: {} });
    const [paiementFiltreCampus, setPaiementFiltreCampus] = useState('');
    const [paiementFiltreSociete, setPaiementFiltreSociete] = useState('');
    const [historiqueFiltreCampus, setHistoriqueFiltreCampus] = useState('');
    const [historiqueFiltreSociete, setHistoriqueFiltreSociete] = useState('');
    const [adresseEditing, setAdresseEditing] = useState(false);
    const [adresseSaving, setAdresseSaving] = useState(false);
    const [adresseError, setAdresseError] = useState('');
    const [historiqueGroupeParXml, setHistoriqueGroupeParXml] = useState(true);
    const [xmlHistorique, setXmlHistorique] = useState<any[]>([]);
    const [xmlFiltreAnnee, setXmlFiltreAnnee] = useState('');
    const [xmlFiltreMois, setXmlFiltreMois] = useState('');
    const [xmlLoading, setXmlLoading] = useState(false);
    const [xmlRegenLoading, setXmlRegenLoading] = useState<string | null>(null);



    type DocStatut = 'en_attente' | 'valide' | 'refuse' | 'absent';
    type DocInfo = { fileName: string; sharepointUrl: string; updatedAt: string; statut: DocStatut; commentaire?: string | null } | null;
    const [profilDocs, setProfilDocs] = useState<{ rib: DocInfo; carte_grise: DocInfo; permis: DocInfo }>({ rib: null, carte_grise: null, permis: null });
    const [ibanData, setIbanData] = useState<{ iban: string | null; ibanSaisi: boolean; bic: string | null } | null>(null);
    const [ibanForm, setIbanForm] = useState({ iban: '', bic: '' });
    const [ibanEditing, setIbanEditing] = useState(false);
    const [ibanSaving, setIbanSaving] = useState(false);
    const [ibanError, setIbanError] = useState('');
    const [profilDocsLoading, setProfilDocsLoading] = useState(false);
    const [profilDocsUploading, setProfilDocsUploading] = useState<string | null>(null);
    const [docsAValider, setDocsAValider] = useState<any[]>([]);
    const [docsAValiderLoading, setDocsAValiderLoading] = useState(false);

    // ── Etats nouveaux rôles ────────────────────────────
    const [notesAVerifier, setNotesAVerifier] = useState<Note[]>([]);
    const [notesVerifiees, setNotesVerifiees] = useState<Note[]>([]);

    const [categories, setCategories] = useState<Categorie[]>([]);
    const [tauxTVADisponibles, setTauxTVADisponibles] = useState<TauxTVA[]>([]);
    const [notifications, setNotifications] = useState<Notification[]>([]);
    const [historiqueNotes, setHistoriqueNotes] = useState<Note[]>([]);
    const [exceptions, setExceptions] = useState<Exception[]>([]);
    const [prochain, setProchain] = useState<{ datePaiement: string; libelle: string; jourPaiement: number } | null>(null);
    const [paiementConfig, setPaiementConfig] = useState<PaiementConfig>({ JourPaiement: 20 });
    const [tarifKm, setTarifKm] = useState<number>(0.697);
    const [previewUrl, setPreviewUrl] = useState<{ url: string; name: string } | null>(null);

    const [loading, setLoading] = useState(false);
    const [notesLoaded, setNotesLoaded] = useState(false);
    const [toast, setToast] = useState<{ msg: string; type: string } | null>(null);
    const [notifOpen, setNotifOpen] = useState(false);
    const [sidebarOpen, setSidebarOpen] = useState(true);

    const [modalValidation, setModalValidation] = useState<{
        noteId: number;
        action: 'valider' | 'refuser';
        onClose: () => void;
    } | null>(null);
    const [motifRefusInput, setMotifRefusInput] = useState('');
    const [validationLoading, setValidationLoading] = useState(false);

    const today = new Date().toISOString().split('T')[0];

    // ── Brouillons ──────────────────────────────────────
    const [activeBrouillonId, setActiveBrouillonId] = useState<number | string>(() => {
        try { return localStorage.getItem('ndf_brouillon_active') || ''; } catch { return ''; }
    });
    const activeBrouillonIdRef = useRef<number | string>('');
    useEffect(() => { activeBrouillonIdRef.current = activeBrouillonId; }, [activeBrouillonId]);

    const _initBrouillon = (() => {
        try {
            const list = JSON.parse(localStorage.getItem('ndf_brouillons') || '[]');
            const activeId = localStorage.getItem('ndf_brouillon_active') || '';
            return list.find((b: any) => b.id === activeId) || null;
        } catch { return null; }
    })();

    const [libelle, setLibelle] = useState<string>(_initBrouillon?.libelle || '');
    const [date, setDate] = useState<string>(_initBrouillon?.date || today);
    const [description, setDescription] = useState<string>(_initBrouillon?.description || '');
    const [files, setFiles] = useState<File[]>([]);
    const [lignes, setLignes] = useState<LigneNote[]>(
        _initBrouillon?.lignes?.length
            ? _initBrouillon.lignes.map((l: LigneNote) => ({ ...l, files: [] }))
            : [newLigne(today)]
    );
    const [formError, setFormError] = useState('');
    const [showBrouillonList, setShowBrouillonList] = useState(false);

    const [notesApprouvees, setNotesApprouvees] = useState<Note[]>([]);
    const [notesEnAttenteXml, setNotesEnAttenteXml] = useState<Note[]>([]);
    const [selectedNoteIds, setSelectedNoteIds] = useState<number[]>([]);
    const [datePaiementSaisie, setDatePaiementSaisie] = useState<string>('');
    const [selectedNoteIdsPaye, setSelectedNoteIdsPaye] = useState<number[]>([]);
    const [paiementLoading, setPaiementLoading] = useState(false);

    const [filtreStatut, setFiltreStatut] = useState('');
    const [filtreMois, setFiltreMois] = useState('');
    const [allNotesAdmin, setAllNotesAdmin] = useState<Note[]>([]);
    const [adminFiltreStatut, setAdminFiltreStatut] = useState('');
    const [adminFiltreMois, setAdminFiltreMois] = useState('');
    const [adminSearch, setAdminSearch] = useState('');
    const [historiqueValidateur, setHistoriqueValidateur] = useState<HistoriqueValidation[]>([]);
    const [historiquePaiements, setHistoriquePaiements] = useState<HistoriquePaiement[]>([]);
    const [paiementFiltreMois, setPaiementFiltreMois] = useState('');
    const [mesNotesFiltreStatut, setMesNotesFiltreStatut] = useState('');

    const campusDisponiblesPaiements = useMemo(() =>
        [...new Set(notesApprouvees.map(n => n.campus).filter(Boolean))].sort(),
        [notesApprouvees]
    );
    const societesDisponiblesPaiements = useMemo(() =>
        [...new Set(notesApprouvees.map(n => (n as any).societe).filter(Boolean))].sort(),
        [notesApprouvees]
    );
    const campusDisponiblesHistorique = useMemo(() =>
        [...new Set(historiquePaiements.map(n => n.campus).filter(Boolean))].sort(),
        [historiquePaiements]
    );
    const societesDisponiblesHistorique = useMemo(() =>
        [...new Set((historiquePaiements as any[]).map(n => n.societe).filter(Boolean))].sort(),
        [historiquePaiements]
    );

    const [qrNoteRef, setQrNoteRef] = useState<string>('');
    const [qrUploaded, setQrUploaded] = useState(false);
    const [qrLink, setQrLink] = useState<string | null>(null);
    const pollingRef = useRef<ReturnType<typeof setInterval> | null>(null);
    const lignePollingRefs = useRef<Record<string, ReturnType<typeof setInterval>>>({});

    const [noteDetail, setNoteDetail] = useState<Note | null>(null);
    const [selectedNote, setSelectedNote] = useState<Note | null>(null);

    const [serverBrouillons, setServerBrouillons] = useState<{ id: number; libelle: string; date: string; description: string; lignesJson: string; montant: number; DateModification: string }[]>([]);
    const [brouillonSaving, setBrouillonSaving] = useState(false);
    const autoSaveTimer = useRef<ReturnType<typeof setTimeout> | null>(null);

    const token = localStorage.getItem('token');
    const hdrs = { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' };
    const hdrsNoContent = { Authorization: `Bearer ${token}` } as HeadersInit;

    const showToast = (msg: string, type = 'success') => {
        setToast({ msg, type });
        setTimeout(() => setToast(null), 3500);
    };



    // ── Navigation avec historique navigateur ────────────
    const nav = (s: string) => {
        window.history.pushState({ section: s }, '', `#${s}`);
        setSection(s);
    };

    useEffect(() => {
        const hash = window.location.hash.replace('#', '');
        if (hash && sectionTitles[hash]) {
            setSection(hash);
        }
    }, []);

    // Écouter le bouton retour du navigateur
    useEffect(() => {
        // Initialiser l'état courant dans l'historique
        window.history.replaceState({ section: 'accueil' }, '', '#accueil');

        const handlePopState = (e: PopStateEvent) => {
            const s = e.state?.section || 'accueil';
            setSection(s);
        };

        window.addEventListener('popstate', handlePopState);
        return () => window.removeEventListener('popstate', handlePopState);
    }, []);

    // ── Auto-refresh toutes les 60 secondes ──────────────
    useEffect(() => {
        const interval = setInterval(() => {
            // Rafraîchir les données de la section active
            if (section === 'mesnotes' || section === 'accueil') {
                setNotesLoaded(false);
            }
            if ((section === 'validation' || section === 'accueil') && canValidate) {
                fetch(`${API}/api/notes/pending`, { headers: hdrs }).then(r => r.ok ? r.json() : []).then(d => Array.isArray(d) && setPending(d));
            }
            if (section === 'verification' && isVerificateurFinance) {
                fetch(`${API}/api/verificateur/notes`, { headers: hdrs }).then(r => r.ok ? r.json() : []).then(d => Array.isArray(d) && setNotesAVerifier(d));
            }
            if (section === 'paiements' && (isRHAdmin || isValidateurFinance)) {
                refreshNotesPaiements();
                fetch(`${API}/api/paiements/exceptions`, { headers: hdrs })
                    .then(r => r.ok ? r.json() : [])
                    .then(d => Array.isArray(d) && setExceptions(d))
                    .catch(() => { });

                // ← Charger les filtres dès l'arrivée sur la section paiements
                const currentToken = localStorage.getItem('token');
                const currentHdrs = {
                    Authorization: `Bearer ${currentToken}`,
                    'Content-Type': 'application/json'
                };
                fetch(`${API}/api/paiements/filtres-disponibles`, { headers: currentHdrs })
                    .then(r => r.ok ? r.json() : { campus: [], societes: [], societeParCampus: {} })
                    .then(d => setFiltresDisponibles(d))
                    .catch(() => { });
            }
            if (section === 'xmlgenerés' && (isRHAdmin || isValidateurFinance)) {
                setXmlLoading(true);
                const params = new URLSearchParams();
                if (xmlFiltreAnnee) params.append('annee', xmlFiltreAnnee);
                if (xmlFiltreMois) params.append('mois', xmlFiltreMois);
                fetch(`${API}/api/paiements/xml-historique?${params}`, { headers: hdrs })
                    .then(r => r.ok ? r.json() : [])
                    .then(d => Array.isArray(d) && setXmlHistorique(d))
                    .catch(() => { })
                    .finally(() => setXmlLoading(false));
            }
            fetch(`${API}/api/notifications`, { headers: hdrs }).then(r => r.ok ? r.json() : []).then(d => Array.isArray(d) && setNotifications(d));
        }, 60000);

        return () => clearInterval(interval);
    }, [section, canValidate, isVerificateurFinance, isRHAdmin, isValidateurFinance]);

    // ── Brouillons API ──────────────────────────────────
    useEffect(() => {
        fetch(`${API}/api/notes/brouillons`, { headers: hdrs })
            .then(r => r.ok ? r.json() : [])
            .then(d => { if (Array.isArray(d)) setServerBrouillons(d); })
            .catch(() => { });
    }, []);

    // ── Charger les filtres dès que les rôles sont connus ──
    useEffect(() => {
        if (!isRHAdmin && !isValidateurFinance) return;
        const currentToken = localStorage.getItem('token');
        fetch(`${API}/api/paiements/filtres-disponibles`, {
            headers: {
                Authorization: `Bearer ${currentToken}`,
                'Content-Type': 'application/json'
            }
        })
            .then(r => r.ok ? r.json() : null)
            .then(d => { if (d?.campus) setFiltresDisponibles(d); })
            .catch(() => { });
    }, [isRHAdmin, isValidateurFinance]);

    useEffect(() => {
        const isEmpty = !libelle && !description && lignes.every(l => !l.libelle && !l.categorie && !l.montant && !l.km);
        if (isEmpty) return;
        if (autoSaveTimer.current) clearTimeout(autoSaveTimer.current);
        autoSaveTimer.current = setTimeout(async () => {
            setBrouillonSaving(true);
            const currentId = activeBrouillonIdRef.current;
            const currentToken = localStorage.getItem('token');
            const currentHdrs = { Authorization: `Bearer ${currentToken}`, 'Content-Type': 'application/json' };
            try {
                const lignesPayload = lignes.map(l => ({ ...l, files: [] }));
                const body = JSON.stringify({ libelle, date, description, lignes: lignesPayload });
                if (currentId) {
                    const res = await fetch(`${API}/api/notes/brouillons/${currentId}`, { method: 'PUT', headers: currentHdrs, body });
                    if (res.ok) {
                        const data = await res.json();
                        setServerBrouillons(prev => prev.map(b => b.id === currentId ? { ...b, libelle, date, description, lignesJson: JSON.stringify(lignesPayload), DateModification: data.updatedAt } : b));
                    }
                } else {
                    const res = await fetch(`${API}/api/notes/brouillons`, { method: 'POST', headers: currentHdrs, body });
                    if (res.ok) {
                        const data = await res.json();
                        activeBrouillonIdRef.current = data.id;
                        setActiveBrouillonId(data.id);
                        localStorage.setItem('ndf_brouillon_active', String(data.id));
                        setServerBrouillons(prev => [{ id: data.id, libelle, date, description, lignesJson: JSON.stringify(lignesPayload), montant: 0, DateModification: data.createdAt }, ...prev]);
                    }
                }
            } catch (e) { console.error('Auto-save failed:', e); }
            finally { setBrouillonSaving(false); }
        }, 3000);
    }, [lignes, libelle, date, description]);

    const clearBrouillon = async (id?: number) => {
        const targetId = id ?? activeBrouillonId as number;
        if (!targetId) return;
        try {
            await fetch(`${API}/api/notes/brouillons/${targetId}`, { method: 'DELETE', headers: hdrs });
            setServerBrouillons(prev => prev.filter(b => b.id !== targetId));
            if (!id || id === activeBrouillonId) { setActiveBrouillonId(''); localStorage.removeItem('ndf_brouillon_active'); }
        } catch { }
    };

    const loadBrouillon = (b: typeof serverBrouillons[0]) => {
        setLibelle(b.libelle || '');
        setDate(b.date ? b.date.split('T')[0] : today);
        setDescription(b.description || '');
        try {
            const parsed = JSON.parse(b.lignesJson || '[]');
            setLignes(parsed.length ? parsed.map((l: LigneNote) => ({ ...l, files: [] })) : [newLigne(today)]);
        } catch { setLignes([newLigne(today)]); }
        setActiveBrouillonId(b.id);
        activeBrouillonIdRef.current = b.id;
        localStorage.setItem('ndf_brouillon_active', String(b.id));
        setShowBrouillonList(false);
    };

    const newBrouillon = () => {
        setActiveBrouillonId('');
        activeBrouillonIdRef.current = '';
        localStorage.removeItem('ndf_brouillon_active');
        setLibelle(''); setDate(today); setDescription('');
        setLignes([newLigne(today)]); setFiles([]);
        setShowBrouillonList(false);
    };

    // ── refreshNotesPaiements ───────────────────────────
    const refreshNotesPaiements = async () => {
        try {
            const data = await fetch(`${API}/api/notes-all`, { headers: hdrs }).then(r => r.ok ? r.json() : []);
            if (Array.isArray(data)) {
                const sourceApprouvees = isValidateurFinance && !isRHAdmin
                    ? data.filter((n: Note) => normalizeStatut(n.statut) === 'verifie')
                    : data.filter((n: Note) => ['approuve', 'verifie'].includes(normalizeStatut(n.statut)));
                setNotesApprouvees(sourceApprouvees);
                // ✅ Ajouter cette ligne pour le badge sidebar
                setNotesVerifiees(data.filter((n: Note) => normalizeStatut(n.statut) === 'verifie'));
                setNotesEnAttenteXml(data.filter((n: Note) => {
                    const s = normalizeStatut(n.statut);
                    return s === 'paiementenattente' || s === 'paiement_en_attente';
                }));
            }
        } catch { }
    };

    // ── useEffect global ────────────────────────────────
    useEffect(() => {
        fetch(`${API}/api/profile`, { headers: hdrs })
            .then(r => r.ok ? r.json() : null)
            .then(d => {
                if (d) {
                    setProfile(d);
                    setAdresseForm({
                        adresse_rue: d.adresse_rue || '',
                        adresse_cp: d.adresse_cp || '',
                        adresse_ville: d.adresse_ville || '',
                        adresse_pays: d.adresse_pays || 'France',
                        societe: d.societe || '',
                    });
                }
            });
        fetch(`${API}/api/categories`, { headers: hdrs }).then(r => r.ok ? r.json() : []).then(d => Array.isArray(d) && setCategories(d)).catch(() => { });
        fetch(`${API}/api/notifications`, { headers: hdrs }).then(r => r.ok ? r.json() : []).then(d => Array.isArray(d) && setNotifications(d)).catch(() => { });
        fetch(`${API}/api/paiements/prochain`, { headers: hdrs }).then(r => r.ok ? r.json() : null).then(d => d && setProchain(d)).catch(() => { });
        fetch(`${API}/api/paiements/config`, { headers: hdrs }).then(r => r.ok ? r.json() : null).then(d => d && setPaiementConfig(d)).catch(() => { });
        fetch(`${API}/api/parametres/km`, { headers: hdrs }).then(r => r.ok ? r.json() : {}).then((d: any) => { if (d?.tarifKm) setTarifKm(parseFloat(String(d.tarifKm))); }).catch(() => { });
        fetch(`${API}/api/parametres/tva`, { headers: hdrs }).then(r => r.ok ? r.json() : []).then(d => Array.isArray(d) && setTauxTVADisponibles(d)).catch(() => { });
        fetch(`${API}/api/profil/documents`, { headers: hdrs }).then(r => r.ok ? r.json() : { rib: null, carte_grise: null, permis: null }).then(d => setProfilDocs(d)).catch(() => { });
    }, []);

    useEffect(() => {
        if ((section === 'mesnotes' || section === 'accueil') && !notesLoaded) {
            fetch(`${API}/api/notes`, { headers: hdrs }).then(r => r.ok ? r.json() : []).then(d => { if (Array.isArray(d)) { setNotes(d); setNotesLoaded(true); } }).catch(() => { });
        }
        if (section === 'accueil' && (isRHAdmin || isValidateurFinance || isVerificateurFinance)) {
            refreshNotesPaiements();
        }
        if (section === 'accueil' && isVerificateurFinance) {
            fetch(`${API}/api/verificateur/notes`, { headers: hdrs })
                .then(r => r.ok ? r.json() : [])
                .then(d => Array.isArray(d) && setNotesAVerifier(d))
                .catch(() => { });
        }
        if (section === 'accueil' && (isFinance || isVerificateurFinance)) {
            fetch(`${API}/api/finance/documents-a-valider`, { headers: hdrs })
                .then(r => r.ok ? r.json() : [])
                .then(d => Array.isArray(d) && setDocsAValider(d))
                .catch(() => { });
        }
        // ✅ Charger pending aussi sur l'accueil si validateur
        if (section === 'validation' || (section === 'accueil' && canValidate)) {
            fetch(`${API}/api/notes/pending`, { headers: hdrs }).then(r => r.ok ? r.json() : []).then(d => Array.isArray(d) && setPending(d)).catch(() => { });
        }
        if (section === 'historique') {
            const params = new URLSearchParams();
            if (filtreMois) { params.append('mois', filtreMois.split('-')[1]); params.append('annee', filtreMois.split('-')[0]); }
            if (filtreStatut) params.append('statut', filtreStatut);
            fetch(`${API}/api/notes?${params}`, { headers: hdrs }).then(r => r.ok ? r.json() : []).then(d => Array.isArray(d) && setHistoriqueNotes(d)).catch(() => { });
        }
        if (section === 'paiements' && (isRHAdmin || isValidateurFinance)) {
            refreshNotesPaiements();
            fetch(`${API}/api/paiements/exceptions`, { headers: hdrs }).then(r => r.ok ? r.json() : []).then(d => Array.isArray(d) && setExceptions(d)).catch(() => { });
        }
        if (section === 'mesvalidations' && canValidate) {
            fetch(`${API}/api/validateur/historique`, { headers: hdrs }).then(r => r.ok ? r.json() : []).then(d => Array.isArray(d) && setHistoriqueValidateur(d)).catch(() => { });
        }
        if (section === 'supervision' && isSuperUser) {
            const params = new URLSearchParams();
            if (adminFiltreMois) { params.append('mois', adminFiltreMois.split('-')[1]); params.append('annee', adminFiltreMois.split('-')[0]); }
            if (adminFiltreStatut) params.append('statut', adminFiltreStatut);
            fetch(`${API}/api/admin/notes?${params}`, { headers: hdrs }).then(r => r.ok ? r.json() : []).then(d => Array.isArray(d) && setAllNotesAdmin(d)).catch(() => { });
        }
        if (section === 'profil') {
            setProfilDocsLoading(true);
            fetch(`${API}/api/profil/documents`, { headers: hdrs }).then(r => r.ok ? r.json() : { rib: null, carte_grise: null, permis: null }).then(d => setProfilDocs(d)).catch(() => { }).finally(() => setProfilDocsLoading(false));
            fetch(`${API}/api/profil/iban`, { headers: hdrs }).then(r => r.ok ? r.json() : null).then(d => d && setIbanData(d)).catch(() => { });
            fetch(`${API}/api/profil/vehicule`, { headers: hdrs })
                .then(r => r.ok ? r.json() : null)
                .then(data => {
                    if (data?.configured && data.vehicule) {
                        setVehicule(data.vehicule);
                        setVehiculeForm(data.vehicule);
                    }
                })
                .catch(() => { });
        }
        
        if (section === 'docsavalider' && (isFinance || isVerificateurFinance)) {
            setDocsAValiderLoading(true);
            fetch(`${API}/api/finance/documents-a-valider`, { headers: hdrs }).then(r => r.ok ? r.json() : []).then(d => Array.isArray(d) && setDocsAValider(d)).catch(() => { }).finally(() => setDocsAValiderLoading(false));
        }
        if (section === 'historiquepaiements' && (isRHAdmin || isValidateurFinance)) {
            const params = new URLSearchParams();
            if (paiementFiltreMois) {
                const [annee, mois] = paiementFiltreMois.split('-');
                params.append('mois', mois);
                params.append('annee', annee);
            }
            fetch(`${API}/api/paiements/historique?${params}`, { headers: hdrs })
                .then(r => r.ok ? r.json() : [])
                .then(d => Array.isArray(d) && setHistoriquePaiements(d))
                .catch(() => { });

            // ← SUPPRIMER la condition !filtresDisponibles.campus.length
            // et forcer le rechargement à chaque fois
            const currentToken = localStorage.getItem('token');
            const currentHdrs = {
                Authorization: `Bearer ${currentToken}`,
                'Content-Type': 'application/json'
            };
            fetch(`${API}/api/paiements/filtres-disponibles`, { headers: currentHdrs })
                .then(r => r.ok ? r.json() : { campus: [], societes: [] })
                .then(d => setFiltresDisponibles(d))
                .catch(() => { });
        }
          if ((section === 'president' || section === 'accueil') && isPresident) {
            fetch(`${API}/api/president/notes`, { headers: hdrs })
                .then(r => r.ok ? r.json() : [])
                .then(d => Array.isArray(d) && setNotesEnAttentePresident(d))
                .catch(() => { });
        }

        // ── NOUVEAU : Vérificateur Finance ──
        if (section === 'verification' && isVerificateurFinance) {
            fetch(`${API}/api/verificateur/notes`, { headers: hdrs }).then(r => r.ok ? r.json() : []).then(d => Array.isArray(d) && setNotesAVerifier(d)).catch(() => { });
        }
    }, [section, filtreMois, filtreStatut, adminFiltreMois, adminFiltreStatut, paiementFiltreMois, isRHAdmin, isVerificateurFinance, isValidateurFinance, isSuperUser, canValidate, isFinance]);

    // ── À ajouter dans le Dashboard, après les autres useEffect ──
    useEffect(() => {
        const noteActive = selectedNote || noteDetail;
        if (!noteActive) return;

        const token = localStorage.getItem('token');

        fetch(`${API}/api/notes/${noteActive.id}/download-urls`, {
            headers: { Authorization: `Bearer ${token}` }
        })
            .then(r => r.ok ? r.json() : {})
            .then(async (urlMap: Record<string, string>) => {
                if (!Object.keys(urlMap).length) return;

                await Promise.all(
                    Object.entries(urlMap).map(async ([spUrl, directUrl]) => {
                        const proxied = proxyUrl(spUrl); // clé de cache = URL proxy
                        if (clientProxyCache.has(proxied)) return; // déjà en cache

                        try {
                            // ✅ Télécharge directement depuis Microsoft CDN (pas via ton serveur)
                            const r = await fetch(directUrl);
                            if (!r.ok) return;
                            const blob = await r.blob();
                            clientProxyCache.set(proxied, URL.createObjectURL(blob));
                        } catch { }
                    })
                );
            })
            .catch(() => { });
    }, [selectedNote?.id, noteDetail?.id]);

    const marquerNotifLue = async (id: number) => {
        await fetch(`${API}/api/notifications/${id}/lu`, { method: 'PUT', headers: hdrs });
        setNotifications(prev => prev.map(n => n.id === id ? { ...n, Lu: true } : n));
    };

    const handleValider = async (id: number, action: 'valider' | 'refuser', commentaire?: string) => {
        try {
            const res = await fetch(`${API}/api/notes/${id}/statut`, { method: 'PUT', headers: hdrs, body: JSON.stringify({ action, commentaire }) });
            const data = await res.json();
            if (!res.ok) throw new Error(data.error || 'Erreur');
            showToast(action === 'valider' ? `Note validée → ${data.statut}` : 'Note refusée', action === 'valider' ? 'success' : 'error');
            setPending(p => p.filter(n => n.id !== id));
            setNotesLoaded(false);
        } catch (e: any) { showToast(e.message || 'Erreur', 'error'); }
    };

    const handleModifierNote = (note: Note) => {
        setLibelle(note.libelle || '')
        setDate(note.date ? String(note.date).split('T')[0] : today)
        setDescription(note.description || '')

        // ✅ Récupérer les justificatifs SharePoint (exclure fiche soumission + recap auto)
        let fichiersNote: { fileName: string; uploadUrl: string }[] = [];
        try {
            fichiersNote = JSON.parse(note.fichiers || '[]')
                .filter((f: any) => {
                    const n = (f.fileName || '').toLowerCase();
                    return !n.includes('soumission') && !n.includes('recap');
                })
                .map((f: any) => ({ fileName: f.fileName, uploadUrl: f.uploadUrl }));
        } catch { fichiersNote = []; }

        try {
            const parsed = JSON.parse(note.lignesJson || '[]')
            setLignes(parsed.length ? parsed.map((l: LigneNote, i: number) => ({
                ...newLigne(today),
                ...l,
                idTemp: crypto.randomUUID(),
                files: [],
                qrUploaded: (l.qrNoteRef || (l.qrFiles?.length ?? 0) > 0) ? true : false,
                // ✅ Injecter les fichiers SharePoint dans la première ligne
                // (les autres lignes gardent leurs qrFiles existants s'il y en a)
                qrFiles: i === 0
                    ? [...(l.qrFiles || []), ...fichiersNote]
                    : (l.qrFiles || []),
            })) : [newLigne(today)])
        } catch { setLignes([newLigne(today)]) }

        const noteKey = `refusee-${note.id}`
        setActiveBrouillonId(noteKey as any)
        activeBrouillonIdRef.current = noteKey as any
        localStorage.setItem('ndfbrouillonactive', noteKey)
        setSelectedNote(null)
        nav('nouvelle')
        showToast('Note chargée : corrigez puis resoumettez.', 'success')
    };

    const handleTraiterException = async (id: number, statut: 'approuve' | 'refuse') => {
        try {
            const res = await fetch(`${API}/api/paiements/exceptions/${id}`, { method: 'PUT', headers: hdrs, body: JSON.stringify({ statut }) });
            if (!res.ok) throw new Error();
            showToast(statut === 'approuve' ? 'Exception approuvée' : 'Exception refusée', statut === 'approuve' ? 'success' : 'error');
            setExceptions(prev => prev.filter(e => e.id !== id));
        } catch { showToast('Erreur lors du traitement', 'error'); }
    };

    const uploadProfilDoc = async (type: string, file: File) => {
        setProfilDocsUploading(type);
        try {
            const formData = new FormData();
            formData.append('file', file);
            const res = await fetch(`${API}/api/profil/documents/${type}`, { method: 'POST', headers: { Authorization: hdrs.Authorization }, body: formData });
            const data = await res.json();
            if (!res.ok) throw new Error(data.error || 'Erreur upload');
            setProfilDocs(prev => ({ ...prev, [type]: { fileName: data.fileName, sharepointUrl: data.sharepointUrl, updatedAt: data.updatedAt, statut: 'en_attente', commentaire: null } }));
            showToast(`✅ Document mis à jour !`);
        } catch (e: any) { showToast(e.message, 'error'); }
        finally { setProfilDocsUploading(null); }
    };

    const deleteProfilDoc = async (type: string) => {
        if (!window.confirm('Supprimer ce document ?')) return;
        try {
            await fetch(`${API}/api/profil/documents/${type}`, { method: 'DELETE', headers: hdrs });
            setProfilDocs(prev => ({ ...prev, [type]: null }));
            showToast('Document supprimé');
        } catch { }
    };

    const generateQRForLigne = async (ligneIdTemp: string) => {
        const tempRef = `NDF-LIGNE-${ligneIdTemp}-${Date.now()}`;
        const res = await fetch(`${API}/api/upload/generate-link`, { method: 'POST', headers: hdrs, body: JSON.stringify({ noteRef: tempRef }) });
        const data = await res.json();
        if (!res.ok) { alert("Erreur: " + (data.error || res.status)); return; }
        setLignes(prev => prev.map(l => l.idTemp === ligneIdTemp ? { ...l, qrLink: data.uploadLink, qrNoteRef: tempRef, qrUploaded: false } : l));
        if (lignePollingRefs.current[ligneIdTemp]) clearInterval(lignePollingRefs.current[ligneIdTemp]);
        lignePollingRefs.current[ligneIdTemp] = setInterval(async () => {
            const r = await fetch(`${API}/api/upload/status/${tempRef}`, { headers: hdrs });
            const d = await r.json();
            if (d.uploaded) { clearInterval(lignePollingRefs.current[ligneIdTemp]); setLignes(prev => prev.map(l => l.idTemp === ligneIdTemp ? { ...l, qrUploaded: true, qrLink: null } : l)); }
        }, 3000);
    };

    const handleSoumettre = async (titre: string, dateDebut: string, dateFin: string, commentaire: string, lignesExterne: any[]): Promise<void> => {
        setFormError('');
        if (!titre.trim()) return setFormError('Le libellé global est obligatoire.');
        if (!lignesExterne.length || lignesExterne.some(l => !l.libelle.trim() || !l.date)) return setFormError('Chaque dépense doit avoir un libellé et une date.');
        if (lignesExterne.some(l => !l.categorie)) return setFormError('Chaque dépense doit avoir une catégorie.');
        const ibanCheck = await fetch(`${API}/api/profil/iban`, { headers: hdrs as HeadersInit })
            .then(r => r.ok ? r.json() : null).catch(() => null);

        if (!ibanCheck?.ibanSaisi) {
            showToast('⛔ Votre IBAN doit être saisi dans "Mon profil" avant de soumettre une note.', 'error');
            return;
        }
        if (!ibanCheck?.bic) {
            showToast('⛔ Votre BIC doit être renseigné dans "Mon profil" avant de soumettre une note.', 'error');
            return;
        }
        if (!profile?.adresse_rue || !profile?.adresse_cp || !profile?.adresse_ville || !profile?.adresse_pays) {
            showToast('⛔ Veuillez renseigner votre adresse complète dans "Mon profil" avant de soumettre une note.', 'error');
            return;
        }
                // Vérification documents obligatoires pour notes kilométriques
                const hasKmLine = lignesExterne.some(l => l.categorie?.toLowerCase().includes('kilom'));
                if (hasKmLine) {
                    const docs = await fetch(`${API}/api/profil/documents`, { headers: hdrs as HeadersInit })
                        .then(r => r.ok ? r.json() : null).catch(() => null);

                    if (!docs?.carte_grise || docs.carte_grise.statut === 'refuse') {
                        showToast('⛔ Votre carte grise doit être soumise dans "Mon profil" avant une note kilométrique.', 'error');
                        return;
                    }
                    if (!docs?.permis || docs.permis.statut === 'refuse') {
                        showToast('⛔ Votre permis de conduire doit être soumis dans "Mon profil" avant une note kilométrique.', 'error');
                        return;
                    }
                }

        const lignesPayload = lignesExterne.map(l => {
            const isKm = l.categorie.toLowerCase().includes('kilom');
            const km = parseFloat(l.km) || 0;
            const cv = parseInt(l.chevaux) || 7;
            const indemnite = isKm ? getIndemniteKm(km, cv) : 0;
            const items = (l.tvaItems || []).filter((i: any) => parseFloat(i.montantTTC) > 0);
            const ttcTotal = isKm ? indemnite : items.reduce((s: number, i: any) => s + parseFloat(i.montantTTC || 0), 0);
            return {
                date: l.date,
                categorie: l.categorie,
                libelle: l.libelle,
                montant: ttcTotal,
                tauxTVA: isKm ? null : (items.length > 0 ? parseFloat(items[0].taux) : null),
                tvaItems: isKm ? [] : items,
                km: isKm ? km : null,
                chevaux: isKm ? cv : null,
                indemniteKm: isKm ? indemnite : null,
                description: l.description || null,
                participants: (l.participants || []).filter((p: any) => p.nom?.trim()) || null,
                nombreParticipants: l.nombreParticipants ? parseInt(l.nombreParticipants) : null,
                qrNoteRef: l.qrNoteRef || null,
                qrUploaded: l.qrUploaded || false,
                // ✅ AJOUT CRITIQUE : transmettre les fichiers QR du brouillon
                qrFiles: l.qrFiles || [],
                nuits: l.nuits || null,
            };
        });

        setLoading(true);
        try {
            const formData = new FormData();
            formData.append('libelle', titre);
            formData.append('date', dateDebut || date);
            formData.append('description', commentaire || description);
            formData.append('lignes', JSON.stringify(lignesPayload));
            if (qrNoteRef) formData.append('qrNoteRef', qrNoteRef);
            files.forEach(f => formData.append('justificatifs', f));
            lignesExterne.forEach(l => {
                l.files?.forEach((f: File) => formData.append(`files_${l.id}`, f));
            });

            // ✅ Détecter si c'est une modification de note refusée
            const brouillonKey = String(activeBrouillonId || '');
            const isNoteRefusee = brouillonKey.startsWith('refusee-');
            const noteRefuseeId = isNoteRefusee ? parseInt(brouillonKey.replace('refusee-', '')) : null;

            let res: Response;
            if (noteRefuseeId) {
                // PUT /api/notes/:id pour modifier une note refusée
                res = await fetch(`${API}/api/notes/${noteRefuseeId}`, {
                    method: 'PUT',
                    headers: hdrsNoContent,
                    body: formData
                });
            } else {
                // POST /api/notes pour créer une nouvelle note
                res = await fetch(`${API}/api/notes`, {
                    method: 'POST',
                    headers: hdrsNoContent,
                    body: formData
                });
            }

            const data = await res.json();
            if (!res.ok) throw new Error(data.error || 'Erreur');

            showToast(`Note ${data.reference} ${noteRefuseeId ? 'corrigée et resoumise' : 'soumise'} !`, 'success');
            setLibelle(''); setDescription(''); setFiles([]); setDate(today); setLignes([newLigne(today)]);
            setQrLink(null); setQrNoteRef(''); setQrUploaded(false); setNotesLoaded(false);

            // Nettoyer le brouillon si c'en était un
            if (activeBrouillonId && !isNoteRefusee) {
                await clearBrouillon(activeBrouillonId as number);
            }

            // Reset
            setActiveBrouillonId('');
            activeBrouillonIdRef.current = '';
            localStorage.removeItem('ndf_brouillon_active');

            nav('mesnotes');
        } catch (e: any) { setFormError(e.message || 'Erreur lors de la soumission'); throw e; }
        finally { setLoading(false); }
    };

    const initials = (user?.name || 'U').split(' ').map((w: string) => w[0]).join('').toUpperCase().slice(0, 2);
    const nonLues = notifications.filter(n => !n.Lu).length;

    const sectionTitles: Record<string, string> = {
        accueil: 'Tableau de bord', nouvelle: 'Nouvelle note de frais',
        mesnotes: 'Mes notes', validation: 'Notes à valider',
        historique: 'Historique', profil: 'Mon profil',
        paiements: isValidateurFinance && !isRHAdmin ? 'Validation des paiements' : 'Gestion des paiements',
        mesvalidations: 'Historique des validations',
        supervision: 'Supervision — Toutes les notes',
        verification: 'Notes à vérifier — Contrôle Finance',
        docsavalider: 'Documents à valider',
        historiquepaiements: 'Historique des paiements',
        xmlgenerés: 'XML virements générés',
        president: 'Validation Président — Virements bancaires',
    };

    const menuItems = [
        { id: 'accueil', icon: <LayoutDashboard size={16} />, label: 'Tableau de bord' },
        { id: 'nouvelle', icon: <PlusCircle size={16} />, label: 'Nouvelle note' },
        { id: 'mesnotes', icon: <FileText size={16} />, label: 'Mes notes' },
        ...(canValidate ? [{ id: 'validation', icon: <CheckSquare size={16} />, label: 'Notes à valider', badge: pending.length }] : []),
        ...(canValidate ? [{ id: 'mesvalidations', icon: <ClipboardList size={16} />, label: 'Mes validations' }] : []),
        { id: 'historique', icon: <History size={16} />, label: 'Historique' },
        // ── Nouveaux rôles ──
        ...(isVerificateurFinance ? [{ id: 'verification', icon: <Eye size={16} />, label: 'Notes à vérifier', badge: notesAVerifier.length || undefined }] : []),
        ...(isValidateurFinance ? [{ id: 'paiements', icon: <CreditCard size={16} />, label: 'Valider paiements', badge: notesVerifiees.length || undefined }] : []),
         ...(isPresident ? [{
                    id: 'president',
                    icon: <ShieldCheck size={16} />,
                    label: 'Validation Président',
                    badge: notesEnAttentePresident.length || undefined
                }] : []),
        // ── Rôles Finance classiques ──
       ...((isFinance || isVerificateurFinance) ? [{ id: 'docsavalider', icon: <ShieldCheck size={16} />, label: 'Documents à valider', badge: docsAValider.filter((d: any) => d.statut === 'en_attente').length || undefined }] : []),
        ...(isRHAdmin ? [{ id: 'paiements', icon: <CreditCard size={16} />, label: 'Paiements', badge: exceptions.length || undefined }] : []),
        ...((isRHAdmin || isValidateurFinance) ? [{ id: 'historiquepaiements', icon: <CreditCard size={16} />, label: 'Historique paiements' }] : []),
        ...(isSuperUser ? [{ id: 'supervision', icon: <ShieldCheck size={16} />, label: 'Supervision' }] : []),
        { id: 'profil', icon: <User size={16} />, label: 'Mon profil' },
        ...((isRHAdmin || isValidateurFinance) ? [{ id: 'xmlgenerés', icon: <Send size={16} />, label: 'XML virements' }] : []),
    ].filter((item, index, self) => self.findIndex(i => i.id === item.id) === index); // déduplique

    const statCards = [
        { label: 'En attente', value: notes.filter(n => ['enattente', 'en_attente', 'en attente'].includes(n.statut || '')).length, sub: 'à valider', accent: '#f59e0b' },
        { label: 'Ce mois', value: fmt(notes.reduce((a, n) => a + (n.montant || 0), 0)), sub: 'total soumis', accent: '#6366f1' },
        { label: 'Validées', value: notes.filter(n => ['valide', 'approuve', 'verifie', 'payee'].includes(normalizeStatut(n.statut || ''))).length, sub: 'notes validées', accent: '#10b981' },
        { label: 'Refusées', value: notes.filter(n => ['refuse', 'refusé'].includes(n.statut || '')).length, sub: 'à corriger', accent: '#ef4444' },
        { label: 'En att. paiement', value: notes.filter(n => ['paiementenattente', 'paiement_en_attente'].includes(normalizeStatut(n.statut || ''))).length, sub: 'à régler', accent: '#b45309' },
    ];

    // ── RENDU PANNEAU DETAIL NOTE (réutilisé dans mesnotes + validation) ──
    const renderNoteDetailPanel = (note: Note, onClose: () => void, withActions = false) => (
        <div style={{ width: 'clamp(320px, 35vw, 420px)', flexShrink: 0, ...cardStyle, alignSelf: 'flex-start', position: 'sticky', top: 20, maxHeight: 'calc(100vh - 48px)', display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
            <div style={{ padding: '16px 20px', borderBottom: '1px solid var(--border-divider)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                <h3 style={{ fontSize: 14, fontWeight: 700, margin: 0 }}>Détail de la note</h3>
                <button onClick={onClose} style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 18, color: 'var(--text-muted)' }}>✕</button>
            </div>
            <div style={{ flex: 1, overflowY: 'auto', padding: 20 }}>
                <StatutStepper statut={note.statut || 'brouillon'} />
                {(note as any).noteRefuseeId && (
                    <div style={{
                        background: '#fff7ed', border: '1.5px solid #fed7aa',
                        borderLeft: '4px solid #f97316',
                        borderRadius: '0 8px 8px 0', padding: '10px 14px', marginBottom: 12,
                    }}>
                        <div style={{ fontSize: 12, fontWeight: 700, color: '#c2410c' }}>
                            🔄 Correction d'une note refusée
                        </div>
                        <div style={{ fontSize: 11, color: '#ea580c', marginTop: 3 }}>
                            Ancienne référence : <strong>{(note as any).ancienneReference || `#${(note as any).noteRefuseeId}`}</strong>
                        </div>
                        <button
                            onClick={() => {
                                fetch(`${API}/api/notes/${(note as any).noteRefuseeId}/detail`, { headers: hdrs })
                                    .then(r => r.ok ? r.json() : Promise.reject('Accès refusé'))
                                    .then(ancienne => setAncienneNoteComparaison(ancienne))
                                    .catch(() => showToast('Impossible de charger l\'ancienne note', 'error'));
                            }}
                            style={{
                                marginTop: 6, padding: '4px 10px',
                                background: '#fed7aa', border: '1px solid #f97316',
                                borderRadius: 6, cursor: 'pointer',
                                fontSize: 11, fontWeight: 600, color: '#c2410c',
                                fontFamily: 'inherit'
                            }}>
                            👁 Voir l'ancienne note
                        </button>
                    </div>
                )}

                {/* Info grid */}
                <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10, marginBottom: 16 }}>
                    {[
                        { label: 'Référence', value: note.reference || `#${note.id}`, mono: true },
                        { label: 'Statut', value: tagStatut(note.statut || 'brouillon'), isNode: true },
                        { label: 'Catégorie', value: note.categorie },
                        { label: 'Date', value: note.date ? new Date(note.date).toLocaleDateString('fr-FR') : '-' },
                        { label: 'Montant TTC', value: fmt(note.montant || 0), bold: true },
                        { label: 'Collaborateur', value: (note as any).collaborateur },
                    ].filter(i => i.value).map(({ label, value, mono, bold, isNode }: any) => (
                        <div key={label} style={{ background: 'var(--bg-input)', borderRadius: 8, padding: '8px 12px' }}>
                            <div style={{ fontSize: 10, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', marginBottom: 2 }}>{label}</div>
                            {isNode
                                ? <div style={{ marginTop: 2 }}>{value}</div>
                                : <div style={{ fontSize: 13, fontWeight: bold ? 800 : 600, color: mono ? '#6366f1' : 'var(--text-primary)', fontFamily: mono ? 'monospace' : 'inherit' }}>{value || '—'}</div>
                            }
                        </div>
                    ))}
                </div>

                {/* Infos vérification */}
                {note.dateVerification && (
                    <div style={{ background: '#ede9fe', border: '1px solid #c4b5fd', borderRadius: 8, padding: '10px 12px', marginBottom: 12, fontSize: 12 }}>
                        <div style={{ fontWeight: 700, color: '#7c3aed', marginBottom: 2 }}>🔍 Vérifié par {note.nomVerificateur}</div>
                        <div style={{ color: '#6d28d9' }}>Le {new Date(note.dateVerification).toLocaleDateString('fr-FR')}</div>
                        {note.commentaireVerification && <div style={{ marginTop: 4, color: '#7c3aed' }}>💬 {note.commentaireVerification}</div>}
                    </div>
                )}

                {normalizeStatut(note.statut || '') === 'refuse' && (
                    <div style={{
                        background: '#fef2f2',
                        border: '1.5px solid #fecaca',
                        borderLeft: '4px solid #ef4444',
                        borderRadius: '0 8px 8px 0',
                        padding: '14px 16px',
                        marginBottom: 16,
                    }}>
                        <div style={{ fontSize: 13, fontWeight: 800, color: '#dc2626', marginBottom: 4 }}>
                            ❌ Note refusée — action requise
                        </div>
                        {note.motifRefus && (
                            <div style={{ fontSize: 12, color: '#991b1b', background: '#fee2e2', padding: '8px 10px', borderRadius: 6, marginBottom: 10, fontWeight: 600 }}>
                                Motif : {note.motifRefus}
                            </div>
                        )}
                        <div style={{ fontSize: 12, color: '#7f1d1d', marginBottom: 10, lineHeight: 1.5 }}>
                            Corrigez les informations demandées puis resoumettez votre note.
                        </div>
                        <button
                            onClick={() => handleModifierNote(note)}
                            style={{
                                display: 'flex', alignItems: 'center', gap: 6,
                                padding: '9px 18px',
                                background: 'linear-gradient(135deg,#ef4444,#dc2626)',
                                color: '#fff', border: 'none', borderRadius: 8,
                                cursor: 'pointer', fontFamily: 'inherit',
                                fontSize: 13, fontWeight: 700,
                                boxShadow: '0 4px 12px rgba(239,68,68,.3)',
                            }}>
                            ✏️ Corriger et resoumette
                        </button>
                    </div>
                )}
                {normalizeStatut(note.statut || '') === 'refuse_verif' && (
                    <div style={{
                        background: '#fef2f2',
                        border: '1.5px solid #fecaca',
                        borderLeft: '4px solid #dc2626',
                        borderRadius: '0 8px 8px 0',
                        padding: '14px 16px',
                        marginBottom: 16,
                    }}>
                        <div style={{ fontSize: 13, fontWeight: 800, color: '#dc2626', marginBottom: 6 }}>
                            ❌ Note refusée par la Finance — action requise
                        </div>
                        <div style={{ fontSize: 12, color: '#7f1d1d', marginBottom: 12, lineHeight: 1.5 }}>
                            Le Vérificateur Finance a refusé certaines lignes. Corrigez-les puis resoumettez votre note.
                        </div>
                        {note.commentaireVerification && (
                            <div style={{
                                fontSize: 12, color: '#991b1b', background: '#fee2e2',
                                padding: '8px 10px', borderRadius: 6, marginBottom: 12, fontWeight: 600,
                            }}>
                                {note.commentaireVerification}
                            </div>
                        )}
                        <button
                            onClick={() => handleModifierNote(note)}
                            style={{
                                display: 'flex', alignItems: 'center', gap: 6,
                                padding: '9px 18px',
                                background: 'linear-gradient(135deg,#ef4444,#dc2626)',
                                color: '#fff', border: 'none', borderRadius: 8,
                                cursor: 'pointer', fontFamily: 'inherit',
                                fontSize: 13, fontWeight: 700,
                                boxShadow: '0 4px 12px rgba(239,68,68,.3)',
                            }}>
                            ✏️ Corriger et resoumettre
                        </button>
                    </div>
                )}
                {note.commentaireN1 && (
                    <div style={{ background: '#f0f9ff', border: '1px solid #bae6fd', borderRadius: 6, padding: '8px 12px', marginBottom: 8, fontSize: 12, color: '#0369a1' }}>
                        💬 Commentaire N1 : {note.commentaireN1}
                    </div>
                )}
                {note.datePaiement && (
                    <div style={{ background: '#f0fdf4', border: '1px solid #86efac', borderRadius: 8, padding: '8px 12px', marginBottom: 12, fontSize: 12, color: '#15803d', fontWeight: 600 }}>
                        💶 Payée le {new Date(note.datePaiement).toLocaleDateString('fr-FR')}
                    </div>
                )}

                {/* Modifier si en attente */}
                {['enattente', 'en_attente', 'en attente'].includes(normalizeStatut(note.statut || '')) && !withActions && (
                    <div style={{ padding: '12px 16px', background: 'linear-gradient(90deg,#eff6ff,#eef2ff)', border: '1.5px solid #c7d2fe', borderRadius: 10, marginBottom: 14, display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12 }}>
                        <div>
                            <div style={{ fontSize: 12, fontWeight: 700, color: '#4338ca' }}>✏️ Note modifiable</div>
                            <div style={{ fontSize: 11, color: '#6366f1', marginTop: 2 }}>En attente — vous pouvez encore la modifier.</div>
                        </div>
                        <button onClick={() => handleModifierNote(note)} style={{ ...btnPrimary, fontSize: 12, padding: '8px 16px' }}>✏️ Modifier</button>
                    </div>
                )}

                {/* Lignes détail */}
                <LignesDetail note={note} tarifKm={tarifKm} onPreview={(url, name) => setPreviewUrl({ url: proxyUrl(url), name })} />

                {/* Fichiers globaux — uniquement si approuvé/vérifié/payé */}
                {/* Fichiers globaux — uniquement si approuvé/vérifié/payé */}
                {['approuve', 'verifie', 'paiementenattente', 'paiement_en_attente', 'payee'].includes(normalizeStatut(note.statut || '')) && (
                    <div style={{ marginBottom: 16 }}>
                        <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-secondary)', textTransform: 'uppercase', marginBottom: 8 }}>Justificatifs</div>
                        <FichiersGlobaux note={note} onPreview={(url, name) => setPreviewUrl({ url, name })} proxyFn={proxyUrl} />
                    </div>
                )}
            </div>

            {/* Boutons fixés en bas — EN DEHORS du scroll */}
            {withActions && (
                <div style={{
                    position: 'sticky',
                    bottom: 16,
                    display: 'flex',
                    gap: 10,
                    margin: '16px -4px -4px',
                    padding: '10px 12px',
                    background: 'var(--bg-card)',
                    borderRadius: 12,
                    boxShadow: '0 4px 20px rgba(0,0,0,0.15)',
                    border: '1px solid var(--border-card)',
                    zIndex: 10,
                }}>
                    <button
                        style={{ ...btnSuccess, flex: 1, justifyContent: 'center', display: 'flex' }}
                        onClick={() => {
                            setMotifRefusInput('');
                            setModalValidation({ noteId: note.id, action: 'valider', onClose });
                        }}>
                        ✅ Valider
                    </button>
                    <button
                        style={{ ...btnDanger, flex: 1, justifyContent: 'center', display: 'flex' }}
                        onClick={() => {
                            setMotifRefusInput('');
                            setModalValidation({ noteId: note.id, action: 'refuser', onClose });
                        }}>
                        ❌ Refuser
                    </button>
                </div>
            )}
        </div>
    );

    return (
        <div style={{ display: 'flex', minHeight: '100vh', fontFamily: '"Inter","Segoe UI",system-ui,sans-serif', background: 'var(--bg-app)', color: 'var(--text-primary)' }}>
            <style>{`
                @media (max-width: 768px) {
                    aside.ndf-aside { transform: translateX(-100%); transition: transform 0.3s ease, width 0.3s ease !important; width: 260px !important; z-index: 150 !important; }
                    aside.ndf-aside.open { transform: translateX(0) !important; }
                    .sidebar-overlay { display: block; position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 99; }
                    main.ndf-main { margin-left: 0 !important; padding: 16px 14px !important; padding-top: 56px !important; }
                    .stat-grid { grid-template-columns: repeat(3,1fr) !important; gap: 8px !important; }
                    .table-wrapper { overflow-x: auto; }
                }
                @media (min-width: 769px) {
                    aside.ndf-aside { transform: none !important; }
                    .sidebar-overlay { display: none !important; }
                }

                 @media (max-width: 1024px) {
                /* Grille stats : 3 colonnes sur tablette */
                .stat-grid { grid-template-columns: repeat(3,1fr) !important; }
        
                /* Grille profil : 2 colonnes */
                .profil-grid { grid-template-columns: 1fr 1fr !important; }
                }
    
                @media (max-width: 768px) {
                aside.ndf-aside { transform: translateX(-100%); transition: transform 0.3s ease, width 0.3s ease !important; width: 260px !important; z-index: 150 !important; }
                aside.ndf-aside.open { transform: translateX(0) !important; }
                .sidebar-overlay { display: block; position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 99; }
                main.ndf-main { margin-left: 0 !important; padding: 16px 14px !important; padding-top: 56px !important; }
        
                /* Stats : 2 colonnes sur mobile */
                .stat-grid { grid-template-columns: repeat(2,1fr) !important; gap: 8px !important; }
        
                /* Header : empiler sur mobile */
                .ndf-header { flex-direction: column !important; align-items: flex-start !important; gap: 10px !important; }
                .ndf-header-actions { width: 100%; justify-content: flex-end; }
        
                /* Tableau : scroll horizontal */
                .table-wrapper { overflow-x: auto; -webkit-overflow-scrolling: touch; }
        
                /* Panneau détail : plein écran sur mobile */
                .detail-panel { 
                position: fixed !important; 
                inset: 0 !important; 
                width: 100% !important; 
                max-height: 100vh !important;
                z-index: 500 !important;
                border-radius: 0 !important;
                }
        
                /* Grille paiements/profil : 1 colonne */
                .paiements-grid { grid-template-columns: 1fr !important; }
                .profil-grid { 
                grid-template-columns: 1fr !important; 
                grid-template-rows: auto !important;
                }
                .profil-col3 { grid-column: 1 !important; grid-row: auto !important; }
                .profil-col12 { grid-column: 1 !important; grid-row: auto !important; }
        
                /* Validation 3 colonnes : empiler */
                .validation-layout { flex-direction: column !important; height: auto !important; }
                .validation-list { flex: none !important; max-width: 100% !important; max-height: 300px !important; }
                }
    
                @keyframes spin { to { transform: rotate(360deg); } }

               @media (max-width: 1440px) and (min-width: 1025px) {
                main.ndf-main {
                padding: 18px 20px !important;
                }
                .stat-grid {
                grid-template-columns: repeat(3, 1fr) !important;
                gap: 8px !important;
                }
                }
        
                /* Panneau liste notes : pas de largeur fixe */
                .notes-list-col { min-width: 0 !important; }
        
                /* Tableau mesnotes */
                .notes-table th:nth-child(3),
                .notes-table td:nth-child(3) { display: none; }
                }
    
                @media (max-width: 1024px) {
                /* Section validation : réduire la col liste */
                .validation-list-col { flex: 0 0 200px !important; }
        
                /* Masquer colonnes secondaires */
                .notes-table th:nth-child(4),
                .notes-table td:nth-child(4) { display: none; }
                }
            `}</style>

            {/* ── TOGGLE ── */}
            <button className="ndf-toggle" onClick={() => setSidebarOpen(o => !o)} style={{ position: 'fixed', top: 16, left: sidebarOpen ? 212 : 18, zIndex: 200, width: 32, height: 32, background: 'var(--bg-sidebar)', border: '2px solid rgba(255,255,255,.25)', borderRadius: '50%', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontSize: 14, fontWeight: 700, boxShadow: '0 2px 8px rgba(0,0,0,.3)', transition: 'left 0.3s ease' }}>
                {sidebarOpen ? '◀' : '▶'}
            </button>

            {sidebarOpen && <div className="sidebar-overlay" onClick={() => setSidebarOpen(false)} style={{ display: 'none' }} />}

            {/* ── SIDEBAR ── */}
            <aside className={`ndf-aside${sidebarOpen ? ' open' : ''}`} style={{ width: sidebarOpen ? 248 : 64, minHeight: '100vh', background: 'var(--bg-sidebar)', position: 'fixed', top: 0, left: 0, bottom: 0, display: 'flex', flexDirection: 'column', zIndex: 100, transition: 'width 0.3s ease', overflow: 'hidden' }}>
                <div style={{ padding: sidebarOpen ? '22px 20px 18px' : '22px 13px 18px', borderBottom: '1px solid rgba(255,255,255,.15)', display: 'flex', alignItems: 'center', gap: 12, overflow: 'hidden' }}>
                    <div style={{ width: 38, height: 38, background: 'rgba(255,255,255,.2)', borderRadius: 10, display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', flexShrink: 0 }}><Receipt size={20} /></div>
                    {sidebarOpen && <div><div style={{ color: '#fff', fontSize: 15, fontWeight: 700 }}>NDF</div><div style={{ color: 'rgba(255,255,255,.55)', fontSize: 10 }}>ENSUP Group</div></div>}
                </div>

                <div style={{ padding: sidebarOpen ? '14px 20px' : '14px 13px', borderBottom: '1px solid rgba(255,255,255,.15)', display: 'flex', alignItems: 'center', gap: 10, overflow: 'hidden' }}>
                    <div style={{ width: 36, height: 36, background: 'rgba(255,255,255,.25)', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontWeight: 700, fontSize: 13, flexShrink: 0 }}>{initials}</div>
                    {sidebarOpen && <div style={{ overflow: 'hidden' }}>
                        <div style={{ color: '#fff', fontSize: 13, fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{user?.name || '-'}</div>
                        <div style={{ display: 'inline-block', background: 'rgba(255,255,255,.2)', color: '#fff', fontSize: 10, fontWeight: 700, padding: '2px 7px', borderRadius: 4, textTransform: 'uppercase', marginTop: 2 }}>{user?.role || 'Collaborateur'}</div>
                    </div>}
                </div>

                <RoleSwitcherSidebar />

                <nav style={{ flex: 1, padding: '10px 10px 0', overflowY: 'auto' }}>
                    {sidebarOpen && <div style={{ color: 'rgba(255,255,255,.4)', fontSize: 10, fontWeight: 700, textTransform: 'uppercase', letterSpacing: 1, padding: '10px 12px 6px' }}>Menu</div>}
                    {menuItems.map(item => (
                        <button key={item.id} onClick={() => nav(item.id)} title={!sidebarOpen ? item.label : undefined} style={{ width: '100%', display: 'flex', alignItems: 'center', gap: 10, padding: sidebarOpen ? '10px 12px' : '10px 0', justifyContent: sidebarOpen ? 'flex-start' : 'center', borderRadius: 8, border: 'none', cursor: 'pointer', marginBottom: 2, fontFamily: 'inherit', fontSize: 13.5, textAlign: 'left', background: section === item.id ? 'rgba(255,255,255,.2)' : 'transparent', color: section === item.id ? '#fff' : 'rgba(255,255,255,.7)', fontWeight: section === item.id ? 700 : 400, transition: 'all 0.15s', position: 'relative' }}>
                            <span style={{ width: 20, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>{item.icon}</span>
                            {sidebarOpen && <span style={{ flex: 1 }}>{item.label}</span>}
                            {sidebarOpen && (item as any).badge > 0 && <span style={{ background: '#ef4444', color: '#fff', fontSize: 10, fontWeight: 800, padding: '1px 6px', borderRadius: 10, minWidth: 18, textAlign: 'center' }}>{(item as any).badge}</span>}
                            {!sidebarOpen && (item as any).badge > 0 && <span style={{ position: 'absolute', top: 4, right: 4, background: '#ef4444', color: '#fff', fontSize: 9, fontWeight: 800, borderRadius: '50%', width: 14, height: 14, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>{(item as any).badge}</span>}
                        </button>
                    ))}
                </nav>

                <div style={{ padding: '12px 10px', borderTop: '1px solid rgba(255,255,255,.15)' }}>
                    <button onClick={logout} title={!sidebarOpen ? 'Déconnexion' : undefined} style={{ width: '100%', display: 'flex', alignItems: 'center', gap: 10, padding: sidebarOpen ? '10px 12px' : '10px 0', justifyContent: sidebarOpen ? 'flex-start' : 'center', borderRadius: 8, border: 'none', cursor: 'pointer', fontFamily: 'inherit', fontSize: 13.5, color: 'rgba(255,255,255,.6)', background: 'transparent' }}>
                        <span style={{ width: 20, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}><LogOut size={16} /></span>
                        {sidebarOpen && <span>Déconnexion</span>}
                    </button>
                </div>
            </aside>

            {/* ── MAIN ── */}
            <main className="ndf-main" style={{ marginLeft: sidebarOpen ? 248 : 64, flex: 1, padding: 'clamp(14px, 2vw, 28px) clamp(16px, 2.5vw, 32px)', minHeight: '100vh', transition: 'margin-left 0.3s ease' }}>

                {/* Header */}
                <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 28, flexWrap: 'wrap', gap: 12 }}>
                    <div>
                        <h1 style={{ fontSize: 22, fontWeight: 800, color: 'var(--text-heading)', margin: 0 }}>{sectionTitles[section] || section}</h1>
                        <div style={{ fontSize: 12, color: 'var(--text-muted)', marginTop: 3 }}>{new Date().toLocaleDateString('fr-FR', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })}</div>
                    </div>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                        <ThemeToggleButton />
                        <div style={{ position: 'relative' }}>
                            <button onClick={() => setNotifOpen(!notifOpen)} style={{ background: 'var(--header-btn-bg)', border: '1px solid var(--header-btn-border)', borderRadius: 10, width: 40, height: 40, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 20 }}>🔔</button>
                            {nonLues > 0 && <span style={{ position: 'absolute', top: -4, right: -4, background: '#ef4444', color: '#fff', fontSize: 10, fontWeight: 800, borderRadius: 10, padding: '1px 5px', minWidth: 16, textAlign: 'center' }}>{nonLues}</span>}
                            {notifOpen && (
                                <div style={{ position: 'absolute', right: 0, top: 48, width: 340, maxHeight: 420, overflowY: 'auto', background: 'var(--bg-card)', borderRadius: 12, boxShadow: 'var(--shadow-notif)', border: '1px solid var(--border-card)', zIndex: 200 }}>
                                    <div style={{ padding: '14px 16px', borderBottom: '1px solid var(--border-divider)', fontWeight: 700, fontSize: 13, color: 'var(--text-primary)' }}>
                                        Notifications {nonLues > 0 && <span style={{ color: '#ef4444' }}>({nonLues})</span>}
                                    </div>
                                    {notifications.length === 0
                                        ? <div style={{ padding: 24, textAlign: 'center', color: 'var(--text-muted)', fontSize: 13 }}>Aucune notification</div>
                                        : notifications.map(n => (
                                            <div key={n.id} onClick={() => marquerNotifLue(n.id)} style={{ padding: '12px 16px', borderBottom: '1px solid var(--border-divider)', background: n.Lu ? 'var(--bg-card)' : 'var(--bg-notif-unread)', cursor: 'pointer' }}>
                                                <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--text-primary)', marginBottom: 3 }}>{n.Titre}</div>
                                                <div style={{ fontSize: 12, color: 'var(--text-secondary)', lineHeight: 1.4 }}>{n.Message}</div>
                                                <div style={{ fontSize: 10, color: 'var(--text-muted)', marginTop: 4 }}>{new Date(n.DateCreation).toLocaleDateString('fr-FR', { day: '2-digit', month: 'short', hour: '2-digit', minute: '2-digit' })}</div>
                                            </div>
                                        ))
                                    }
                                </div>
                            )}
                        </div>
                        <button style={btnPrimary} onClick={() => nav('nouvelle')}><PlusCircle size={16} /><span>Nouvelle note</span></button>
                    </div>
                </div>

                {/* ════════════════════════════════════════ */}
                {/* ACCUEIL                                  */}
                {/* ════════════════════════════════════════ */}
                {section === 'accueil' && (
                    <div style={{ display: 'flex', flexDirection: 'column', gap: 24 }}>

                        {/* ── STAT CARDS ── */}
                        <div className="stat-grid" style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(160px, 1fr))', gap: 10 }}>
                            {statCards.map((c, i) => (
                                <div key={i} style={{ ...cardStyle, padding: '14px 16px', borderLeft: `4px solid ${c.accent}` }}>
                                    <div style={{ fontSize: 20, fontWeight: 900, color: c.accent, marginBottom: 3 }}>{c.value}</div>
                                    <div style={{ fontSize: 12, fontWeight: 700, color: 'var(--text-primary)' }}>{c.label}</div>
                                    <div style={{ fontSize: 10, color: 'var(--text-muted)', marginTop: 1 }}>{c.sub}</div>
                                </div>
                            ))}
                        </div>
                        <div style={{ display: 'grid', gridTemplateColumns: (canValidate || isVerificateurFinance || isValidateurFinance || isPresident) ? '1fr 1fr' : '1fr', gap: 20 }}>
                            {/* ── SECTION 1 : MES NOTES ── */}
                            <div style={cardStyle}>
                                <div style={{
                                    padding: '16px 20px',
                                    borderBottom: '1px solid var(--border-divider)',
                                    display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                                    background: 'linear-gradient(90deg, #eef2ff, var(--bg-card))',
                                }}>
                                    <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                                        <div style={{
                                            width: 32, height: 32, borderRadius: 8,
                                            background: 'linear-gradient(135deg,#6366f1,#4f46e5)',
                                            display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 15
                                        }}>📋</div>
                                        <div>
                                            <div style={{ fontSize: 14, fontWeight: 800, color: 'var(--text-primary)' }}>Mes notes</div>
                                            <div style={{ fontSize: 11, color: 'var(--text-muted)' }}>{notes.length} note{notes.length > 1 ? 's' : ''} au total</div>
                                        </div>
                                    </div>
                                    <button
                                        onClick={() => nav('mesnotes')}
                                        style={{
                                            display: 'flex', alignItems: 'center', gap: 6,
                                            padding: '7px 14px',
                                            background: 'linear-gradient(135deg,#6366f1,#4f46e5)',
                                            color: '#fff', border: 'none', borderRadius: 8,
                                            cursor: 'pointer', fontFamily: 'inherit',
                                            fontSize: 12, fontWeight: 700,
                                        }}>
                                        Voir tout →
                                    </button>
                                </div>

                                {/* Mini stats mes notes */}
                              

                                {/* Dernières notes */}
                                <div style={{ padding: 16, display: 'flex', flexDirection: 'column', gap: 8 }}>
                                    {notes.length === 0 ? (
                                        <div style={{ padding: '24px', textAlign: 'center', color: 'var(--text-muted)', fontSize: 13 }}>
                                            Aucune note de frais
                                        </div>
                                    ) : notes.slice(0, 4).map(note => (
                                        <div
                                            key={note.id}
                                            onClick={() => { nav('mesnotes'); setSelectedNote(note); }}
                                            style={{
                                                display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                                                padding: '10px 12px',
                                                border: '1.5px solid var(--border-card)',
                                                borderRadius: 10, cursor: 'pointer',
                                                background: 'var(--bg-card)',
                                                transition: 'all 0.15s',
                                            }}
                                            onMouseEnter={e => {
                                                e.currentTarget.style.borderColor = '#6366f1';
                                                e.currentTarget.style.background = '#eef2ff';
                                            }}
                                            onMouseLeave={e => {
                                                e.currentTarget.style.borderColor = 'var(--border-card)';
                                                e.currentTarget.style.background = 'var(--bg-card)';
                                            }}
                                        >
                                            <div style={{ minWidth: 0 }}>
                                                <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 2 }}>
                                                    <span style={{ fontFamily: 'monospace', fontSize: 11, color: '#6366f1', fontWeight: 700 }}>
                                                        {note.reference || `#${note.id}`}
                                                    </span>
                                                    {tagStatut(note.statut || 'brouillon')}
                                                </div>
                                                <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--text-primary)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                                                    {note.libelle}
                                                </div>
                                                <div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 1 }}>
                                                    {note.date ? new Date(note.date).toLocaleDateString('fr-FR') : '—'}
                                                </div>
                                            </div>
                                            <div style={{ fontSize: 15, fontWeight: 900, color: 'var(--text-primary)', flexShrink: 0, marginLeft: 12 }}>
                                                {fmt(note.montant || 0)}
                                            </div>
                                        </div>
                                    ))}

                                    {notes.length > 4 && (
                                        <button
                                            onClick={() => nav('mesnotes')}
                                            style={{
                                                padding: '8px', background: 'none',
                                                border: '1px dashed var(--border-input)',
                                                borderRadius: 8, cursor: 'pointer',
                                                fontFamily: 'inherit', fontSize: 12,
                                                color: 'var(--text-muted)', fontWeight: 600,
                                            }}>
                                            + {notes.length - 4} autres notes
                                        </button>
                                    )}

                                    <button
                                        onClick={() => nav('nouvelle')}
                                        style={{
                                            ...btnPrimary, justifyContent: 'center',
                                            marginTop: 4, fontSize: 13,
                                        }}>
                                        ＋ Nouvelle note
                                    </button>
                                </div>
                            </div>
                            {isVerificateurFinance && (
                                <div style={cardStyle}>
                                    <div style={{
                                        padding: '16px 20px',
                                        borderBottom: '1px solid var(--border-divider)',
                                        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                                        background: 'linear-gradient(90deg, #ede9fe, var(--bg-card))',
                                    }}>
                                        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                                            <div style={{
                                                width: 32, height: 32, borderRadius: 8,
                                                background: 'linear-gradient(135deg,#7c3aed,#6d28d9)',
                                                display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 15
                                            }}>🔍</div>
                                            <div>
                                                <div style={{ fontSize: 14, fontWeight: 800, color: 'var(--text-primary)' }}>
                                                    Notes à vérifier
                                                    {notesAVerifier.length > 0 && (
                                                        <span style={{
                                                            marginLeft: 8, background: '#ef4444', color: '#fff',
                                                            fontSize: 11, fontWeight: 800, padding: '2px 7px', borderRadius: 10
                                                        }}>{notesAVerifier.length}</span>
                                                    )}
                                                </div>
                                                <div style={{ fontSize: 11, color: 'var(--text-muted)' }}>
                                                    {notesAVerifier.length === 0 ? 'Aucune note à contrôler' : `${notesAVerifier.length} note${notesAVerifier.length > 1 ? 's' : ''} à contrôler`}
                                                </div>
                                            </div>
                                        </div>
                                        <button
                                            onClick={() => nav('verification')}
                                            style={{
                                                display: 'flex', alignItems: 'center', gap: 6,
                                                padding: '7px 14px',
                                                background: 'linear-gradient(135deg,#7c3aed,#6d28d9)',
                                                color: '#fff', border: 'none', borderRadius: 8,
                                                cursor: 'pointer', fontFamily: 'inherit',
                                                fontSize: 12, fontWeight: 700,
                                            }}>
                                            Voir tout →
                                        </button>
                                    </div>

                                    {/* Mini stat */}
                                    <div style={{ borderBottom: '1px solid var(--border-divider)', padding: '12px 16px', textAlign: 'center', background: '#f5f3ff' }}>
                                        <div style={{ fontSize: 20, fontWeight: 900, color: '#7c3aed' }}>
                                            {notesAVerifier.length}
                                        </div>
                                        <div style={{ fontSize: 10, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', marginTop: 2 }}>
                                            En attente de vérification Finance
                                        </div>
                                    </div>

                                    {/* Liste */}
                                    <div style={{ padding: 16, display: 'flex', flexDirection: 'column', gap: 8 }}>
                                        {notesAVerifier.length === 0 ? (
                                            <div style={{
                                                padding: '32px 16px', textAlign: 'center',
                                                color: 'var(--text-muted)', fontSize: 13,
                                                display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8,
                                            }}>
                                                <span style={{ fontSize: 32 }}>✅</span>
                                                Aucune note en attente de vérification !
                                            </div>
                                        ) : notesAVerifier.slice(0, 4).map(note => (
                                            <div
                                                key={note.id}
                                                onClick={() => nav('verification')}
                                                style={{
                                                    display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                                                    padding: '10px 12px',
                                                    border: '1.5px solid var(--border-card)',
                                                    borderRadius: 10, cursor: 'pointer',
                                                    background: 'var(--bg-card)',
                                                    transition: 'all 0.15s',
                                                }}
                                                onMouseEnter={e => {
                                                    e.currentTarget.style.borderColor = '#7c3aed';
                                                    e.currentTarget.style.background = '#f5f3ff';
                                                }}
                                                onMouseLeave={e => {
                                                    e.currentTarget.style.borderColor = 'var(--border-card)';
                                                    e.currentTarget.style.background = 'var(--bg-card)';
                                                }}
                                            >
                                                <div style={{ minWidth: 0 }}>
                                                    <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 2 }}>
                                                        <span style={{ fontFamily: 'monospace', fontSize: 11, color: '#7c3aed', fontWeight: 700 }}>
                                                            {note.reference || `#${note.id}`}
                                                        </span>
                                                        {tagStatut(note.statut || 'brouillon')}
                                                    </div>
                                                    <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--text-primary)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                                                        {note.libelle}
                                                    </div>
                                                    <div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 1 }}>
                                                        👤 {note.collaborateur} · {note.date ? new Date(note.date).toLocaleDateString('fr-FR') : '—'}
                                                    </div>
                                                </div>
                                                <div style={{ fontSize: 15, fontWeight: 900, color: 'var(--text-primary)', flexShrink: 0, marginLeft: 12 }}>
                                                    {fmt(note.montant || 0)}
                                                </div>
                                            </div>
                                        ))}

                                        {notesAVerifier.length > 4 && (
                                            <button
                                                onClick={() => nav('verification')}
                                                style={{
                                                    padding: '8px', background: 'none',
                                                    border: '1px dashed var(--border-input)',
                                                    borderRadius: 8, cursor: 'pointer',
                                                    fontFamily: 'inherit', fontSize: 12,
                                                    color: 'var(--text-muted)', fontWeight: 600,
                                                }}>
                                                + {notesAVerifier.length - 4} autres notes à vérifier
                                            </button>
                                        )}

                                        {notesAVerifier.length > 0 && (
                                            <button
                                                onClick={() => nav('verification')}
                                                style={{
                                                    display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
                                                    padding: '11px 22px', marginTop: 4,
                                                    background: 'linear-gradient(135deg,#7c3aed,#6d28d9)',
                                                    color: '#fff', border: 'none', borderRadius: 10,
                                                    cursor: 'pointer', fontFamily: 'inherit',
                                                    fontSize: 13, fontWeight: 700,
                                                    boxShadow: '0 4px 14px rgba(124,58,237,.35)',
                                                }}>
                                                🔍 Vérifier les {notesAVerifier.length} note{notesAVerifier.length > 1 ? 's' : ''}
                                            </button>
                                        )}
                                    </div>
                                </div>
                            )}
                            {isVerificateurFinance && docsAValider.length > 0 && (
                                <div style={cardStyle}>
                                    <div style={{
                                        padding: '16px 20px',
                                        borderBottom: '1px solid var(--border-divider)',
                                        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                                        background: 'linear-gradient(90deg, #fef3c7, var(--bg-card))',
                                    }}>
                                        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                                            <div style={{
                                                width: 32, height: 32, borderRadius: 8,
                                                background: 'linear-gradient(135deg,#d97706,#b45309)',
                                                display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 15
                                            }}>📄</div>
                                            <div>
                                                <div style={{ fontSize: 14, fontWeight: 800, color: 'var(--text-primary)' }}>
                                                    Documents à valider
                                                    <span style={{
                                                        marginLeft: 8, background: '#ef4444', color: '#fff',
                                                        fontSize: 11, fontWeight: 800, padding: '2px 7px', borderRadius: 10
                                                    }}>{docsAValider.filter((d: any) => d.statut === 'en_attente').length}</span>
                                                </div>
                                                <div style={{ fontSize: 11, color: 'var(--text-muted)' }}>
                                                    RIB, cartes grises et permis à contrôler
                                                </div>
                                            </div>
                                        </div>
                                        <button
                                            onClick={() => nav('docsavalider')}
                                            style={{
                                                display: 'flex', alignItems: 'center', gap: 6,
                                                padding: '7px 14px',
                                                background: 'linear-gradient(135deg,#d97706,#b45309)',
                                                color: '#fff', border: 'none', borderRadius: 8,
                                                cursor: 'pointer', fontFamily: 'inherit',
                                                fontSize: 12, fontWeight: 700,
                                            }}>
                                            Voir tout →
                                        </button>
                                    </div>
                                </div>
                            )}
                            {isValidateurFinance && (
                                <div style={cardStyle}>
                                    <div style={{
                                        padding: '16px 20px',
                                        borderBottom: '1px solid var(--border-divider)',
                                        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                                        background: 'linear-gradient(90deg, #f0fdf4, var(--bg-card))',
                                    }}>
                                        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                                            <div style={{
                                                width: 32, height: 32, borderRadius: 8,
                                                background: 'linear-gradient(135deg,#10b981,#059669)',
                                                display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 15
                                            }}>💶</div>
                                            <div>
                                                <div style={{ fontSize: 14, fontWeight: 800, color: 'var(--text-primary)' }}>
                                                    Paiements à valider
                                                    {notesVerifiees.length > 0 && (
                                                        <span style={{
                                                            marginLeft: 8, background: '#ef4444', color: '#fff',
                                                            fontSize: 11, fontWeight: 800, padding: '2px 7px', borderRadius: 10
                                                        }}>{notesVerifiees.length}</span>
                                                    )}
                                                </div>
                                                <div style={{ fontSize: 11, color: 'var(--text-muted)' }}>
                                                    {notesVerifiees.length === 0 ? 'Aucun paiement en attente' : `${notesVerifiees.length} note${notesVerifiees.length > 1 ? 's' : ''} vérifiée${notesVerifiees.length > 1 ? 's' : ''} à régler`}
                                                </div>
                                            </div>
                                        </div>
                                        <button
                                            onClick={() => nav('paiements')}
                                            style={{
                                                display: 'flex', alignItems: 'center', gap: 6,
                                                padding: '7px 14px',
                                                background: 'linear-gradient(135deg,#10b981,#059669)',
                                                color: '#fff', border: 'none', borderRadius: 8,
                                                cursor: 'pointer', fontFamily: 'inherit',
                                                fontSize: 12, fontWeight: 700,
                                            }}>
                                            Voir tout →
                                        </button>
                                    </div>

                                    {/* Mini stats */}
                                    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 0, borderBottom: '1px solid var(--border-divider)' }}>
                                        {[
                                            { label: 'À régler', value: notesVerifiees.length, color: '#10b981', bg: '#f0fdf4' },
                                            { label: 'Volume', value: fmt(notesVerifiees.reduce((s, n) => s + (n.montant || 0), 0)), color: '#6366f1', bg: '#eef2ff' },
                                        ].map((s, i) => (
                                            <div key={i} style={{ padding: '12px 16px', textAlign: 'center', background: s.bg, borderRight: i === 0 ? '1px solid var(--border-divider)' : 'none' }}>
                                                <div style={{ fontSize: i === 0 ? 20 : 14, fontWeight: 900, color: s.color }}>{s.value}</div>
                                                <div style={{ fontSize: 10, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', marginTop: 2 }}>{s.label}</div>
                                            </div>
                                        ))}
                                    </div>

                                    {/* Liste */}
                                    <div style={{ padding: 16, display: 'flex', flexDirection: 'column', gap: 8 }}>
                                        {notesVerifiees.length === 0 ? (
                                            <div style={{
                                                padding: '32px 16px', textAlign: 'center',
                                                color: 'var(--text-muted)', fontSize: 13,
                                                display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8,
                                            }}>
                                                <span style={{ fontSize: 32 }}>🎉</span>
                                                Aucun paiement en attente !
                                            </div>
                                        ) : notesVerifiees.slice(0, 4).map(note => (
                                            <div
                                                key={note.id}
                                                onClick={() => nav('paiements')}
                                                style={{
                                                    display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                                                    padding: '10px 12px',
                                                    border: '1.5px solid var(--border-card)',
                                                    borderRadius: 10, cursor: 'pointer',
                                                    background: 'var(--bg-card)',
                                                    transition: 'all 0.15s',
                                                }}
                                                onMouseEnter={e => {
                                                    e.currentTarget.style.borderColor = '#10b981';
                                                    e.currentTarget.style.background = '#f0fdf4';
                                                }}
                                                onMouseLeave={e => {
                                                    e.currentTarget.style.borderColor = 'var(--border-card)';
                                                    e.currentTarget.style.background = 'var(--bg-card)';
                                                }}
                                            >
                                                <div style={{ minWidth: 0 }}>
                                                    <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 2 }}>
                                                        <span style={{ fontFamily: 'monospace', fontSize: 11, color: '#10b981', fontWeight: 700 }}>
                                                            {note.reference || `#${note.id}`}
                                                        </span>
                                                        {tagStatut(note.statut || 'brouillon')}
                                                    </div>
                                                    <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--text-primary)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                                                        {note.libelle}
                                                    </div>
                                                    <div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 1 }}>
                                                        👤 {note.collaborateur} · {note.date ? new Date(note.date).toLocaleDateString('fr-FR') : '—'}
                                                    </div>
                                                </div>
                                                <div style={{ fontSize: 15, fontWeight: 900, color: '#10b981', flexShrink: 0, marginLeft: 12 }}>
                                                    {fmt(note.montant || 0)}
                                                </div>
                                            </div>
                                        ))}

                                        {notesVerifiees.length > 4 && (
                                            <button
                                                onClick={() => nav('paiements')}
                                                style={{
                                                    padding: '8px', background: 'none',
                                                    border: '1px dashed var(--border-input)',
                                                    borderRadius: 8, cursor: 'pointer',
                                                    fontFamily: 'inherit', fontSize: 12,
                                                    color: 'var(--text-muted)', fontWeight: 600,
                                                }}>
                                                + {notesVerifiees.length - 4} autres notes à régler
                                            </button>
                                        )}

                                        {/* Indicateur config débiteur */}
                                        {selectedNoteIds.length > 0 && (() => {
                                            // Trouver le campus dominant des notes sélectionnées
                                            const selectedNotes = notesApprouvees.filter(n => selectedNoteIds.includes(n.id));
                                            const campusCounts: Record<string, number> = {};
                                            selectedNotes.forEach(n => {
                                                const code = normalizeCampus(n.campus || '') || n.campus || 'global';
                                                campusCounts[code] = (campusCounts[code] || 0) + 1;
                                            });
                                            const campusDominant = Object.entries(campusCounts).sort((a, b) => b[1] - a[1])[0]?.[0];
                                            return (
                                                <div style={{
                                                    display: 'flex', alignItems: 'center', gap: 8,
                                                    padding: '8px 14px',
                                                    background: '#eef2ff', border: '1px solid #c7d2fe', borderRadius: 8,
                                                    fontSize: 12, color: '#4338ca', fontWeight: 600,
                                                }}>
                                                    🏦 Compte débiteur : <strong>{campusDominant || 'global'}</strong>
                                                </div>
                                            );
                                        })()}

                                       
                                    </div>
                                </div>
                            )}

                                     {/* ── SECTION : VIREMENTS À VALIDER (Président) ── */}
                            {isPresident && (
                                <div style={cardStyle}>
                                    <div style={{
                                        padding: '16px 20px',
                                        borderBottom: '1px solid var(--border-divider)',
                                        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                                        background: 'linear-gradient(90deg, #eff6ff, var(--bg-card))',
                                    }}>
                                        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                                            <div style={{
                                                width: 32, height: 32, borderRadius: 8,
                                                background: 'linear-gradient(135deg,#1e3a5f,#1d4ed8)',
                                                display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 15,
                                            }}>💼</div>
                                            <div>
                                                <div style={{ fontSize: 14, fontWeight: 800, color: 'var(--text-primary)' }}>
                                                    Virements à valider
                                                    {notesEnAttentePresident.length > 0 && (
                                                        <span style={{
                                                            marginLeft: 8, background: '#ef4444', color: '#fff',
                                                            fontSize: 11, fontWeight: 800, padding: '2px 7px', borderRadius: 10,
                                                        }}>{notesEnAttentePresident.length}</span>
                                                    )}
                                                </div>
                                                <div style={{ fontSize: 11, color: 'var(--text-muted)' }}>
                                                    {notesEnAttentePresident.length === 0
                                                        ? 'Aucun virement en attente'
                                                        : `${notesEnAttentePresident.length} virement(s) requièrent votre validation`
                                                    }
                                                </div>
                                            </div>
                                        </div>
                                        <button
                                            onClick={() => nav('president')}
                                            style={{
                                                display: 'flex', alignItems: 'center', gap: 6,
                                                padding: '7px 14px',
                                                background: 'linear-gradient(135deg,#1e3a5f,#1d4ed8)',
                                                color: '#fff', border: 'none', borderRadius: 8,
                                                cursor: 'pointer', fontFamily: 'inherit',
                                                fontSize: 12, fontWeight: 700,
                                            }}>
                                            Voir tout →
                                        </button>
                                    </div>

                                    {/* Mini stat */}
                                    <div style={{ borderBottom: '1px solid var(--border-divider)', padding: '12px 16px', textAlign: 'center', background: '#eff6ff' }}>
                                        <div style={{ fontSize: 20, fontWeight: 900, color: '#1d4ed8' }}>
                                            {notesEnAttentePresident.length}
                                        </div>
                                        <div style={{ fontSize: 10, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', marginTop: 2 }}>
                                            En attente de validation Président
                                        </div>
                                    </div>

                                    <div style={{ padding: 16, display: 'flex', flexDirection: 'column', gap: 8 }}>
                                        {notesEnAttentePresident.length === 0 ? (
                                            <div style={{
                                                padding: '32px 16px', textAlign: 'center',
                                                color: 'var(--text-muted)', fontSize: 13,
                                                display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8,
                                            }}>
                                                <span style={{ fontSize: 32 }}>✅</span>
                                                Aucun virement à valider !
                                            </div>
                                        ) : notesEnAttentePresident.slice(0, 4).map(note => (
                                            <div
                                                key={note.id}
                                                onClick={() => nav('president')}
                                                style={{
                                                    display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                                                    padding: '10px 12px',
                                                    border: '1.5px solid var(--border-card)',
                                                    borderRadius: 10, cursor: 'pointer',
                                                    background: 'var(--bg-card)', transition: 'all 0.15s',
                                                }}
                                                onMouseEnter={e => { e.currentTarget.style.borderColor = '#1d4ed8'; e.currentTarget.style.background = '#eff6ff'; }}
                                                onMouseLeave={e => { e.currentTarget.style.borderColor = 'var(--border-card)'; e.currentTarget.style.background = 'var(--bg-card)'; }}
                                            >
                                                <div style={{ minWidth: 0 }}>
                                                    <div style={{ fontFamily: 'monospace', fontSize: 11, color: '#1d4ed8', fontWeight: 700, marginBottom: 2 }}>
                                                        {note.reference || `#${note.id}`}
                                                    </div>
                                                    <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--text-primary)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                                                        {note.collaborateur}
                                                    </div>
                                                    <div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 1 }}>
                                                        {note.libelle}
                                                    </div>
                                                </div>
                                                <div style={{ fontSize: 15, fontWeight: 900, color: '#1d4ed8', flexShrink: 0, marginLeft: 12 }}>
                                                    {fmt(note.montant || 0)}
                                                </div>
                                            </div>
                                        ))}

                                        {notesEnAttentePresident.length > 0 && (
                                            <button
                                                onClick={() => nav('president')}
                                                style={{
                                                    display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
                                                    padding: '11px 22px', marginTop: 4,
                                                    background: 'linear-gradient(135deg,#1e3a5f,#1d4ed8)',
                                                    color: '#fff', border: 'none', borderRadius: 10,
                                                    cursor: 'pointer', fontFamily: 'inherit',
                                                    fontSize: 13, fontWeight: 700,
                                                    boxShadow: '0 4px 14px rgba(29,78,216,.35)',
                                                }}>
                                                💼 Valider {notesEnAttentePresident.length} virement{notesEnAttentePresident.length > 1 ? 's' : ''}
                                            </button>
                                        )}
                                    </div>
                                </div>
                            )}
                            {/* ── SECTION 2 : NOTES À VALIDER (seulement si validateur) ── */}
                            {canValidate && (
                                <div style={cardStyle}>
                                    <div style={{
                                        padding: '16px 20px',
                                        borderBottom: '1px solid var(--border-divider)',
                                        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                                        background: 'linear-gradient(90deg, #fef9c3, var(--bg-card))',
                                    }}>
                                        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                                            <div style={{
                                                width: 32, height: 32, borderRadius: 8,
                                                background: 'linear-gradient(135deg,#f59e0b,#d97706)',
                                                display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 15
                                            }}>✅</div>
                                            <div>
                                                <div style={{ fontSize: 14, fontWeight: 800, color: 'var(--text-primary)' }}>
                                                    Notes à valider
                                                    {pending.length > 0 && (
                                                        <span style={{
                                                            marginLeft: 8, background: '#ef4444', color: '#fff',
                                                            fontSize: 11, fontWeight: 800, padding: '2px 7px', borderRadius: 10
                                                        }}>{pending.length}</span>
                                                    )}
                                                </div>
                                                <div style={{ fontSize: 11, color: 'var(--text-muted)' }}>
                                                    {pending.length === 0 ? 'Aucune note en attente' : `${pending.length} note${pending.length > 1 ? 's' : ''} à traiter`}
                                                </div>
                                            </div>
                                        </div>
                                        <button
                                            onClick={() => nav('validation')}
                                            style={{
                                                display: 'flex', alignItems: 'center', gap: 6,
                                                padding: '7px 14px',
                                                background: 'linear-gradient(135deg,#f59e0b,#d97706)',
                                                color: '#fff', border: 'none', borderRadius: 8,
                                                cursor: 'pointer', fontFamily: 'inherit',
                                                fontSize: 12, fontWeight: 700,
                                            }}>
                                            Voir tout →
                                        </button>
                                    </div>

                                    {/* Mini stats validation */}
                                    <div style={{ borderBottom: '1px solid var(--border-divider)', padding: '12px 16px', textAlign: 'center', background: '#fffbeb' }}>
                                        <div style={{ fontSize: 20, fontWeight: 900, color: '#f59e0b' }}>
                                            {pending.length}
                                        </div>
                                        <div style={{ fontSize: 10, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', marginTop: 2 }}>
                                            En attente de validation
                                        </div>
                                    </div>

                                    {/* Liste notes pending */}
                                    <div style={{ padding: 16, display: 'flex', flexDirection: 'column', gap: 8 }}>
                                        {pending.length === 0 ? (
                                            <div style={{
                                                padding: '32px 16px', textAlign: 'center',
                                                color: 'var(--text-muted)', fontSize: 13,
                                                display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8,
                                            }}>
                                                <span style={{ fontSize: 32 }}>🎉</span>
                                                Tout est à jour, aucune note en attente !
                                            </div>
                                        ) : pending.slice(0, 4).map(note => (
                                            <div
                                                key={note.id}
                                                onClick={() => nav('validation')}
                                                style={{
                                                    display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                                                    padding: '10px 12px',
                                                    border: '1.5px solid var(--border-card)',
                                                    borderRadius: 10, cursor: 'pointer',
                                                    background: 'var(--bg-card)',
                                                    transition: 'all 0.15s',
                                                }}
                                                onMouseEnter={e => {
                                                    e.currentTarget.style.borderColor = '#f59e0b';
                                                    e.currentTarget.style.background = '#fffbeb';
                                                }}
                                                onMouseLeave={e => {
                                                    e.currentTarget.style.borderColor = 'var(--border-card)';
                                                    e.currentTarget.style.background = 'var(--bg-card)';
                                                }}
                                            >
                                                <div style={{ minWidth: 0 }}>
                                                    <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 2 }}>
                                                        <span style={{ fontFamily: 'monospace', fontSize: 11, color: '#6366f1', fontWeight: 700 }}>
                                                            {note.reference || `#${note.id}`}
                                                        </span>
                                                        {tagStatut(note.statut || 'brouillon')}
                                                        {(note as any).noteRefuseeId && (
                                                            <span style={{
                                                                background: '#fff7ed', color: '#c2410c',
                                                                fontSize: 10, fontWeight: 700,
                                                                padding: '1px 6px', borderRadius: 4,
                                                                border: '1px solid #fed7aa'
                                                            }}>🔄 Correction</span>
                                                        )}
                                                    </div>
                                                    <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--text-primary)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                                                        {note.libelle}
                                                    </div>
                                                    <div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 1 }}>
                                                        👤 {note.collaborateur} · {note.date ? new Date(note.date).toLocaleDateString('fr-FR') : '—'}
                                                    </div>
                                                </div>
                                                <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 4, flexShrink: 0, marginLeft: 12 }}>
                                                    <div style={{ fontSize: 15, fontWeight: 900, color: 'var(--text-primary)' }}>
                                                        {fmt(note.montant || 0)}
                                                    </div>
                                                    <span style={{
                                                        fontSize: 10, fontWeight: 700, color: '#fff',
                                                        background: normalizeStatut(note.statut || '') === 'enattente' ? '#f59e0b' : '#7c3aed',
                                                        padding: '2px 7px', borderRadius: 4
                                                    }}>
                                                        {normalizeStatut(note.statut || '') === 'enattente' ? 'N1' : 'N2'}
                                                    </span>
                                                </div>
                                            </div>
                                        ))}

                                        {pending.length > 4 && (
                                            <button
                                                onClick={() => nav('validation')}
                                                style={{
                                                    padding: '8px', background: 'none',
                                                    border: '1px dashed var(--border-input)',
                                                    borderRadius: 8, cursor: 'pointer',
                                                    fontFamily: 'inherit', fontSize: 12,
                                                    color: 'var(--text-muted)', fontWeight: 600,
                                                }}>
                                                + {pending.length - 4} autres notes à valider
                                            </button>
                                        )}

                                        {pending.length > 0 && (
                                            <button
                                                onClick={() => nav('validation')}
                                                style={{
                                                    display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
                                                    padding: '11px 22px', marginTop: 4,
                                                    background: 'linear-gradient(135deg,#f59e0b,#d97706)',
                                                    color: '#fff', border: 'none', borderRadius: 10,
                                                    cursor: 'pointer', fontFamily: 'inherit',
                                                    fontSize: 13, fontWeight: 700,
                                                    boxShadow: '0 4px 14px rgba(245,158,11,.35)',
                                                }}>
                                                ✅ Traiter les {pending.length} note{pending.length > 1 ? 's' : ''}
                                            </button>
                                        )}
                                    </div>
                                </div>
                            )}
                        </div>
                    </div>
                )}

       


                {/* ════════════════════════════════════════ */}
                {/* NOUVELLE NOTE                            */}
                {/* ════════════════════════════════════════ */}
                {section === 'nouvelle' && (
                    <NouvelleNote
                        key={`nouvelle-${activeBrouillonId || 'new'}-${libelle.slice(0, 10)}`}
                        apiBaseUrl={API}
                        authToken={token || ''}
                        onSubmit={(titre, dateDebut, dateFin, commentaire, depenses) =>
                            handleSoumettre(titre, dateDebut, dateFin, commentaire, depenses)}
                        onCancel={() => nav('accueil')}
                        initialBrouillonId={typeof activeBrouillonId === 'number' ? activeBrouillonId : null}
                        libelleInitial={libelle}
                        dateDebutInitiale={date}
                        commentaireInitial={description}
                        depensesInitiales={lignes}
                         onNavigateToProfil={() => nav('profil')}

                    />
                )}

                {/* ════════════════════════════════════════ */}
                {/* MES NOTES                                */}
                {/* ════════════════════════════════════════ */}
                {section === 'mesnotes' && (
                    <div style={{ 
                        display: 'flex', gap: 0,   // ← gap: 0 pour coller les colonnes
                        height: 'calc(100vh - 140px)', 
                        overflow: 'hidden',
                        background: 'var(--bg-card)',   // ← fond commun
                        borderRadius: 16,               // ← arrondi commun
                        border: '1px solid var(--border-card)',
                        boxShadow: 'var(--shadow-card)',
                    }}>

                        {/* ── COL GAUCHE : liste des notes (50%) ── */}
                        <div style={{ flex: '0 0 50%', minWidth: 0, display: 'flex', flexDirection: 'column', overflow: 'hidden', borderRight: '1px solid var(--border-divider)' }}>

                            <div style={{
                                padding: '14px 20px',
                                borderBottom: '1px solid var(--border-divider)',
                                display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap',
                                flexShrink: 0,
                            }}>
                                <h3 style={{ fontSize: 14, fontWeight: 700, margin: 0, flex: 1 }}>Mes notes de frais</h3>
                                <select
                                    value={mesNotesFiltreStatut}
                                    onChange={e => setMesNotesFiltreStatut(e.target.value)}
                                    style={{
                                        padding: '6px 10px', borderRadius: 8,
                                        border: '1.5px solid var(--border-divider)',
                                        fontSize: 12, background: 'var(--bg-input)',
                                        color: 'var(--text-primary)', cursor: 'pointer', outline: 'none',
                                    }}>
                                    <option value="">Tous les statuts</option>
                                  
                                    <option value="enattente">En attente</option>
                                    <option value="valide">Validation</option>
                                    <option value="approuve">Approuvé</option>
                                    <option value="verifie">Vérifié</option>
                                    <option value="paiementenattente">Paiement en attente</option>
                                    <option value="payee">Payée</option>
                                    <option value="refuse">Refusée</option>
                                    <option value="nonconformeverif">Non conforme</option>
                                </select>
                                {mesNotesFiltreStatut && (
                                    <button onClick={() => setMesNotesFiltreStatut('')} style={{
                                        padding: '5px 10px', borderRadius: 7,
                                        border: '1.5px solid #fca5a5', background: '#fef2f2',
                                        color: '#dc2626', fontSize: 12, fontWeight: 600,
                                        cursor: 'pointer', fontFamily: 'inherit',
                                    }}>✕</button>
                                )}
                            </div>

                            {/* Liste scrollable */}
                            <div style={{ flex: 1, overflowY: 'auto', padding: '12px 14px', display: 'flex', flexDirection: 'column', gap: 10 }}>
                                {(() => {
                                    const notesFiltrees = notes
                                        .filter(note => normalizeStatut(note.statut) !== 'brouillon')
                                        .filter(note => !mesNotesFiltreStatut || normalizeStatut(note.statut) === mesNotesFiltreStatut);

                                    if (notesFiltrees.length === 0) return (
                                        <div style={{ padding: '48px 24px', textAlign: 'center', color: 'var(--text-muted)' }}>
                                            <div style={{ fontSize: 32, marginBottom: 10 }}>📋</div>
                                            <p style={{ fontSize: 14 }}>
                                                {mesNotesFiltreStatut ? 'Aucune note pour ce statut.' : 'Aucune note de frais'}
                                            </p>
                                            <button onClick={() => nav('nouvelle')} style={{ ...btnPrimary, margin: '12px auto 0', fontSize: 13 }}>
                                                ＋ Nouvelle note
                                            </button>
                                        </div>
                                    );

                                    return notesFiltrees.map(note => {
                                        const isSelected = selectedNote?.id === note.id;
                                        return (
                                            <div
                                                key={note.id}
                                                onClick={() => {
                                                    if (note.statut === 'brouillon') {
                                                        const b = {
                                                            id: note.id as unknown as number,
                                                            libelle: note.libelle || '',
                                                            date: note.date ? String(note.date).split('T')[0] : today,
                                                            description: note.description || '',
                                                            lignesJson: note.lignesJson || '[]',
                                                            montant: note.montant || 0,
                                                            DateModification: note.DateModification || new Date().toISOString()
                                                        };
                                                        loadBrouillon(b);
                                                        nav('nouvelle');
                                                    } else {
                                                        setSelectedNote(isSelected ? null : note);
                                                    }
                                                }}
                                                style={{
                                                    border: `2px solid ${note.statut === 'brouillon' ? '#fde68a'
                                                        : isSelected ? '#6366f1'
                                                            : 'var(--border-card)'
                                                        }`,
                                                    borderRadius: 12, padding: '12px 14px',
                                                    background: note.statut === 'brouillon' ? '#fffbeb'
                                                        : isSelected ? '#eef2ff'
                                                            : 'var(--bg-card)',
                                                    cursor: 'pointer', transition: 'all 0.15s',
                                                    flexShrink: 0,
                                                }}
                                                onMouseEnter={e => {
                                                    if (!isSelected) e.currentTarget.style.borderColor = '#6366f1';
                                                }}
                                                onMouseLeave={e => {
                                                    if (!isSelected) e.currentTarget.style.borderColor =
                                                        note.statut === 'brouillon' ? '#fde68a' : 'var(--border-card)';
                                                }}
                                            >
                                                <StatutStepper statut={note.statut || 'brouillon'} />
                                                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12 }}>
                                                    <div style={{ minWidth: 0, flex: 1 }}>
                                                        <div style={{ fontFamily: 'monospace', fontSize: 11, color: '#6366f1', fontWeight: 700, marginBottom: 2 }}>
                                                            {note.reference || `#${note.id}`}
                                                        </div>
                                                        <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--text-primary)', marginBottom: 2, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                                                            {note.libelle}
                                                        </div>
                                                        <div style={{ fontSize: 11, color: 'var(--text-secondary)' }}>
                                                            {note.categorie && <span>{note.categorie} · </span>}
                                                            {note.date ? new Date(note.date).toLocaleDateString('fr-FR') : '-'}
                                                        </div>
                                                    </div>
                                                    <div style={{ textAlign: 'right', flexShrink: 0 }}>
                                                        <div style={{ fontSize: 16, fontWeight: 900, color: 'var(--text-primary)', marginBottom: 4 }}>
                                                            {fmt(note.montant || 0)}
                                                        </div>
                                                        {tagStatut(note.statut || 'brouillon')}
                                                    </div>
                                                </div>
                                            </div>
                                        );
                                    });
                                })()}
                            </div>

                            {/* Bouton bas fixe */}
                            <div style={{ padding: '12px 14px', borderTop: '1px solid var(--border-divider)', flexShrink: 0 }}>
                                <button onClick={() => nav('nouvelle')} style={{ ...btnPrimary, width: '100%', justifyContent: 'center', fontSize: 13 }}>
                                    <PlusCircle size={15} /> Nouvelle note
                                </button>
                            </div>
                        </div>

                        {/* ── COL DROITE : détail note (50%) ── */}
                        <div style={{ flex: '0 0 50%', minWidth: 0, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
                            {selectedNote ? (
                                <>
                                    {/* Header panneau détail */}
                                    <div style={{
                                        padding: '14px 20px', borderBottom: '1px solid var(--border-divider)',
                                        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                                        flexShrink: 0,
                                    }}>
                                        <div style={{ minWidth: 0 }}>
                                            <h3 style={{ fontSize: 14, fontWeight: 700, margin: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                                                {selectedNote.libelle || 'Détail de la note'}
                                            </h3>
                                            <div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 2, fontFamily: 'monospace' }}>
                                                {selectedNote.reference || `#${selectedNote.id}`}
                                            </div>
                                        </div>
                                        <button onClick={() => setSelectedNote(null)} style={{
                                            background: 'none', border: 'none', cursor: 'pointer',
                                            fontSize: 18, color: 'var(--text-muted)', flexShrink: 0, marginLeft: 12,
                                        }}>✕</button>
                                    </div>

                                    {/* Corps scrollable */}
                                    <div style={{ flex: 1, overflowY: 'auto', padding: '16px 20px' }}>
                                        <StatutStepper statut={selectedNote.statut || 'brouillon'} />

                                        {/* Info grid */}
                                        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10, marginBottom: 16 }}>
                                            {[
                                                { label: 'Référence', value: selectedNote.reference || `#${selectedNote.id}`, mono: true },
                                                { label: 'Statut', value: tagStatut(selectedNote.statut || 'brouillon'), isNode: true },
                                                { label: 'Catégorie', value: selectedNote.categorie },
                                                { label: 'Date', value: selectedNote.date ? new Date(selectedNote.date).toLocaleDateString('fr-FR') : '-' },
                                                { label: 'Montant TTC', value: fmt(selectedNote.montant || 0), bold: true },
                                                { label: 'Collaborateur', value: (selectedNote as any).collaborateur },
                                            ].filter(i => i.value).map(({ label, value, mono, bold, isNode }: any) => (
                                                <div key={label} style={{ background: 'var(--bg-input)', borderRadius: 8, padding: '8px 12px' }}>
                                                    <div style={{ fontSize: 10, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', marginBottom: 2 }}>{label}</div>
                                                    {isNode
                                                        ? <div style={{ marginTop: 2 }}>{value}</div>
                                                        : <div style={{ fontSize: 13, fontWeight: bold ? 800 : 600, color: mono ? '#6366f1' : 'var(--text-primary)', fontFamily: mono ? 'monospace' : 'inherit' }}>{value || '—'}</div>
                                                    }
                                                </div>
                                            ))}
                                        </div>

                                        {/* Refusée */}
                                        {normalizeStatut(selectedNote.statut || '') === 'refuse' && (
                                            <div style={{
                                                background: '#fef2f2', border: '1.5px solid #fecaca',
                                                borderLeft: '4px solid #ef4444', borderRadius: '0 8px 8px 0',
                                                padding: '14px 16px', marginBottom: 16,
                                            }}>
                                                <div style={{ fontSize: 13, fontWeight: 800, color: '#dc2626', marginBottom: 4 }}>
                                                    ❌ Note refusée — action requise
                                                </div>
                                                {selectedNote.motifRefus && (
                                                    <div style={{ fontSize: 12, color: '#991b1b', background: '#fee2e2', padding: '8px 10px', borderRadius: 6, marginBottom: 10, fontWeight: 600 }}>
                                                        Motif : {selectedNote.motifRefus}
                                                    </div>
                                                )}
                                                <button onClick={() => handleModifierNote(selectedNote)} style={{
                                                    display: 'flex', alignItems: 'center', gap: 6, padding: '9px 18px',
                                                    background: 'linear-gradient(135deg,#ef4444,#dc2626)',
                                                    color: '#fff', border: 'none', borderRadius: 8,
                                                    cursor: 'pointer', fontFamily: 'inherit', fontSize: 13, fontWeight: 700,
                                                }}>✏️ Corriger et resoumettre</button>
                                            </div>
                                        )}
                                        {/* Refusée par Finance */}
                                        {normalizeStatut(selectedNote.statut || '') === 'refuse_verif' && (
                                            <div style={{
                                                background: '#fef2f2', border: '1.5px solid #fecaca',
                                                borderLeft: '4px solid #dc2626', borderRadius: '0 8px 8px 0',
                                                padding: '14px 16px', marginBottom: 16,
                                            }}>
                                                <div style={{ fontSize: 13, fontWeight: 800, color: '#dc2626', marginBottom: 4 }}>
                                                    ❌ Note refusée par la Finance — action requise
                                                </div>
                                                {selectedNote.commentaireVerification && (
                                                    <div style={{ fontSize: 12, color: '#991b1b', background: '#fee2e2', padding: '8px 10px', borderRadius: 6, marginBottom: 10, fontWeight: 600 }}>
                                                        {selectedNote.commentaireVerification}
                                                    </div>
                                                )}
                                                <div style={{ fontSize: 12, color: '#7f1d1d', marginBottom: 10, lineHeight: 1.5 }}>
                                                    Le Vérificateur Finance a refusé certaines lignes. Corrigez-les puis resoumettez.
                                                </div>
                                                <button onClick={() => handleModifierNote(selectedNote)} style={{
                                                    display: 'flex', alignItems: 'center', gap: 6, padding: '9px 18px',
                                                    background: 'linear-gradient(135deg,#ef4444,#dc2626)',
                                                    color: '#fff', border: 'none', borderRadius: 8,
                                                    cursor: 'pointer', fontFamily: 'inherit', fontSize: 13, fontWeight: 700,
                                                    boxShadow: '0 4px 12px rgba(239,68,68,.3)',
                                                }}>✏️ Corriger et resoumettre</button>
                                            </div>
                                        )}

                                        {/* Modifiable si en attente */}
                                        {['enattente', 'en_attente', 'en attente'].includes(normalizeStatut(selectedNote.statut || '')) && (
                                            <div style={{
                                                padding: '12px 16px', background: 'linear-gradient(90deg,#eff6ff,#eef2ff)',
                                                border: '1.5px solid #c7d2fe', borderRadius: 10, marginBottom: 14,
                                                display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12,
                                            }}>
                                                <div>
                                                    <div style={{ fontSize: 12, fontWeight: 700, color: '#4338ca' }}>✏️ Note modifiable</div>
                                                    <div style={{ fontSize: 11, color: '#6366f1', marginTop: 2 }}>En attente — vous pouvez encore la modifier.</div>
                                                </div>
                                                <button onClick={() => handleModifierNote(selectedNote)} style={{ ...btnPrimary, fontSize: 12, padding: '8px 16px' }}>
                                                    ✏️ Modifier
                                                </button>
                                            </div>
                                        )}

                                        {/* Commentaires */}
                                        {selectedNote.commentaireN1 && (
                                            <div style={{ background: '#f0f9ff', border: '1px solid #bae6fd', borderRadius: 6, padding: '8px 12px', marginBottom: 8, fontSize: 12, color: '#0369a1' }}>
                                                💬 Commentaire N1 : {selectedNote.commentaireN1}
                                            </div>
                                        )}

                                        {/* Date paiement */}
                                        {selectedNote.datePaiement && (
                                            <div style={{ background: '#f0fdf4', border: '1px solid #86efac', borderRadius: 8, padding: '8px 12px', marginBottom: 12, fontSize: 12, color: '#15803d', fontWeight: 600 }}>
                                                💶 Payée le {new Date(selectedNote.datePaiement).toLocaleDateString('fr-FR')}
                                            </div>
                                        )}

                                        {/* Lignes détail */}
                                        <LignesDetail
                                            note={selectedNote}
                                            tarifKm={tarifKm}
                                            onPreview={(url, name) => setPreviewUrl({ url: proxyUrl(url), name })}
                                        />

                                        {/* Fichiers globaux */}
                                        {['approuve', 'verifie', 'paiementenattente', 'paiement_en_attente', 'payee'].includes(normalizeStatut(selectedNote.statut || '')) && (
                                            <FichiersGlobaux
                                                note={selectedNote}
                                                onPreview={(url, name) => setPreviewUrl({ url, name })}
                                                proxyFn={proxyUrl}
                                            />
                                        )}
                                    </div>
                                </>
                            ) : (
                                /* État vide — aucune note sélectionnée */
                                <div style={{
                                    flex: 1, display: 'flex', flexDirection: 'column',
                                    alignItems: 'center', justifyContent: 'center',
                                    color: 'var(--text-muted)', padding: 40, textAlign: 'center',
                                }}>
                                    <div style={{
                                        width: 64, height: 64, borderRadius: 16, marginBottom: 16,
                                        background: 'var(--bg-input)',
                                        display: 'flex', alignItems: 'center', justifyContent: 'center',
                                        fontSize: 28,
                                    }}>📋</div>
                                    <div style={{ fontSize: 15, fontWeight: 700, color: 'var(--text-secondary)', marginBottom: 8 }}>
                                        Sélectionnez une note
                                    </div>
                                    <div style={{ fontSize: 13, color: 'var(--text-muted)', lineHeight: 1.6, maxWidth: 260 }}>
                                        Cliquez sur une note à gauche pour afficher son détail, son statut et ses justificatifs ici.
                                    </div>
                                </div>
                            )}
                        </div>
                    </div>
                )}

                {/* ════════════════════════════════════════ */}
                {/* VALIDATION                               */}
                {/* ════════════════════════════════════════ */}
                {section === 'validation' && canValidate && (
                    <div style={{ 
                        display: 'flex', gap: 12, 
                        height: 'calc(100vh - 140px)', 
                        alignItems: 'stretch', 
                        overflow: 'hidden',
                        maxWidth: '100%',   // ← clé
                        minWidth: 0,        // ← clé
                    }}>

                        {/* COL 1 : liste notes */}
                        <div style={{ flex: noteDetail ? '0 0 240px' : '1 1 100%', minWidth: 0, background: 'var(--bg-card)', borderRadius: 16, border: '1px solid var(--border-card)', boxShadow: 'var(--shadow-card)', display: 'flex', flexDirection: 'column', overflow: 'hidden', transition: 'flex-basis 0.35s ease', maxWidth: noteDetail ? 240 : '100%' }}>
                            <div style={{ padding: '12px 16px', borderBottom: '1px solid var(--border-divider)', flexShrink: 0 }}>
                                <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--text-primary)' }}>
                                    À valider
                                    {pending.length > 0 && <span style={{ marginLeft: 8, background: '#ef4444', color: '#fff', fontSize: 10, padding: '1px 7px', borderRadius: 10 }}>{pending.length}</span>}
                                </div>
                            </div>
                            <div style={{ overflowY: 'auto', flex: 1, padding: 8, display: 'flex', flexDirection: 'column', gap: 6 }}>
                                {pending.length === 0
                                    ? <div style={{ padding: '32px 16px', textAlign: 'center', color: 'var(--text-muted)', fontSize: 13 }}>Aucune note en attente</div>
                                    : pending.map(note => {
                                        const isSelected = noteDetail?.id === note.id;
                                        return (
                                            <div key={note.id} onClick={() => { setNoteDetail(isSelected ? null : note); setInlinePreview(null); }} style={{
                                                padding: '10px 12px', borderRadius: 10, cursor: 'pointer',
                                                border: `1.5px solid ${isSelected ? '#6366f1' : 'var(--border-card)'}`,
                                                background: isSelected ? '#eef2ff' : 'var(--bg-card)',
                                                transition: 'all 0.15s',
                                            }}>
                                                <div style={{ fontFamily: 'monospace', fontSize: 10, color: '#6366f1', marginBottom: 3 }}>{note.reference || `#${note.id}`}</div>
                                                <div style={{ fontSize: 12, fontWeight: 700, color: 'var(--text-primary)', marginBottom: 2, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{note.libelle}</div>
                                                <div style={{ fontSize: 11, color: 'var(--text-muted)', marginBottom: 4, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{note.collaborateur}</div>
                                                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                                                    <span style={{
                                                        fontSize: 9, fontWeight: 700, color: '#fff',
                                                        background: normalizeStatut(note.statut || '') === 'enattente' ? '#f59e0b' : '#7c3aed',
                                                        padding: '2px 6px', borderRadius: 4
                                                    }}>{normalizeStatut(note.statut || '') === 'enattente' ? 'N1' : 'N2'}</span>
                                                    <span style={{ fontSize: 12, fontWeight: 800, color: 'var(--text-primary)' }}>{fmt(note.montant || 0)}</span>
                                                </div>
                                            </div>
                                        );
                                    })
                                }
                            </div>
                        </div>

                        {/* COL 2 + COL 3 : détail + justificatif */}
                        {noteDetail ? (
                            <>
                                {/* COL 2 : dépenses */}
                                <div style={{ flex: 1, minWidth: 0, ...cardStyle, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
                                    <div style={{ padding: '12px 16px', borderBottom: '1px solid var(--border-divider)', flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8 }}>
                                        <div style={{ minWidth: 0 }}>
                                            <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--text-primary)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                                                {noteDetail.collaborateur} · {fmt(noteDetail.montant || 0)}
                                            </div>
                                            <div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 1 }}>{noteDetail.libelle}</div>
                                        </div>
                                        <button onClick={() => setNoteDetail(null)} style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 18, color: 'var(--text-muted)', flexShrink: 0 }}>✕</button>
                                    </div>
                                    <div style={{ flex: 1, overflowY: 'auto', padding: 16 }}>
                                        <StatutStepper statut={noteDetail.statut || 'brouillon'} />
                                        {(noteDetail as any).noteRefuseeId && (
                                            <div style={{ background: '#fff7ed', border: '1.5px solid #fed7aa', borderLeft: '4px solid #f97316', borderRadius: '0 8px 8px 0', padding: '8px 12px', marginBottom: 10 }}>
                                                <div style={{ fontSize: 11, fontWeight: 700, color: '#c2410c' }}>🔄 Correction d'une note refusée</div>
                                                <div style={{ fontSize: 10, color: '#ea580c', marginTop: 2 }}>Ancienne référence : {(noteDetail as any).ancienneReference || `#${(noteDetail as any).noteRefuseeId}`}</div>
                                            </div>
                                        )}
                                        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginBottom: 12 }}>
                                            {[
                                                { label: 'Référence', value: noteDetail.reference || `#${noteDetail.id}`, mono: true },
                                                { label: 'Statut', value: tagStatut(noteDetail.statut || 'brouillon'), isNode: true },
                                                { label: 'Date', value: noteDetail.date ? new Date(noteDetail.date).toLocaleDateString('fr-FR') : '-' },
                                                { label: 'Montant TTC', value: fmt(noteDetail.montant || 0), bold: true },
                                            ].map(({ label, value, mono, bold, isNode }: any) => (
                                                <div key={label} style={{ background: 'var(--bg-input)', borderRadius: 8, padding: '7px 10px' }}>
                                                    <div style={{ fontSize: 10, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', marginBottom: 2 }}>{label}</div>
                                                    {isNode ? <div style={{ marginTop: 2 }}>{value}</div>
                                                        : <div style={{ fontSize: 12, fontWeight: bold ? 800 : 600, color: mono ? '#6366f1' : 'var(--text-primary)', fontFamily: mono ? 'monospace' : 'inherit' }}>{value}</div>}
                                                </div>
                                            ))}
                                        </div>
                                        {noteDetail.commentaireN1 && (
                                            <div style={{ background: '#f0f9ff', border: '1px solid #bae6fd', borderRadius: 6, padding: '7px 10px', marginBottom: 8, fontSize: 11, color: '#0369a1' }}>
                                                💬 Commentaire N1 : {noteDetail.commentaireN1}
                                            </div>
                                        )}
                                        <LignesDetail
                                            note={noteDetail!}
                                            tarifKm={tarifKm}
                                            onPreview={(url, name) => setInlinePreview({ url, name })}
                                        />
                                    </div>
                                    {/* Boutons fixes en bas */}
                                    <div style={{ padding: '12px 16px', borderTop: '1px solid var(--border-divider)', flexShrink: 0, display: 'flex', gap: 10, background: 'var(--bg-card)' }}>
                                        <button
                                            style={{ ...btnSuccess, flex: 1, justifyContent: 'center', display: 'flex', padding: '10px' }}
                                            onClick={() => { setMotifRefusInput(''); setModalValidation({ noteId: noteDetail.id, action: 'valider', onClose: () => setNoteDetail(null) }); }}>
                                            ✅ Valider
                                        </button>
                                        <button
                                            style={{ ...btnDanger, flex: 1, justifyContent: 'center', display: 'flex', padding: '10px' }}
                                            onClick={() => { setMotifRefusInput(''); setModalValidation({ noteId: noteDetail.id, action: 'refuser', onClose: () => setNoteDetail(null) }); }}>
                                            ❌ Refuser
                                        </button>
                                    </div>
                                </div>

                                {/* COL 3 : aperçu justificatif inline */}
                                {/* COL 3 : aperçu justificatif inline */}
                                <div style={{ flex: 1, minWidth: 0, ...cardStyle, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>

                                    <div style={{ padding: '12px 16px', borderBottom: '1px solid var(--border-divider)', flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                                        <div style={{ fontSize: 12, fontWeight: 700, color: 'var(--text-primary)' }}>
                                            {inlinePreview ? inlinePreview.name : 'Justificatif'}
                                        </div>
                                        {inlinePreview && (
                                            <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
                                                <a href={inlinePreview.url} target="_blank" rel="noreferrer"
                                                    style={{ fontSize: 11, color: '#6366f1', fontWeight: 600, textDecoration: 'none' }}>
                                                    ↗ Ouvrir
                                                </a>
                                                <button onClick={() => setInlinePreview(null)}
                                                    style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 16, color: 'var(--text-muted)' }}>✕</button>
                                            </div>
                                        )}
                                    </div>
                                    <div style={{ flex: 1, overflow: 'hidden', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--bg-input)' }}>
                                        {inlinePreview
                                            ? <InlinePreviewViewer item={inlinePreview} />
                                            : (
                                                <div style={{ textAlign: 'center', color: 'var(--text-muted)', padding: 24 }}>
                                                    <div style={{ fontSize: 36, marginBottom: 10 }}>📎</div>
                                                    <div style={{ fontSize: 12, lineHeight: 1.5 }}>Cliquez sur "Voir" dans une dépense pour afficher le justificatif ici</div>
                                                </div>
                                            )
                                        }
                                    </div>
                                </div>
                            </>
                        ) : (
                            <div style={{ flex: 1, minWidth: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--text-muted)', fontSize: 14 }}>
                           
                            </div>
                        )}
                    </div>
                )}
                {/* ════════════════════════════════════════ */}
                {/* MES VALIDATIONS                          */}
                {/* ════════════════════════════════════════ */}
                {section === 'mesvalidations' && canValidate && (
                    <div style={cardStyle}>
                        <div style={{ padding: '16px 24px', borderBottom: '1px solid var(--border-divider)' }}>
                            <h3 style={{ fontSize: 14, fontWeight: 700, margin: 0 }}>Historique de mes décisions</h3>
                        </div>
                        {historiqueValidateur.length === 0
                            ? <div style={{ padding: '48px 24px', textAlign: 'center', color: 'var(--text-muted)' }}><p style={{ fontSize: 14 }}>Aucune décision enregistrée</p></div>
                            : <div style={{ overflowX: 'auto' }}>
                                <table style={{ width: '100%', borderCollapse: 'collapse', minWidth: 600 }}>
                                    <thead>
                                        <tr style={{ background: 'var(--bg-input)' }}>
                                            {['Reference', 'Collaborateur', 'Montant', 'Niveau', 'Action', 'Date'].map(h => (
                                                <th key={h} style={{ padding: '10px 16px', textAlign: 'left', fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '0.6px', borderBottom: '1px solid var(--border-divider)' }}>{h}</th>
                                            ))}
                                        </tr>
                                    </thead>
                                    <tbody>
                                        {historiqueValidateur.map((h, i) => (
                                            <tr key={i} style={{ borderTop: '1px solid var(--border-divider)' }}>
                                                <td style={{ padding: '12px 16px', fontFamily: 'monospace', fontSize: 12, color: '#6366f1', fontWeight: 700 }}>{h.reference}</td>
                                                <td style={{ padding: '12px 16px', fontSize: 13 }}>{h.collaborateur}</td>
                                                <td style={{ padding: '12px 16px', fontWeight: 700 }}>{fmt(h.montant)}</td>
                                                <td style={{ padding: '12px 16px' }}>
                                                    <span style={{ background: h.Niveau === 'N1' ? '#dbeafe' : h.Niveau === 'VERIF' ? '#ede9fe' : '#ede9fe', color: h.Niveau === 'N1' ? '#1d4ed8' : '#7c3aed', fontSize: 11, fontWeight: 700, padding: '2px 8px', borderRadius: 6 }}>{h.Niveau}</span>
                                                </td>
                                                <td style={{ padding: '12px 16px' }}>
                                                    <span style={{ background: h.Action === 'valider' || h.Action === 'verifier' ? '#dcfce7' : '#fee2e2', color: h.Action === 'valider' || h.Action === 'verifier' ? '#15803d' : '#dc2626', fontSize: 11, fontWeight: 700, padding: '2px 8px', borderRadius: 6 }}>
                                                        {h.Action === 'valider' ? 'Validé' : h.Action === 'verifier' ? 'Vérifié' : 'Refusé'}
                                                    </span>
                                                </td>
                                                <td style={{ padding: '12px 16px', fontSize: 12, color: 'var(--text-muted)' }}>{new Date(h.DateAction).toLocaleDateString('fr-FR', { day: '2-digit', month: 'short', year: 'numeric' })}</td>
                                            </tr>
                                        ))}
                                    </tbody>
                                </table>
                            </div>
                        }
                    </div>
                )}

                {/* ════════════════════════════════════════ */}
                {/* HISTORIQUE                               */}
                {/* ════════════════════════════════════════ */}
                {section === 'historique' && (
                    <div style={cardStyle}>
                        <div style={{ padding: '16px 24px', borderBottom: '1px solid var(--border-divider)', display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
                            <h3 style={{ fontSize: 14, fontWeight: 700, margin: 0, flex: 1 }}>Historique complet</h3>
                            <input type="month" value={filtreMois} onChange={e => setFiltreMois(e.target.value)} style={{ ...inputStyle, width: 180 }} />
                            <select value={filtreStatut} onChange={e => setFiltreStatut(e.target.value)} style={{ ...inputStyle, width: 180 }}>
                                <option value="">Tous les statuts</option>
                                <option value="enattente">En attente</option>
                                <option value="validen1">Valide N1</option>
                                <option value="approuve">Approuvé</option>
                                <option value="verifie">Vérifié</option>
                                <option value="payee">Payée</option>
                                <option value="refuse">Refusée</option>
                            </select>
                            {(filtreMois || filtreStatut) && <button onClick={() => { setFiltreMois(''); setFiltreStatut(''); }} style={btnDanger}>Réinitialiser</button>}
                        </div>
                        <NotesTable notes={historiqueNotes} />
                    </div>
                )}
                {section === 'verification' && isVerificateurFinance && (
                    <VerificateurFinanceLight
                        notesAVerifier={notesAVerifier}
                        onVerified={(id) => {
                            setNotesAVerifier(prev => prev.filter(n => n.id !== id));
                        }}
                        API={API}
                        hdrs={hdrs}
                        proxyUrl={proxyUrl}
                        setPreviewUrl={setPreviewUrl}
                    />
                )}
             
                {/* ════════════════════════════════════════ */}
                {/* PAIEMENTS (Finance + ValidateurFinance)  */}
                {/* ════════════════════════════════════════ */}
                {section === 'paiements' && (isRHAdmin || isValidateurFinance) && (() => {

                    // ── Listes campus/sociétés disponibles ──
                    const campusPaiements = filtresDisponibles.campus;

                    // ── Mapping campus → sociétés (inline, pas de useMemo ici) ──
                    const campusSocieteMapping: Record<string, string[]> = {
                        'SQY': ['ENSUP', 'ENSUP SOLUTIONS ET SUPPORT'],      // ← SOLUTIONS avec S
                        'CGY': ['ENSUP', 'ENSUP SOLUTIONS ET SUPPORT'],      // ← SOLUTIONS avec S
                        'NTE': ['ENSUP NTE'],
                        'MRS': ['ENSUP MRS'],
                    };

                    const societesFiltrablesPaiements = (() => {
                        if (!paiementFiltreCampus) return filtresDisponibles.societes;
                        // Utiliser la map serveur — données exactes de la BDD
                        return filtresDisponibles.societeParCampus[paiementFiltreCampus] || filtresDisponibles.societes;
                    })();

                    // ── Filtrage des notes ──
                    const filtrerNote = (n: Note) => {
                        const campusNorm = normalizeCampus(n.campus || '');
                        const matchCampus = !paiementFiltreCampus ||
                            campusNorm === paiementFiltreCampus ||
                            (n.campus || '').toUpperCase().includes(paiementFiltreCampus);
                        const matchSociete = !paiementFiltreSociete ||
                            (n.societe || '').trim().toUpperCase() === paiementFiltreSociete.trim().toUpperCase();
                        return matchCampus && matchSociete;
                    };

                    const notesFiltreesPaiements = notesApprouvees.filter(filtrerNote);
                    const notesFiltreesXml = notesEnAttenteXml.filter(filtrerNote);
                    const hasFiltre = paiementFiltreCampus || paiementFiltreSociete;

                    return (
                        <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>

                            {/* ── Barre de filtres globale ── */}
                            <div style={{ ...cardStyle, padding: '14px 20px' }}>
                                <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
                                    <span style={{ fontSize: 12, fontWeight: 700, color: 'var(--text-secondary)', textTransform: 'uppercase', letterSpacing: '0.5px', flexShrink: 0 }}>
                                        🔍 Filtrer
                                    </span>

                                    {/* Campus */}
                                    <select
                                        value={paiementFiltreCampus}
                                        onChange={e => {
                                            setPaiementFiltreCampus(e.target.value);
                                            setPaiementFiltreSociete(''); // ← reset société quand campus change
                                            setSelectedNoteIds([]);
                                            setSelectedNoteIdsPaye([]);
                                        }}
                                        style={{ ...inputStyle, width: 160 }}>
                                        <option value="">Tous les campus</option>
                                        {campusPaiements.map(c => (
                                            <option key={c} value={normalizeCampus(c) || c}>
                                                {normalizeCampus(c) || c}
                                            </option>
                                        ))}
                                    </select>

                                    {/* Société — filtrée selon le campus */}
                                    <select
                                        value={paiementFiltreSociete}
                                        onChange={e => {
                                            setPaiementFiltreSociete(e.target.value);
                                            setSelectedNoteIds([]);
                                            setSelectedNoteIdsPaye([]);
                                        }}
                                        style={{ ...inputStyle, width: 220 }}>
                                        <option value="">Toutes les sociétés</option>
                                        {societesFiltrablesPaiements.map(s => (
                                            <option key={s} value={s}>{s}</option>
                                        ))}
                                    </select>

                                    {/* Indicateur compte débiteur */}
                                    {paiementFiltreCampus && (
                                        <div style={{
                                            display: 'flex', alignItems: 'center', gap: 6,
                                            padding: '6px 12px',
                                            background: '#eef2ff', border: '1px solid #c7d2fe',
                                            borderRadius: 8, fontSize: 12, color: '#4338ca', fontWeight: 600,
                                        }}>
                                            🏦 Compte : <strong style={{ marginLeft: 4 }}>{paiementFiltreCampus}</strong>
                                        </div>
                                    )}

                                    {hasFiltre && (
                                        <>
                                            <button
                                                onClick={() => {
                                                    setPaiementFiltreCampus('');
                                                    setPaiementFiltreSociete('');
                                                    setSelectedNoteIds([]);
                                                    setSelectedNoteIdsPaye([]);
                                                }}
                                                style={btnDanger}>
                                                Réinitialiser
                                            </button>
                                            <span style={{ fontSize: 12, color: 'var(--text-muted)', fontStyle: 'italic' }}>
                                                {notesFiltreesPaiements.length + notesFiltreesXml.length} note(s) affichée(s)
                                            </span>
                                        </>
                                    )}
                                </div>
                            </div>

                            {/* Notes approuvées à régler */}
                            <div style={cardStyle}>
                                <div style={{ padding: '16px 24px', borderBottom: '1px solid var(--border-divider)', display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 12 }}>
                                    <h3 style={{ fontSize: 14, fontWeight: 700, margin: 0 }}>
                                        {isValidateurFinance && !isRHAdmin ? 'Notes vérifiées — à régler' : 'Notes approuvées — à régler'}
                                        <span style={{ marginLeft: 8, background: '#dcfce7', color: '#15803d', fontSize: 11, padding: '2px 8px', borderRadius: 10 }}>
                                            {notesFiltreesPaiements.length}
                                        </span>
                                    </h3>
                                   <button
                                        style={{
                                            ...btnPrimary,
                                            background: paiementLoading
                                                ? 'linear-gradient(135deg,#4b5563,#374151)'
                                                : 'linear-gradient(135deg,#1e3a5f,#1d4ed8)',
                                            opacity: selectedNoteIds.length === 0 ? 0.5 : 1,
                                            cursor: paiementLoading ? 'wait' : 'pointer',
                                        }}
                                        disabled={selectedNoteIds.length === 0 || paiementLoading}
                                        onClick={async () => {
                                            if (!selectedNoteIds.length) return;
                                            setPaiementLoading(true);
                                            try {
                                                const res = await fetch(`${API}/api/paiements/soumettre-president`, {
                                                    method: 'POST',
                                                    headers: hdrs,
                                                    body: JSON.stringify({ noteIds: selectedNoteIds })
                                                });
                                                const data = await res.json();
                                                if (!res.ok) throw new Error(data.error || 'Erreur');
                                                showToast(
                                                    `✅ ${data.nbNotes} note(s) soumises au Président pour validation`,
                                                    'success'
                                                );
                                                setSelectedNoteIds([]);
                                                await refreshNotesPaiements();
                                            } catch (e: any) {
                                                showToast(e.message, 'error');
                                            } finally {
                                                setPaiementLoading(false);
                                            }
                                        }}>
                                        {paiementLoading
                                            ? <><span>⏳</span><span>Envoi...</span></>
                                            : <><span>💼</span><span>Soumettre au Président ({selectedNoteIds.length})</span></>
                                        }
                                    </button>
                                </div>

                                {notesFiltreesPaiements.length === 0
                                    ? <div style={{ padding: '48px 24px', textAlign: 'center', color: 'var(--text-muted)' }}>
                                        {hasFiltre ? 'Aucune note pour les filtres sélectionnés' : 'Aucune note approuvée en attente de règlement'}
                                    </div>
                                    : <div style={{ padding: 16 }}>
                                        <div style={{ marginBottom: 12, display: 'flex', alignItems: 'center', gap: 10 }}>
                                            <input
                                                type="checkbox"
                                                checked={selectedNoteIds.length === notesFiltreesPaiements.length && notesFiltreesPaiements.length > 0}
                                                onChange={e => setSelectedNoteIds(e.target.checked ? notesFiltreesPaiements.map(n => n.id) : [])}
                                                style={{ width: 16, height: 16, cursor: 'pointer' }} />
                                            <span style={{ fontSize: 12, fontWeight: 700, color: 'var(--text-secondary)' }}>
                                                Tout sélectionner ({notesFiltreesPaiements.length})
                                            </span>
                                            {selectedNoteIds.length > 0 && (
                                                <span style={{ fontSize: 12, color: '#6366f1', fontWeight: 600 }}>
                                                    · {selectedNoteIds.length} sélectionnée(s) — {fmt(
                                                        notesFiltreesPaiements
                                                            .filter(n => selectedNoteIds.includes(n.id))
                                                            .reduce((s, n) => s + (n.montant ?? 0), 0)
                                                    )}
                                                </span>
                                            )}
                                        </div>
                                        <div style={{ overflowX: 'auto' }}>
                                            <table style={{ width: '100%', borderCollapse: 'collapse', minWidth: 600 }}>
                                                <thead>
                                                    <tr style={{ background: 'var(--bg-thead)' }}>
                                                        {['', 'Référence', 'Collaborateur', 'Campus', 'Société', 'Montant', 'Statut'].map(h => (
                                                            <th key={h} style={{ padding: '10px 14px', textAlign: 'left', fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '0.6px', borderBottom: '1px solid var(--border-divider)' }}>{h}</th>
                                                        ))}
                                                    </tr>
                                                </thead>
                                                <tbody>
                                                    {notesFiltreesPaiements.map(n => {
                                                        const isChecked = selectedNoteIds.includes(n.id);
                                                        return (
                                                            <tr key={n.id}
                                                                style={{ borderTop: '1px solid var(--border-divider)', background: isChecked ? '#eef2ff' : undefined, cursor: 'pointer' }}
                                                                onClick={() => setSelectedNoteIds(isChecked ? selectedNoteIds.filter(id => id !== n.id) : [...selectedNoteIds, n.id])}>
                                                                <td style={{ padding: '12px 14px' }}><input type="checkbox" checked={isChecked} onChange={() => { }} style={{ width: 16, height: 16 }} /></td>
                                                                <td style={{ padding: '12px 14px', fontFamily: 'monospace', fontSize: 12, color: '#6366f1', fontWeight: 700 }}>{n.reference ?? `#${n.id}`}</td>
                                                                <td style={{ padding: '12px 14px', fontSize: 13, fontWeight: 600 }}>{n.collaborateur}</td>
                                                                <td style={{ padding: '12px 14px', fontSize: 12 }}>
                                                                    {n.campus ? <span style={{ background: '#eef2ff', color: '#6366f1', padding: '2px 8px', borderRadius: 6, fontSize: 11, fontWeight: 700 }}>{normalizeCampus(n.campus)}</span> : '-'}
                                                                </td>
                                                                <td style={{ padding: '12px 14px', fontSize: 12, color: 'var(--text-muted)' }}>{n.societe || '-'}</td>
                                                                <td style={{ padding: '12px 14px', fontWeight: 800, fontSize: 14 }}>{fmt(n.montant ?? 0)}</td>
                                                                <td style={{ padding: '12px 14px' }}>{tagStatut(n.statut ?? 'brouillon')}</td>
                                                            </tr>
                                                        );
                                                    })}
                                                </tbody>
                                            </table>
                                        </div>
                                    </div>
                                }
                            </div>

                            {/* Confirmation paiement */}
                            {/* Confirmation paiement */}
                            {(hasFiltre ? notesFiltreesXml.length > 0 : notesEnAttenteXml.length > 0) && (
                                <div style={cardStyle}>
                                    <div style={{ padding: '16px 24px', borderBottom: '1px solid var(--border-divider)', display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 12 }}>
                                        <h3 style={{ fontSize: 14, fontWeight: 700, margin: 0 }}>
                                            Paiements en attente de confirmation
                                            <span style={{ marginLeft: 8, background: '#fef9c3', color: '#a16207', fontSize: 11, padding: '2px 8px', borderRadius: 10 }}>
                                                {notesFiltreesXml.length}
                                                {hasFiltre && notesEnAttenteXml.length !== notesFiltreesXml.length &&
                                                    <span style={{ opacity: 0.6 }}> / {notesEnAttenteXml.length}</span>
                                                }
                                            </span>
                                        </h3>
                                        <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
                                            <input type="date" value={datePaiementSaisie} onChange={e => setDatePaiementSaisie(e.target.value)} style={{ ...inputStyle, width: 160 }} />
                                            <button
                                                style={{ ...btnSuccess, padding: '10px 18px', fontSize: 13, opacity: (selectedNoteIdsPaye.length === 0 || !datePaiementSaisie) ? 0.5 : 1 }}
                                                disabled={selectedNoteIdsPaye.length === 0 || !datePaiementSaisie || paiementLoading}
                                                onClick={async () => {
                                                    if (!selectedNoteIdsPaye.length || !datePaiementSaisie) return;
                                                    setPaiementLoading(true);
                                                    try {
                                                        const res = await fetch(`${API}/api/paiements/confirmer-paiement`, { method: 'POST', headers: hdrs, body: JSON.stringify({ noteIds: selectedNoteIdsPaye, datePaiement: datePaiementSaisie }) });
                                                        if (!res.ok) { const e = await res.json(); throw new Error(e.error); }
                                                        const data = await res.json();
                                                        showToast(`${data.count} paiement(s) confirmé(s)`, 'success');
                                                        setSelectedNoteIdsPaye([]);
                                                        setDatePaiementSaisie('');
                                                        await refreshNotesPaiements();
                                                    } catch (e: any) { showToast(e.message, 'error'); }
                                                    finally { setPaiementLoading(false); }
                                                }}>
                                                ✅ Confirmer paiement ({selectedNoteIdsPaye.length})
                                            </button>
                                        </div>
                                    </div>

                                    <div style={{ padding: 16 }}>
                                        {/* Sélectionner tout */}
                                        <div style={{ marginBottom: 12, display: 'flex', alignItems: 'center', gap: 10 }}>
                                            <input
                                                type="checkbox"
                                                checked={selectedNoteIdsPaye.length === notesFiltreesXml.length && notesFiltreesXml.length > 0}
                                                onChange={e => setSelectedNoteIdsPaye(e.target.checked ? notesFiltreesXml.map(n => n.id) : [])}
                                                style={{ width: 16, height: 16, cursor: 'pointer' }} />
                                            <span style={{ fontSize: 12, fontWeight: 700, color: 'var(--text-secondary)' }}>
                                                Tout sélectionner ({notesFiltreesXml.length})
                                            </span>
                                            {selectedNoteIdsPaye.length > 0 && (
                                                <span style={{ fontSize: 12, color: '#15803d', fontWeight: 600 }}>
                                                    · {selectedNoteIdsPaye.length} sélectionnée(s) — {fmt(
                                                        notesFiltreesXml
                                                            .filter(n => selectedNoteIdsPaye.includes(n.id))
                                                            .reduce((s, n) => s + (n.montant ?? 0), 0)
                                                    )}
                                                </span>
                                            )}
                                        </div>

                                        {/* ── Groupes par date XML ── */}
                                        {(() => {
                                            const groupes = notesFiltreesXml.reduce((acc, n) => {
                                                const dateKey = n.dateXml
                                                    ? new Date(n.dateXml).toISOString().split('T')[0]
                                                    : 'sans-date';
                                                if (!acc[dateKey]) acc[dateKey] = [];
                                                acc[dateKey].push(n);
                                                return acc;
                                            }, {} as Record<string, typeof notesFiltreesXml>);

                                            const groupesTries = Object.entries(groupes).sort(([a], [b]) =>
                                                a === 'sans-date' ? 1 : b === 'sans-date' ? -1 : b.localeCompare(a)
                                            );

                                            return (
                                                <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
                                                    {groupesTries.map(([dateKey, notesGroupe]) => {
                                                        const totalGroupe = notesGroupe.reduce((s, n) => s + (n.montant ?? 0), 0);
                                                        const tousSelectes = notesGroupe.every(n => selectedNoteIdsPaye.includes(n.id));
                                                        const certainsSelectes = notesGroupe.some(n => selectedNoteIdsPaye.includes(n.id));
                                                        const dateLabel = dateKey === 'sans-date'
                                                            ? 'Date XML inconnue'
                                                            : new Date(dateKey).toLocaleDateString('fr-FR', {
                                                                weekday: 'long', day: '2-digit', month: 'long', year: 'numeric'
                                                            });
                                                        const dateHeureLabel = dateKey === 'sans-date' ? '' :
                                                            new Date(notesGroupe[0].dateXml!).toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' });

                                                        return (
                                                            <div key={dateKey} style={{
                                                                border: '1.5px solid var(--border-card)',
                                                                borderRadius: 10, overflow: 'hidden',
                                                            }}>
                                                                {/* En-tête groupe */}
                                                                <div style={{
                                                                    padding: '10px 16px',
                                                                    background: 'var(--bg-thead)',
                                                                    borderBottom: '1px solid var(--border-divider)',
                                                                    display: 'flex', alignItems: 'center',
                                                                    justifyContent: 'space-between', gap: 12, flexWrap: 'wrap',
                                                                }}>
                                                                    <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                                                                        {/* Checkbox groupe */}
                                                                        <input
                                                                            type="checkbox"
                                                                            checked={tousSelectes}
                                                                            ref={el => { if (el) el.indeterminate = !tousSelectes && certainsSelectes; }}
                                                                            onChange={e => {
                                                                                if (e.target.checked) {
                                                                                    setSelectedNoteIdsPaye(prev => [...new Set([...prev, ...notesGroupe.map(n => n.id)])]);
                                                                                } else {
                                                                                    setSelectedNoteIdsPaye(prev => prev.filter(id => !notesGroupe.some(n => n.id === id)));
                                                                                }
                                                                            }}
                                                                            style={{ width: 15, height: 15, cursor: 'pointer' }}
                                                                        />
                                                                        <div>
                                                                            <div style={{ fontSize: 13, fontWeight: 800, color: 'var(--text-primary)', textTransform: 'capitalize' }}>
                                                                                🏦 XML généré le {dateLabel}
                                                                                {dateHeureLabel && (
                                                                                    <span style={{ fontSize: 11, fontWeight: 400, color: 'var(--text-muted)', marginLeft: 6 }}>
                                                                                        à {dateHeureLabel}
                                                                                    </span>
                                                                                )}
                                                                            </div>
                                                                            <div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 1 }}>
                                                                                {notesGroupe.length} virement{notesGroupe.length > 1 ? 's' : ''} · {
                                                                                    selectedNoteIdsPaye.filter(id => notesGroupe.some(n => n.id === id)).length > 0
                                                                                        ? `${selectedNoteIdsPaye.filter(id => notesGroupe.some(n => n.id === id)).length} sélectionné(s)`
                                                                                        : 'aucun sélectionné'
                                                                                }
                                                                            </div>
                                                                        </div>
                                                                    </div>
                                                                    <div style={{
                                                                        fontSize: 14, fontWeight: 900, color: '#b45309',
                                                                        background: '#fef9c3', border: '1px solid #fde68a',
                                                                        padding: '4px 14px', borderRadius: 8,
                                                                    }}>
                                                                        {fmt(totalGroupe)}
                                                                    </div>
                                                                </div>

                                                                {/* Tableau du groupe */}
                                                                <div style={{ overflowX: 'auto' }}>
                                                                    <table style={{ width: '100%', borderCollapse: 'collapse' }}>
                                                                        <thead>
                                                                            <tr style={{ background: 'var(--bg-thead)' }}>
                                                                                {['', 'Référence', 'Collaborateur', 'Campus', 'Société', 'Montant', 'PDF'].map(h => (
                                                                                    <th key={h} style={{ padding: '8px 14px', textAlign: 'left', fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '0.6px', borderBottom: '1px solid var(--border-divider)' }}>{h}</th>
                                                                                ))}
                                                                            </tr>
                                                                        </thead>
                                                                        <tbody>
                                                                            {notesGroupe.map(n => {
                                                                                const isChecked = selectedNoteIdsPaye.includes(n.id);
                                                                                let pdfUrl: string | null = null;
                                                                                try {
                                                                                    const fichiers: { fileName: string; uploadUrl: string }[] = n.fichiers ? JSON.parse(n.fichiers as string) : [];
                                                                                    pdfUrl = fichiers[0]?.uploadUrl ?? n.sharepointUrl ?? null;
                                                                                } catch { pdfUrl = n.sharepointUrl ?? null; }

                                                                                return (
                                                                                    <tr key={n.id}
                                                                                        style={{ borderTop: '1px solid var(--border-divider)', background: isChecked ? '#f0fdf4' : undefined, cursor: 'pointer' }}
                                                                                        onClick={() => setSelectedNoteIdsPaye(isChecked ? selectedNoteIdsPaye.filter(id => id !== n.id) : [...selectedNoteIdsPaye, n.id])}>
                                                                                        <td style={{ padding: '11px 14px' }}>
                                                                                            <input type="checkbox" checked={isChecked} onChange={() => { }} style={{ width: 15, height: 15 }} />
                                                                                        </td>
                                                                                        <td style={{ padding: '11px 14px', fontFamily: 'monospace', fontSize: 12, color: '#6366f1', fontWeight: 700 }}>{n.reference ?? `#${n.id}`}</td>
                                                                                        <td style={{ padding: '11px 14px', fontSize: 13, fontWeight: 600 }}>{n.collaborateur}</td>
                                                                                        <td style={{ padding: '11px 14px', fontSize: 12 }}>
                                                                                            {n.campus ? (
                                                                                                <span style={{ background: '#eef2ff', color: '#6366f1', padding: '2px 8px', borderRadius: 6, fontSize: 11, fontWeight: 700 }}>
                                                                                                    {normalizeCampus(n.campus)}
                                                                                                </span>
                                                                                            ) : <span style={{ color: 'var(--text-muted)' }}>—</span>}
                                                                                        </td>
                                                                                        <td style={{ padding: '11px 14px', fontSize: 12, color: 'var(--text-muted)' }}>{(n as any).societe || '—'}</td>
                                                                                        <td style={{ padding: '11px 14px', fontWeight: 800, fontSize: 14 }}>{fmt(n.montant ?? 0)}</td>
                                                                                        <td style={{ padding: '11px 14px' }} onClick={e => e.stopPropagation()}>
                                                                                            {pdfUrl
                                                                                                ? <button onClick={() => setPreviewUrl({ url: proxyUrl(pdfUrl!), name: 'PDF' })} style={{ display: 'inline-flex', alignItems: 'center', gap: 4, padding: '5px 10px', background: '#f0fdf4', border: '1px solid #86efac', borderRadius: 6, cursor: 'pointer', fontFamily: 'inherit', color: '#15803d', fontSize: 12, fontWeight: 600 }}>📄</button>
                                                                                                : <span style={{ color: '#cbd5e1', fontSize: 12 }}>—</span>}
                                                                                        </td>
                                                                                    </tr>
                                                                                );
                                                                            })}
                                                                        </tbody>
                                                                        {notesGroupe.length > 1 && (
                                                                            <tfoot>
                                                                                <tr style={{ borderTop: '2px solid var(--border-divider)', background: 'var(--bg-thead)' }}>
                                                                                    <td colSpan={5} style={{ padding: '8px 14px', fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '0.5px' }}>
                                                                                        Sous-total batch
                                                                                    </td>
                                                                                    <td colSpan={2} style={{ padding: '8px 14px', fontWeight: 900, fontSize: 14, color: '#b45309' }}>
                                                                                        {fmt(totalGroupe)}
                                                                                    </td>
                                                                                </tr>
                                                                            </tfoot>
                                                                        )}
                                                                    </table>
                                                                </div>
                                                            </div>
                                                        );
                                                    })}
                                                </div>
                                            );
                                        })()}
                                    </div>
                                </div>
                            )}

                            {/* Exceptions */}
                            {isRHAdmin && exceptions.length > 0 && (
                                <div style={cardStyle}>
                                    <div style={{ padding: '16px 24px', borderBottom: '1px solid var(--border-divider)' }}>
                                        <h3 style={{ fontSize: 14, fontWeight: 700, margin: 0 }}>Exceptions à traiter <span style={{ marginLeft: 8, background: '#ef4444', color: '#fff', fontSize: 11, padding: '2px 8px', borderRadius: 10 }}>{exceptions.length}</span></h3>
                                    </div>
                                    <div style={{ padding: 24, display: 'flex', flexDirection: 'column', gap: 12 }}>
                                        {exceptions.map(ex => (
                                            <div key={ex.id} style={{ border: '1px solid #fde68a', borderRadius: 10, padding: 16, background: '#fffbeb', display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 12 }}>
                                                <div>
                                                    <div style={{ fontWeight: 700, fontSize: 13 }}>{ex.reference} — {ex.collaborateur}</div>
                                                    <div style={{ fontSize: 12, color: 'var(--text-secondary)', marginTop: 2 }}>{ex.Motif}</div>
                                                    <div style={{ fontSize: 13, fontWeight: 800, marginTop: 4 }}>{fmt(ex.montant ?? 0)}</div>
                                                </div>
                                                <div style={{ display: 'flex', gap: 8 }}>
                                                    <button style={btnSuccess} onClick={() => handleTraiterException(ex.id, 'approuve')}>Approuver</button>
                                                    <button style={btnDanger} onClick={() => handleTraiterException(ex.id, 'refuse')}>Refuser</button>
                                                </div>
                                            </div>
                                        ))}
                                    </div>
                                </div>
                            )}
                        </div>
                    );
                })()}
   
                {/* ════════════════════════════════════════ */}
                {/* SUPERVISION                              */}
                {/* ════════════════════════════════════════ */}
                {section === 'supervision' && isSuperUser && (() => {
                    const notesFiltrees = allNotesAdmin.filter(n => {
                        const matchSearch = !adminSearch ||
                            (n.collaborateur || '').toLowerCase().includes(adminSearch.toLowerCase()) ||
                            (n.libelle || '').toLowerCase().includes(adminSearch.toLowerCase()) ||
                            (n.reference || '').toLowerCase().includes(adminSearch.toLowerCase());
                        return matchSearch;
                    });
                    const statsAdmin = {
                        total: allNotesAdmin.length,
                        montant: allNotesAdmin.reduce((a, n) => a + (n.montant || 0), 0),
                        enAttente: allNotesAdmin.filter(n => ['enattente', 'en_attente'].includes(normalizeStatut(n.statut || ''))).length,
                        verifie: allNotesAdmin.filter(n => normalizeStatut(n.statut || '') === 'verifie').length,
                        approuve: allNotesAdmin.filter(n => ['approuve', 'payee'].includes(normalizeStatut(n.statut || ''))).length,
                        refuse: allNotesAdmin.filter(n => normalizeStatut(n.statut || '') === 'refuse').length,
                    };
                    return (
                        <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
                            <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '14px 20px', background: 'linear-gradient(135deg,#1e1b4b,#312e81)', borderRadius: 12, border: '1px solid #4338ca' }}>
                                <ShieldCheck size={22} color="#a5b4fc" />
                                <div><div style={{ color: '#a5b4fc', fontSize: 12, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.6px' }}>Mode supervision</div><div style={{ color: '#e0e7ff', fontSize: 13, marginTop: 2 }}>Lecture seule — toutes les notes de l'organisation</div></div>
                            </div>
                            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(5,1fr)', gap: 14 }}>
                                {[
                                    { label: 'Total notes', value: statsAdmin.total, accent: '#6366f1' },
                                    { label: 'Volume total', value: fmt(statsAdmin.montant), accent: '#0ea5e9' },
                                    { label: 'En attente', value: statsAdmin.enAttente, accent: '#f59e0b' },
                                    { label: 'Vérifiées', value: statsAdmin.verifie, accent: '#7c3aed' },
                                    { label: 'Approuvées', value: statsAdmin.approuve, accent: '#10b981' },
                                ].map((c, i) => (
                                    <div key={i} style={{ ...cardStyle, padding: '16px 18px', borderLeft: `4px solid ${c.accent}` }}>
                                        <div style={{ fontSize: 20, fontWeight: 900, color: c.accent }}>{c.value}</div>
                                        <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', marginTop: 4, textTransform: 'uppercase', letterSpacing: '0.5px' }}>{c.label}</div>
                                    </div>
                                ))}
                            </div>
                            <div style={{ ...cardStyle, padding: '16px 20px' }}>
                                <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', alignItems: 'center' }}>
                                    <input style={{ ...inputStyle, flex: 1, minWidth: 200 }} placeholder="Rechercher..." value={adminSearch} onChange={e => setAdminSearch(e.target.value)} />
                                    <input type="month" value={adminFiltreMois} onChange={e => setAdminFiltreMois(e.target.value)} style={{ ...inputStyle, width: 180 }} />
                                    <select value={adminFiltreStatut} onChange={e => setAdminFiltreStatut(e.target.value)} style={{ ...inputStyle, width: 180 }}>
                                        <option value="">Tous les statuts</option>
                                        <option value="enattente">En attente</option>
                                        <option value="approuve">Approuvé</option>
                                        <option value="verifie">Vérifié</option>
                                        <option value="payee">Payée</option>
                                        <option value="refuse">Refusée</option>
                                    </select>
                                    {(adminSearch || adminFiltreMois || adminFiltreStatut) && <button onClick={() => { setAdminSearch(''); setAdminFiltreMois(''); setAdminFiltreStatut(''); }} style={btnDanger}>Réinitialiser</button>}
                                </div>
                            </div>
                            <div style={cardStyle}>
                                <div style={{ padding: '14px 24px', borderBottom: '1px solid var(--border-divider)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                                    <h3 style={{ fontSize: 14, fontWeight: 700, margin: 0 }}>Toutes les notes <span style={{ marginLeft: 8, background: '#eef2ff', color: '#6366f1', fontSize: 11, fontWeight: 800, padding: '2px 8px', borderRadius: 10 }}>{notesFiltrees.length}</span></h3>
                                    <span style={{ fontSize: 12, color: 'var(--text-muted)', fontStyle: 'italic' }}>Lecture seule</span>
                                </div>
                                {notesFiltrees.length === 0
                                    ? <div style={{ padding: '48px 24px', textAlign: 'center', color: 'var(--text-muted)' }}><p style={{ fontSize: 14 }}>Aucune note trouvée</p></div>
                                    : <div style={{ overflowX: 'auto' }}>
                                        <table style={{ width: '100%', borderCollapse: 'collapse', minWidth: 0 }}>
                                            <thead>
                                                <tr style={{ background: 'var(--bg-thead)' }}>
                                                    {['Référence', 'Collaborateur', 'Département', 'Libellé', 'Date', 'Montant', 'Statut'].map(h => (
                                                        <th key={h} style={{ padding: '10px 16px', textAlign: 'left', fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '0.6px', borderBottom: '1px solid var(--border-divider)' }}>{h}</th>
                                                    ))}
                                                </tr>
                                            </thead>
                                            <tbody>
                                                {notesFiltrees.map((n, i) => (
                                                    <tr key={i} style={{ borderTop: '1px solid var(--border-divider)' }}>
                                                        <td style={{ padding: '12px 16px', color: '#6366f1', fontWeight: 700, fontFamily: 'monospace', fontSize: 12 }}>{n.reference || `#${n.id}`}</td>
                                                        <td style={{ padding: '12px 16px', fontSize: 13, fontWeight: 600 }}>{n.collaborateur || '-'}<div style={{ fontSize: 11, color: 'var(--text-muted)', fontWeight: 400 }}>{n.collaborateurEmail}</div></td>
                                                        <td style={{ padding: '12px 16px', fontSize: 12, color: 'var(--text-secondary)' }}>{n.departement || '-'}<br /><span style={{ fontSize: 11, color: 'var(--text-muted)' }}>{n.campus ? normalizeCampus(n.campus) : '-'}</span></td>
                                                        <td style={{ padding: '12px 16px', fontSize: 13 }}>{n.libelle || '-'}</td>
                                                        <td style={{ padding: '12px 16px', fontSize: 12, color: 'var(--text-muted)' }}>{n.date ? new Date(n.date).toLocaleDateString('fr-FR') : '-'}</td>
                                                        <td style={{ padding: '12px 16px', fontWeight: 800, fontSize: 14 }}>{fmt(n.montant || 0)}</td>
                                                        <td style={{ padding: '12px 16px' }}>{tagStatut(n.statut || 'brouillon')}</td>
                                                    </tr>
                                                ))}
                                            </tbody>
                                        </table>
                                    </div>
                                }
                            </div>
                        </div>
                    );
                })()}
                {section === 'president' && isPresident && (
                    <PresidentValidation
                        apiBaseUrl={API}
                        authToken={token || ''}
                       user={{
                                 prenom: profile?.prenom || '',
                                 nom: profile?.nom || '',
                                 email: user?.email || '',
                                  roles: user?.roles || [],
                                                    }}
                        onShowToast={showToast}
                    />
                )}
                {/* ════════════════════════════════════════ */}
                {/* DOCUMENTS À VALIDER (Finance)            */}
                {/* ════════════════════════════════════════ */}
                {section === 'docsavalider' && (isFinance || isVerificateurFinance) && (
                    <div style={{ maxWidth: 900, margin: '0 auto' }}>
                        <div style={{ fontSize: 20, fontWeight: 800, color: 'var(--text-primary)', marginBottom: 24, display: 'flex', alignItems: 'center', gap: 10 }}>
                            <ShieldCheck size={22} /> Documents à valider
                            {docsAValider.length > 0 && <span style={{ background: '#6366f1', color: '#fff', fontSize: 12, fontWeight: 700, padding: '2px 10px', borderRadius: 20 }}>{docsAValider.length}</span>}
                        </div>
                        {docsAValiderLoading ? (
                            <div style={{ textAlign: 'center', padding: 60, color: 'var(--text-muted)' }}>⏳ Chargement...</div>
                        ) : docsAValider.length === 0 ? (
                            <div style={{ textAlign: 'center', padding: 60, color: 'var(--text-muted)' }}>✅ Aucun document en attente de validation</div>
                        ) : (
                            <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
                                {docsAValider.map((doc: any) => {
                                    const tl: Record<string, string> = { rib: '🏦 RIB', carte_grise: '🚗 Carte grise', cartegrise: '🚗 Carte grise', permis: '📄 Permis de conduire' };
                                    return (
                                        <div key={doc.id} style={{ ...cardStyle, padding: '18px 22px' }}>
                                            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap', gap: 12 }}>
                                                <div>
                                                    <div style={{ fontWeight: 800, fontSize: 16, color: 'var(--text-primary)' }}>{doc.prenom} {doc.nom}</div>
                                                    <div style={{ fontSize: 12, color: 'var(--text-muted)', marginTop: 3 }}>📍 {doc.campus} · {doc.departement}</div>
                                                    <div style={{ marginTop: 8, display: 'flex', gap: 8, alignItems: 'center' }}>
                                                        <span style={{ background: '#eef2ff', color: '#6366f1', padding: '3px 10px', borderRadius: 6, fontWeight: 700, fontSize: 12 }}>{tl[doc.type] || doc.type}</span>
                                                        <span style={{ fontSize: 12, color: 'var(--text-muted)' }}>Soumis le {new Date(doc.DateModification).toLocaleDateString('fr-FR')}</span>
                                                    </div>
                                                </div>
                                                <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
                                                    <button onClick={() => setPreviewUrl({ url: proxyUrl(doc.sharepointUrl), name: doc.fileName })} style={{ padding: '8px 14px', background: '#eef2ff', color: '#6366f1', border: 'none', borderRadius: 8, cursor: 'pointer', fontSize: 13, fontWeight: 700, fontFamily: 'inherit' }}>👁 Voir</button>
                                                    <button onClick={async () => {
                                                        await fetch(`${API}/api/finance/documents/${doc.id}/valider`, { method: 'PUT', headers: hdrs, body: JSON.stringify({ action: 'valider' }) });
                                                        setDocsAValider(prev => prev.filter((d: any) => d.id !== doc.id));
                                                        showToast('✅ Document validé', 'success');
                                                    }} style={{ padding: '8px 14px', background: '#dcfce7', color: '#15803d', border: 'none', borderRadius: 8, cursor: 'pointer', fontSize: 13, fontWeight: 700, fontFamily: 'inherit' }}>✅ Valider</button>
                                                    <button onClick={async () => {
                                                        const motif = window.prompt('Motif du refus :');
                                                        if (motif === null) return;
                                                        await fetch(`${API}/api/finance/documents/${doc.id}/valider`, { method: 'PUT', headers: hdrs, body: JSON.stringify({ action: 'refuser', commentaire: motif }) });
                                                        setDocsAValider(prev => prev.filter((d: any) => d.id !== doc.id));
                                                        showToast('❌ Document refusé', 'error');
                                                    }} style={{ padding: '8px 14px', background: '#fee2e2', color: '#dc2626', border: 'none', borderRadius: 8, cursor: 'pointer', fontSize: 13, fontWeight: 700, fontFamily: 'inherit' }}>❌ Refuser</button>
                                                </div>
                                            </div>
                                        </div>
                                    );
                                })}
                            </div>
                        )}
                    </div>
                )}
                {/* ════════════════════════════════════════ */}
                {/* PROFIL                                   */}
                {/* ════════════════════════════════════════ */}
                {section === 'profil' && (
                    <div style={{ ...cardStyle, maxWidth: 1100, padding: 32 }}>

                        {/* ── En-tête profil ── */}
                        <div style={{ display: 'flex', alignItems: 'center', gap: 16, marginBottom: 28 }}>
                            <div style={{
                                width: 56, height: 56,
                                background: 'linear-gradient(135deg,#6366f1,#4f46e5)',
                                borderRadius: '50%', display: 'flex', alignItems: 'center',
                                justifyContent: 'center', color: '#fff', fontWeight: 800, fontSize: 20,
                                flexShrink: 0,
                            }}>
                                {initials}
                            </div>
                            <div>
                                <div style={{ fontSize: 18, fontWeight: 800, color: 'var(--text-primary)' }}>
                                    {profile?.prenom} {profile?.nom}
                                </div>
                                <div style={{ fontSize: 13, color: 'var(--text-secondary)', marginTop: 2 }}>
                                    {profile?.email}
                                </div>
                                <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginTop: 4 }}>
                                    {user?.roles?.map((r: string) => (
                                        <span key={r} style={{
                                            display: 'inline-block', background: '#eef2ff', color: '#6366f1',
                                            fontSize: 11, fontWeight: 700, padding: '2px 8px', borderRadius: 4,
                                        }}>{r}</span>
                                    ))}
                                </div>
                            </div>
                        </div>

                        {/* ══════════════════════════════════════════════
                    GRILLE : 3 colonnes × 2 lignes
                    Col1 L1 = Infos pro
                    Col2 L1 = Adresse
                    Col3 L1+L2 = Documents (span 2 lignes)
                    Col1+2 L2 = Véhicule (span 2 colonnes)
                ══════════════════════════════════════════════ */}
                        <div style={{
                            display: 'grid',
                            gridTemplateColumns: '1fr 1fr 1fr',
                            gridTemplateRows: 'auto auto',
                            gap: 16,
                            alignItems: 'start',
                        }}>

                            {/* ── COLONNE 1, LIGNE 1 : Infos professionnelles ── */}
                            <div style={{
                                gridColumn: 1, gridRow: 1,
                                background: 'var(--bg-input)', borderRadius: 12,
                                padding: '20px 18px', border: '1px solid var(--border-card)',
                            }}>
                                <div style={{
                                    fontSize: 12, fontWeight: 800, color: 'var(--text-secondary)',
                                    textTransform: 'uppercase', letterSpacing: '0.6px', marginBottom: 14,
                                    display: 'flex', alignItems: 'center', gap: 6,
                                }}>
                                    👤 Informations professionnelles
                                </div>
                                {[
                                    { label: 'Poste', value: profile?.poste },
                                    { label: 'Département', value: profile?.departement },
                                    { label: 'Société', value: profile?.societe },  
                                    { label: 'Campus', value: profile?.campus ? normalizeCampus(profile.campus) : undefined },
                                    { label: 'Type de contrat', value: profile?.TypeContrat },
                                    { label: "Date d'entrée", value: profile?.DateEntree ? new Date(profile.DateEntree).toLocaleDateString('fr-FR') : undefined },
                                ].map(({ label, value }) => value ? (
                                    <div key={label} style={{ marginBottom: 12 }}>
                                        <div style={{ ...labelStyle, marginBottom: 3 }}>{label}</div>
                                        <div style={{ fontSize: 14, color: 'var(--text-primary)', fontWeight: 500 }}>{value}</div>
                                    </div>
                                ) : null)}
                            </div>

                            {/* ── COLONNE 2, LIGNE 1 : Adresse & Société ── */}
                            <div style={{
                                gridColumn: 2, gridRow: 1,
                                background: 'var(--bg-input)', borderRadius: 12,
                                padding: '20px 18px', border: '1px solid var(--border-card)',
                            }}>
                                <div style={{
                                    display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14,
                                }}>
                                    <div style={{
                                        fontSize: 12, fontWeight: 800, color: 'var(--text-secondary)',
                                        textTransform: 'uppercase', letterSpacing: '0.6px',
                                        display: 'flex', alignItems: 'center', gap: 6,
                                    }}>
                                        🏠 Votre Adresse postale personnelle
                                        {(!profile?.adresse_rue || !profile?.adresse_cp || !profile?.adresse_ville || !profile?.adresse_pays) && (
                                            <span style={{
                                                background: '#fef3c7', color: '#b45309',
                                                fontSize: 10, fontWeight: 700, padding: '2px 6px', borderRadius: 20,
                                            }}>Requis</span>
                                        )}
                                    </div>
                                    {!adresseEditing && (
                                        <button onClick={() => { setAdresseEditing(true); setAdresseError(''); }} style={{
                                            padding: '4px 10px', background: '#eef2ff', color: '#6366f1',
                                            border: '1px solid #c7d2fe', borderRadius: 8,
                                            cursor: 'pointer', fontSize: 11, fontWeight: 600, fontFamily: 'inherit',
                                            flexShrink: 0,
                                        }}>Modifier</button>
                                    )}
                                </div>

                                {(!profile?.adresse_rue || !profile?.adresse_cp || !profile?.adresse_ville || !profile?.adresse_pays) && !adresseEditing && (
                                    <div style={{
                                        display: 'flex', alignItems: 'center', gap: 10, padding: '10px 12px',
                                        background: '#fff7ed', border: '1.5px solid #fed7aa',
                                        borderLeft: '4px solid #f97316', borderRadius: '0 8px 8px 0', marginBottom: 12,
                                    }}>
                                        <span style={{ fontSize: 16 }}>⚠️</span>
                                        <div>
                                            <div style={{ fontSize: 12, fontWeight: 700, color: '#c2410c' }}>Adresse incomplète</div>
                                            <div style={{ fontSize: 11, color: '#ea580c', marginTop: 1 }}>Requise pour la soumission</div>
                                        </div>
                                    </div>
                                )}

                                {!adresseEditing ? (
                                    <>
                                        {[
                                            
                                            { label: 'Rue', value: profile?.adresse_rue },
                                            { label: 'Code postal', value: profile?.adresse_cp },
                                            { label: 'Ville', value: profile?.adresse_ville },
                                            { label: 'Pays', value: profile?.adresse_pays },
                                        ].map(({ label, value }) => (
                                            <div key={label} style={{
                                                display: 'flex', alignItems: 'center', gap: 10,
                                                padding: '7px 10px', background: 'var(--bg-card)', borderRadius: 8, marginBottom: 6,
                                            }}>
                                                <span style={{
                                                    fontSize: 11, fontWeight: 700, color: 'var(--text-muted)',
                                                    width: 72, flexShrink: 0,
                                                }}>{label}</span>
                                                <span style={{
                                                    fontSize: 13, fontWeight: 600,
                                                    color: value ? 'var(--text-primary)' : '#ef4444',
                                                }}>{value || 'Non renseigné'}</span>
                                            </div>
                                        ))}
                                    </>
                                ) : (
                                    <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                                       
                                        <div>
                                            <label style={labelSm}>Rue</label>
                                            <input style={inputSm} value={adresseForm.adresse_rue}
                                                onChange={e => setAdresseForm(f => ({ ...f, adresse_rue: e.target.value }))}
                                                 />
                                        </div>
                                        <div style={{ display: 'grid', gridTemplateColumns: '110px 1fr', gap: 8 }}>
                                            <div>
                                                <label style={labelSm}>Code postal</label>
                                                <input style={inputSm} value={adresseForm.adresse_cp}
                                                    onChange={e => setAdresseForm(f => ({ ...f, adresse_cp: e.target.value }))}
                                                    />
                                            </div>
                                            <div>
                                                <label style={labelSm}>Ville</label>
                                                <input style={inputSm} value={adresseForm.adresse_ville}
                                                    onChange={e => setAdresseForm(f => ({ ...f, adresse_ville: e.target.value }))}
                                                    />
                                            </div>
                                        </div>
                                        <div>
                                            <label style={labelSm}>Pays</label>
                                            <input style={inputSm} value={adresseForm.adresse_pays}
                                                onChange={e => setAdresseForm(f => ({ ...f, adresse_pays: e.target.value }))}
                                               />
                                        </div>
                                        {adresseError && (
                                            <div style={{ fontSize: 12, color: '#dc2626', background: '#fee2e2', padding: '8px 12px', borderRadius: 8 }}>
                                                {adresseError}
                                            </div>
                                        )}
                                        <div style={{ display: 'flex', gap: 8 }}>
                                            <button onClick={async () => {
                                                setAdresseError(''); setAdresseSaving(true);
                                                try {
                                                    const res = await fetch(`${API}/api/profile/adresse`, { method: 'PUT', headers: hdrs, body: JSON.stringify(adresseForm) });
                                                    const data = await res.json();
                                                    if (!res.ok) throw new Error(data.error || 'Erreur');
                                                    setProfile(p => p ? { ...p, ...adresseForm } : p);
                                                    setAdresseEditing(false);
                                                    showToast('Adresse enregistrée', 'success');
                                                } catch (e: any) { setAdresseError(e.message); }
                                                finally { setAdresseSaving(false); }
                                            }} disabled={adresseSaving} style={{ ...btnPrimary, fontSize: 12, padding: '8px 16px', opacity: adresseSaving ? 0.6 : 1 }}>
                                                {adresseSaving ? 'Enregistrement...' : 'Enregistrer'}
                                            </button>
                                            <button onClick={() => { setAdresseEditing(false); setAdresseError(''); }} style={{
                                                padding: '8px 14px', background: 'var(--bg-input)',
                                                border: '1px solid var(--border-input)', borderRadius: 8,
                                                cursor: 'pointer', fontSize: 12, fontFamily: 'inherit', color: 'var(--text-secondary)',
                                            }}>Annuler</button>
                                        </div>
                                    </div>
                                )}
                            </div>

                            {/* ── COLONNE 3, LIGNES 1+2 : Documents obligatoires ── */}
                            <div style={{
                                gridColumn: 3, gridRow: '1 / span 2',
                                background: 'var(--bg-input)', borderRadius: 12,
                                padding: '20px 18px', border: '1px solid var(--border-card)',
                            }}>
                                <div style={{
                                    fontSize: 12, fontWeight: 800, color: 'var(--text-secondary)',
                                    textTransform: 'uppercase', letterSpacing: '0.6px', marginBottom: 14,
                                    display: 'flex', alignItems: 'center', gap: 6,
                                }}>
                                    📄 Documents obligatoires
                                    {profilDocsLoading && <span style={{ fontSize: 11, color: 'var(--text-muted)', fontWeight: 400 }}>Chargement...</span>}
                                </div>

                                {/* IBAN */}
                                <div style={{
                                    border: `1.5px solid ${ibanData?.ibanSaisi ? '#dcfce7' : '#fde68a'}`,
                                    borderRadius: 10, padding: '14px 16px', marginBottom: 10, background: 'var(--bg-card)',
                                }}>
                                    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 6 }}>
                                        <span style={{ fontWeight: 700, fontSize: 14 }}>💳 RIB / Coordonnées bancaires</span>
                                        <span style={{
                                            background: ibanData?.ibanSaisi ? '#dcfce7' : '#fef3c7',
                                            color: ibanData?.ibanSaisi ? '#15803d' : '#b45309',
                                            fontSize: 11, fontWeight: 700, padding: '3px 10px', borderRadius: 20,
                                        }}>
                                            {ibanData?.ibanSaisi ? 'Enregistré' : 'Non renseigné'}
                                        </span>
                                    </div>
                                    <div style={{ fontSize: 11, color: 'var(--text-muted)', marginBottom: 10 }}>
                                        Obligatoire pour tout remboursement — l'IBAN est chiffré en base
                                    </div>

                                    {!ibanEditing && ibanData?.ibanSaisi && (
                                        <div style={{ display: 'flex', flexDirection: 'column', gap: 6, marginBottom: 10 }}>
                                            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                                                <span style={{ fontSize: 12, color: 'var(--text-muted)', width: 36, flexShrink: 0 }}>IBAN</span>
                                                <code style={{
                                                    fontSize: 13, fontWeight: 700, color: 'var(--text-primary)',
                                                    background: 'var(--bg-input)', padding: '4px 10px', borderRadius: 6, letterSpacing: '0.5px',
                                                }}>{ibanData.iban}</code>
                                            </div>
                                            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                                                <span style={{ fontSize: 12, color: 'var(--text-muted)', width: 36, flexShrink: 0 }}>BIC</span>
                                                <code style={{
                                                    fontSize: 13, fontWeight: 700, color: 'var(--text-primary)',
                                                    background: 'var(--bg-input)', padding: '4px 10px', borderRadius: 6,
                                                }}>{ibanData.bic}</code>
                                            </div>
                                        </div>
                                    )}

                                    {ibanEditing ? (
                                        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                                            <div>
                                                <label style={labelSm}>IBAN</label>
                                                <input
                                                    style={{ ...inputSm, fontFamily: 'monospace', textTransform: 'uppercase' }}
                                                    value={ibanForm.iban}
                                                    onChange={e => setIbanForm(f => ({ ...f, iban: e.target.value.replace(/\s/g, '').toUpperCase() }))}

                                                    placeholder="FR76 3000..." maxLength={34}
                                                />
                                            </div>
                                            <div>
                                                <label style={labelSm}>BIC / SWIFT</label>
                                                <input
                                                    style={{ ...inputSm, fontFamily: 'monospace', textTransform: 'uppercase' }}
                                                    value={ibanForm.bic}
                                                    onChange={e => setIbanForm(f => ({ ...f, bic: e.target.value }))}
                                                    placeholder="BNPAFRPP" maxLength={11}
                                                />
                                            </div>
                                            {ibanError && (
                                                <div style={{ fontSize: 12, color: '#dc2626', background: '#fee2e2', padding: '6px 10px', borderRadius: 6 }}>
                                                    {ibanError}
                                                </div>
                                            )}
                                            <div style={{ display: 'flex', gap: 8 }}>
                                                <button onClick={async () => {
                                                    setIbanError(''); setIbanSaving(true);
                                                    if (!ibanForm.bic.trim()) { setIbanError('Le BIC est obligatoire'); setIbanSaving(false); return; }
                                                    try {
                                                        const res = await fetch(`${API}/api/profil/iban`, { method: 'PUT', headers: hdrs, body: JSON.stringify({ iban: ibanForm.iban, bic: ibanForm.bic }) });
                                                        const data = await res.json();
                                                        if (!res.ok) throw new Error(data.error || 'Erreur');
                                                        showToast('Coordonnées bancaires enregistrées', 'success');
                                                        setIbanEditing(false);
                                                        const refreshed = await fetch(`${API}/api/profil/iban`, { headers: hdrs }).then(r => r.json());
                                                        setIbanData(refreshed);
                                                    } catch (e: any) { setIbanError(e.message); }
                                                    finally { setIbanSaving(false); }
                                                }} disabled={ibanSaving} style={{ ...btnPrimary, fontSize: 12, padding: '8px 16px', opacity: ibanSaving ? 0.6 : 1 }}>
                                                    {ibanSaving ? 'Enregistrement...' : 'Enregistrer'}
                                                </button>
                                                <button onClick={() => { setIbanEditing(false); setIbanError(''); }} style={{
                                                    padding: '8px 14px', background: 'var(--bg-input)',
                                                    border: '1px solid var(--border-input)', borderRadius: 8,
                                                    cursor: 'pointer', fontSize: 12, fontFamily: 'inherit', color: 'var(--text-secondary)',
                                                }}>Annuler</button>
                                            </div>
                                        </div>
                                    ) : (
                                        <button onClick={() => { setIbanForm({ iban: '', bic: ibanData?.bic ?? '' }); setIbanEditing(true); }} style={{
                                            padding: '6px 14px',
                                            background: ibanData?.ibanSaisi ? '#fef3c7' : '#dcfce7',
                                            border: `1px solid ${ibanData?.ibanSaisi ? '#fde68a' : '#86efac'}`,
                                            borderRadius: 6, cursor: 'pointer', fontSize: 12, fontWeight: 600,
                                            color: ibanData?.ibanSaisi ? '#92400e' : '#15803d', fontFamily: 'inherit',
                                        }}>
                                            {ibanData?.ibanSaisi ? "Modifier l'IBAN" : 'Saisir mon IBAN'}
                                        </button>
                                    )}
                                </div>

                                {/* Carte grise + Permis */}
                                {(['carte_grise', 'permis'] as const).map(type => {
                                    const doc = profilDocs[type];
                                    const label = type === 'carte_grise' ? '🚗 Carte grise' : '📋 Permis de conduire';
                                    const statutColor = !doc ? '#6b7280' : doc.statut === 'valide' ? '#15803d' : doc.statut === 'refuse' ? '#dc2626' : '#d97706';
                                    const statutBg = !doc ? '#f3f4f6' : doc.statut === 'valide' ? '#dcfce7' : doc.statut === 'refuse' ? '#fee2e2' : '#fef3c7';
                                    const statutLabel = !doc ? 'Absent' : doc.statut === 'valide' ? 'Validé' : doc.statut === 'refuse' ? 'Refusé' : 'En attente';
                                    const isUploading = profilDocsUploading === type;
                                    return (
                                        <div key={type} style={{
                                            border: `1.5px solid ${statutBg}`, borderRadius: 10,
                                            padding: '14px 16px', marginBottom: 10, background: 'var(--bg-card)',
                                        }}>
                                            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 6 }}>
                                                <span style={{ fontWeight: 700, fontSize: 14 }}>{label}</span>
                                                <span style={{
                                                    background: statutBg, color: statutColor,
                                                    fontSize: 11, fontWeight: 700, padding: '3px 10px', borderRadius: 20,
                                                }}>{statutLabel}</span>
                                            </div>
                                            <div style={{ fontSize: 11, color: 'var(--text-muted)', marginBottom: 8 }}>
                                                Obligatoire pour les notes kilométriques
                                            </div>
                                            {doc?.commentaire && doc.statut === 'refuse' && (
                                                <div style={{ fontSize: 12, color: '#dc2626', marginBottom: 8, background: '#fee2e2', padding: '6px 10px', borderRadius: 6 }}>
                                                    Motif : {doc.commentaire}
                                                </div>
                                            )}
                                            <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
                                                {doc && (
                                                    <>
                                                        <span style={{
                                                            fontSize: 12, color: 'var(--text-secondary)',
                                                            overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', maxWidth: 140,
                                                        }}>{doc.fileName}</span>
                                                        <button onClick={() => setPreviewUrl({ url: proxyUrl(doc.sharepointUrl), name: doc.fileName })}
                                                            style={{ padding: '4px 10px', background: '#eef2ff', color: '#6366f1', border: 'none', borderRadius: 6, cursor: 'pointer', fontSize: 11, fontWeight: 600, fontFamily: 'inherit' }}>
                                                            Voir
                                                        </button>
                                                    </>
                                                )}
                                                <label style={{
                                                    padding: '4px 12px',
                                                    background: isUploading ? '#f1f5f9' : doc ? '#fef3c7' : '#dcfce7',
                                                    border: `1px solid ${doc ? '#fde68a' : '#86efac'}`,
                                                    borderRadius: 6, cursor: isUploading ? 'not-allowed' : 'pointer',
                                                    fontSize: 12, fontWeight: 600, color: doc ? '#92400e' : '#15803d',
                                                }}>
                                                    {isUploading ? 'Upload...' : doc ? 'Remplacer' : 'Soumettre'}
                                                    <input type="file" accept=".pdf,.jpg,.jpeg,.png" style={{ display: 'none' }}
                                                        disabled={isUploading}
                                                        onChange={e => { const f = e.target.files?.[0]; if (f) uploadProfilDoc(type, f); e.target.value = ''; }} />
                                                </label>
                                                {doc && (
                                                    <button onClick={() => deleteProfilDoc(type)}
                                                        style={{ padding: '4px 10px', background: '#fee2e2', color: '#dc2626', border: 'none', borderRadius: 6, cursor: 'pointer', fontSize: 11, fontWeight: 600, fontFamily: 'inherit' }}>
                                                        🗑
                                                    </button>
                                                )}
                                            </div>
                                        </div>
                                    );
                                })}
                            </div>

                            {/* ── COLONNES 1+2, LIGNE 2 : Véhicule personnel ── */}
                            <div style={{
                                gridColumn: '1 / span 2', gridRow: 2,
                                background: 'var(--bg-input)', borderRadius: 12,
                                padding: '20px 18px', border: '1px solid var(--border-card)',
                            }}>
                                <div style={{
                                    display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14,
                                }}>
                                    <div style={{
                                        fontSize: 12, fontWeight: 800, color: 'var(--text-secondary)',
                                        textTransform: 'uppercase', letterSpacing: '0.6px',
                                        display: 'flex', alignItems: 'center', gap: 6,
                                    }}>
                                        🚘 Véhicule personnel
                                        {!vehicule && (
                                            <span style={{
                                                background: '#fef3c7', color: '#b45309',
                                                fontSize: 10, fontWeight: 700, padding: '2px 6px', borderRadius: 20,
                                            }}>Requis km</span>
                                        )}
                                    </div>
                                    {!vehiculeEditing && (
                                        <button onClick={() => { setVehiculeEditing(true); setVehiculeError(''); }} style={{
                                            padding: '4px 10px', background: '#eef2ff', color: '#6366f1',
                                            border: '1px solid #c7d2fe', borderRadius: 8,
                                            cursor: 'pointer', fontSize: 11, fontWeight: 600, fontFamily: 'inherit',
                                        }}>Modifier</button>
                                    )}
                                </div>

                                {!vehicule && !vehiculeEditing && (
                                    <div style={{
                                        display: 'flex', alignItems: 'center', gap: 10, padding: '10px 12px',
                                        background: '#fff7ed', border: '1.5px solid #fed7aa',
                                        borderLeft: '4px solid #f97316', borderRadius: '0 8px 8px 0', marginBottom: 12,
                                    }}>
                                        <span style={{ fontSize: 16 }}>⚠️</span>
                                        <div>
                                            <div style={{ fontSize: 12, fontWeight: 700, color: '#c2410c' }}>Véhicule non renseigné</div>
                                            <div style={{ fontSize: 11, color: '#ea580c', marginTop: 1 }}>
                                                Requis pour les notes kilométriques
                                            </div>
                                        </div>
                                    </div>
                                )}

                                {!vehiculeEditing ? (
                                    vehicule ? (
                                        <>
                                            {/* 2 colonnes pour profiter de la largeur */}
                                            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 6, marginBottom: 10 }}>
                                                {[
                                                    { label: 'Puissance fiscale', value: `${vehicule.chevaux} CV` },
                                                    { label: 'Marque', value: vehicule.marque },
                                                    { label: 'Modèle', value: vehicule.modele },
                                                    { label: 'Immatriculation', value: vehicule.immatriculation },
                                                ].map(({ label, value }) => (
                                                    <div key={label} style={{
                                                        display: 'flex', alignItems: 'center', gap: 10,
                                                        padding: '7px 10px', background: 'var(--bg-card)', borderRadius: 8,
                                                    }}>
                                                        <span style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', width: 110, flexShrink: 0 }}>{label}</span>
                                                        <span style={{ fontSize: 13, fontWeight: 600, color: value ? 'var(--text-primary)' : '#ef4444' }}>
                                                            {value || 'Non renseigné'}
                                                        </span>
                                                    </div>
                                                ))}
                                            </div>
                                            <div style={{
                                                padding: '8px 12px',
                                                background: '#f0fdf4', border: '1px solid #86efac',
                                                borderRadius: 8, fontSize: 11, color: '#15803d',
                                            }}>
                                                ✅ Ce barème s'applique automatiquement à vos notes kilométriques.
                                            </div>
                                        </>
                                    ) : (
                                        <div style={{ padding: '20px 0', textAlign: 'center', color: 'var(--text-muted)', fontSize: 13 }}>
                                            Aucun véhicule configuré
                                        </div>
                                    )
                                ) : (
                                    <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
                                        <div>
                                            <label style={{ ...labelStyle, marginBottom: 6 }}>Puissance fiscale *</label>
                                            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
                                                {BAREME_KM_DASHBOARD.map(b => (
                                                    <button
                                                        key={b.cv}
                                                        type="button"
                                                        onClick={() => setVehiculeForm(f => ({ ...f, chevaux: b.cv }))}
                                                        style={{
                                                            padding: '6px 12px', borderRadius: 8, cursor: 'pointer',
                                                            fontFamily: 'inherit', fontSize: 12, fontWeight: 600,
                                                            border: vehiculeForm.chevaux === b.cv
                                                                ? '2px solid #7c3aed'
                                                                : '1.5px solid var(--border-input)',
                                                            background: vehiculeForm.chevaux === b.cv
                                                                ? 'rgba(124,58,237,.1)' : 'var(--bg-input)',
                                                            color: vehiculeForm.chevaux === b.cv
                                                                ? '#7c3aed' : 'var(--text-primary)',
                                                        }}
                                                    >
                                                        {b.label}
                                                        <span style={{ display: 'block', fontSize: 10, opacity: 0.7, fontFamily: 'monospace' }}>
                                                            × {b.t1}€/km
                                                        </span>
                                                    </button>
                                                ))}
                                            </div>
                                            <div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 5 }}>
                                                📋 Case P.6 de votre carte grise
                                            </div>
                                        </div>

                                        {/* Marque + Modèle + Immat sur 3 colonnes */}
                                        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 10 }}>
                                            <div>
                                                <label style={labelSm}>Marque</label>
                                                <input
                                                    list="veh-marques"
                                                    style={inputSm}
                                                    value={vehiculeForm.marque}
                                                    onChange={e => setVehiculeForm(f => ({ ...f, marque: e.target.value }))}
                                                    placeholder="Renault, Peugeot…"
                                                />
                                                <datalist id="veh-marques">
                                                    {['Renault', 'Peugeot', 'Citroën', 'Volkswagen', 'Toyota', 'Ford', 'BMW',
                                                        'Mercedes', 'Audi', 'Fiat', 'Opel', 'Seat', 'Hyundai', 'Kia', 'Dacia', 'Nissan'].map(m => (
                                                            <option key={m} value={m} />
                                                        ))}
                                                </datalist>
                                            </div>
                                            <div>
                                                <label style={labelSm}>Modèle</label>
                                                <input
                                                    style={inputSm}
                                                    value={vehiculeForm.modele}
                                                    onChange={e => setVehiculeForm(f => ({ ...f, modele: e.target.value }))}
                                                    placeholder="Clio, 308…"
                                                />
                                            </div>
                                            <div>
                                                <label style={labelSm}>Immatriculation</label>
                                                <input
                                                    style={{ ...inputSm, textTransform: 'uppercase', fontFamily: 'monospace' }}
                                                    value={vehiculeForm.immatriculation}
                                                    onChange={e => setVehiculeForm(f => ({ ...f, immatriculation: e.target.value.toUpperCase() }))}
                                                    placeholder="AB-123-CD"
                                                    maxLength={9}
                                                />
                                            </div>
                                        </div>

                                        {vehiculeError && (
                                            <div style={{ fontSize: 12, color: '#dc2626', background: '#fee2e2', padding: '8px 12px', borderRadius: 8 }}>
                                                {vehiculeError}
                                            </div>
                                        )}

                                        <div style={{ display: 'flex', gap: 8 }}>
                                            <button
                                                onClick={async () => {
                                                    setVehiculeError('');
                                                    if (!vehiculeForm.chevaux) { setVehiculeError('La puissance fiscale est obligatoire'); return; }
                                                    setVehiculeSaving(true);
                                                    try {
                                                        const res = await fetch(`${API}/api/profil/vehicule`, {
                                                            method: 'PUT', headers: hdrs, body: JSON.stringify(vehiculeForm),
                                                        });
                                                        const data = await res.json();
                                                        if (!res.ok) throw new Error(data.error || 'Erreur');
                                                        setVehicule(vehiculeForm);
                                                        setVehiculeEditing(false);
                                                        showToast('🚘 Véhicule enregistré avec succès', 'success');
                                                    } catch (e: any) { setVehiculeError(e.message); }
                                                    finally { setVehiculeSaving(false); }
                                                }}
                                                disabled={vehiculeSaving}
                                                style={{ ...btnPrimary, fontSize: 12, padding: '8px 16px', opacity: vehiculeSaving ? 0.6 : 1 }}
                                            >
                                                {vehiculeSaving ? 'Enregistrement…' : 'Enregistrer'}
                                            </button>
                                            <button
                                                onClick={() => { setVehiculeEditing(false); setVehiculeError(''); }}
                                                style={{
                                                    padding: '8px 14px', background: 'var(--bg-input)',
                                                    border: '1px solid var(--border-input)', borderRadius: 8,
                                                    cursor: 'pointer', fontSize: 12, fontFamily: 'inherit', color: 'var(--text-secondary)',
                                                }}
                                            >
                                                Annuler
                                            </button>
                                            {vehicule && (
                                                <button
                                                    onClick={async () => {
                                                        if (!window.confirm('Supprimer le véhicule ?')) return;
                                                        await fetch(`${API}/api/profil/vehicule`, { method: 'DELETE', headers: hdrs });
                                                        setVehicule(null);
                                                        setVehiculeEditing(false);
                                                        showToast('Véhicule supprimé', 'success');
                                                    }}
                                                    style={{
                                                        padding: '8px 14px', background: '#fee2e2', color: '#dc2626',
                                                        border: 'none', borderRadius: 8, cursor: 'pointer',
                                                        fontSize: 12, fontFamily: 'inherit',
                                                    }}
                                                >
                                                    🗑 Supprimer
                                                </button>
                                            )}
                                        </div>
                                    </div>
                                )}
                            </div>

                        </div>{/* fin grille */}
                    </div>
                )}
                {/* ── HISTORIQUE PAIEMENTS (Finance) ── */}
                {section === 'historiquepaiements' && (isRHAdmin || isValidateurFinance) && (() => {
                    const campusHistorique = filtresDisponibles.campus;
                    const societesHistorique = filtresDisponibles.societes;

                    const historiqueFiltres = historiquePaiements.filter(n => {
                        const matchCampus = !historiqueFiltreCampus ||
                            normalizeCampus(n.campus || '') === historiqueFiltreCampus;
                        const matchSociete = !historiqueFiltreSociete ||
                            (n.societe || '') === historiqueFiltreSociete;
                        return matchCampus && matchSociete;
                    });

                    const genererExcel = () => {
                        const doExport = (XLSX: any) => {
                            const rows = historiqueFiltres.map((n: any) => {
                                const datePaiement = n.datePaiement ? new Date(n.datePaiement) : null;
                                const dateDemande = n.date ? new Date(n.date) : null;

                                let moisLabel = '';
                                if (datePaiement) {
                                    moisLabel = `- ${datePaiement.toLocaleDateString('fr-FR', { month: 'long' }).replace(/^\w/, c => c.toUpperCase())}`;
                                } else if (dateDemande) {
                                    moisLabel = `- ${dateDemande.toLocaleDateString('fr-FR', { month: 'long' }).replace(/^\w/, c => c.toUpperCase())}`;
                                }

                                let repas = 0, hebergement = 0, kmMontant = 0, transport = 0, autres = 0;

                                if (n.indemniteKm) {
                                    kmMontant += parseFloat(n.indemniteKm);
                                } else if (n.km && (!n.lignesJson || n.lignesJson === '[]')) {
                                    kmMontant += getIndemniteKm(parseFloat(n.km), 7);
                                }

                                try {
                                    if (n.lignesJson && n.lignesJson !== '[]') {
                                        const lignes = JSON.parse(n.lignesJson);
                                        lignes.forEach((l: any) => {
                                            const cat = (l.categorie || '').toLowerCase();
                                            if (cat.includes('kilom')) {
                                                kmMontant += getIndemniteKm(parseFloat(l.km) || 0, parseInt(l.chevaux) || 7);
                                            } else {
                                                const m = parseFloat(l.montant) || 0;
                                                if (cat.includes('repas') || cat.includes('restaurant')) repas += m;
                                                else if (cat.includes('hébergement') || cat.includes('hebergement') || cat.includes('hotel') || cat.includes('hôtel')) hebergement += m;
                                                else if (cat.includes('transport') || cat.includes('avion') || cat.includes('train') || cat.includes('taxi') || cat.includes('bus') || cat.includes('péage') || cat.includes('peage') || cat.includes('parking') || cat.includes('carburant')) transport += m;
                                                else autres += m;
                                            }
                                        });
                                    } else if (n.montant && !n.indemniteKm && (!n.lignesJson || n.lignesJson === '[]')) {
                                        const cat = (n.categorie || '').toLowerCase();
                                        const m = parseFloat(n.montant) || 0;
                                        if (cat.includes('repas')) repas += m;
                                        else if (cat.includes('hebergement') || cat.includes('hotel')) hebergement += m;
                                        else if (cat.includes('transport') || cat.includes('avion') || cat.includes('train') || cat.includes('taxi')) transport += m;
                                        else autres += m;
                                    }
                                } catch (e) {
                                    console.error("Erreur lors du parsing des lignes", e);
                                }

                                const formatDevise = (val: number) => val > 0
                                    ? new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR' }).format(val)
                                    : '';

                                let dateVersement = '';
                                const statutNormalise = (n.statut || '').toLowerCase().trim();
                                if (statutNormalise === 'payee' || statutNormalise === 'payée') {
                                    dateVersement = datePaiement
                                        ? datePaiement.toLocaleDateString('fr-FR')
                                        : (dateDemande ? dateDemande.toLocaleDateString('fr-FR') : '');
                                } else if (dateDemande) {
                                    dateVersement = `Dde le ${dateDemande.toLocaleDateString('fr-FR')}`;
                                }

                                return {
                                    'Mois': moisLabel,
                                    'Campus': normalizeCampus(n.campus) || n.campus || n.departement || '',
                                    'Société': n.societe || '',
                                    'Salarié': n.collaborateur || '',
                                    'Montant total': new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR' }).format(n.montant || 0),
                                    'Repas': formatDevise(repas),
                                    'Hébergement': formatDevise(hebergement),
                                    'Indemnités kilométriques': formatDevise(kmMontant),
                                    'Transport (Avion-train-taxis)': formatDevise(transport),
                                    'Autres': formatDevise(autres),
                                    'Date versement': dateVersement,
                                    'Banque': n.banque || '',
                                    ' ': (statutNormalise === 'payee' || statutNormalise === 'payée') ? 'OK réglé' : ''
                                };
                            });

                            const ws = XLSX.utils.json_to_sheet(rows);
                            const cols = [
                                { wch: 15 }, { wch: 10 }, { wch: 25 }, { wch: 25 }, { wch: 16 },
                                { wch: 14 }, { wch: 15 }, { wch: 24 }, { wch: 28 }, { wch: 12 },
                                { wch: 18 }, { wch: 12 }, { wch: 12 },
                            ];
                            ws['!cols'] = cols;

                            const wb = XLSX.utils.book_new();
                            const labelCampus = historiqueFiltreCampus ? `_${historiqueFiltreCampus}` : '';
                            const labelSociete = historiqueFiltreSociete ? `_${historiqueFiltreSociete.slice(0, 10).replace(/\s/g, '-')}` : '';
                            const labelMois = paiementFiltreMois ? `_${paiementFiltreMois.replace('-', '_')}` : '';
                            const label = `${new Date().toISOString().split('T')[0]}${labelMois}${labelCampus}${labelSociete}`;

                            XLSX.utils.book_append_sheet(wb, ws, 'RBT NDF');
                            XLSX.writeFile(wb, `RBT_NDF_${label}.xlsx`);
                        };

                        if ((window as any).XLSX) {
                            doExport((window as any).XLSX);
                        } else {
                            const script = document.createElement('script');
                            script.src = 'https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js';
                            script.onload = () => doExport((window as any).XLSX);
                            document.head.appendChild(script);
                        }
                    };

                    const hasFiltre = paiementFiltreMois || historiqueFiltreCampus || historiqueFiltreSociete;
                    const totalFiltres = historiqueFiltres.reduce((s, n) => s + (n.montant || 0), 0);
                    const totalTous = historiquePaiements.reduce((s, n) => s + (n.montant || 0), 0);

                    // ── Groupement par date de paiement (= date du virement XML) ──
                    const groupesParDate = historiqueFiltres.reduce((acc, n) => {
                        const dateKey = n.datePaiement
                            ? new Date(n.datePaiement).toISOString().split('T')[0]
                            : 'sans-date';
                        if (!acc[dateKey]) acc[dateKey] = [];
                        acc[dateKey].push(n);
                        return acc;
                    }, {} as Record<string, typeof historiqueFiltres>);

                    const groupesTries = Object.entries(groupesParDate).sort(([a], [b]) =>
                        a === 'sans-date' ? 1 : b === 'sans-date' ? -1 : b.localeCompare(a)
                    );

                    return (
                        <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>

                            {/* Stat cards */}
                            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2,1fr)', gap: 14 }}>
                                <div style={{ ...cardStyle, padding: '18px 22px', borderLeft: '4px solid #10b981' }}>
                                    <div style={{ fontSize: 22, fontWeight: 900, color: '#10b981' }}>
                                        {historiqueFiltres.length}
                                        {hasFiltre && historiqueFiltres.length !== historiquePaiements.length && (
                                            <span style={{ fontSize: 14, color: 'var(--text-muted)', fontWeight: 400 }}> / {historiquePaiements.length}</span>
                                        )}
                                    </div>
                                    <div style={{ fontSize: 12, fontWeight: 700, color: 'var(--text-muted)', marginTop: 4, textTransform: 'uppercase' }}>Notes payées</div>
                                </div>
                                <div style={{ ...cardStyle, padding: '18px 22px', borderLeft: '4px solid #6366f1' }}>
                                    <div style={{ fontSize: 22, fontWeight: 900, color: '#6366f1' }}>
                                        {fmt(totalFiltres)}
                                        {hasFiltre && totalFiltres !== totalTous && (
                                            <div style={{ fontSize: 11, color: 'var(--text-muted)', fontWeight: 400, marginTop: 2 }}>
                                                Total global : {fmt(totalTous)}
                                            </div>
                                        )}
                                    </div>
                                    <div style={{ fontSize: 12, fontWeight: 700, color: 'var(--text-muted)', marginTop: 4, textTransform: 'uppercase' }}>Volume total</div>
                                </div>
                            </div>

                            {/* Barre de filtres */}
                            <div style={{ ...cardStyle, padding: '14px 20px' }}>
                                <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
                                    <span style={{ fontSize: 12, fontWeight: 700, color: 'var(--text-secondary)', textTransform: 'uppercase', letterSpacing: '0.5px', flexShrink: 0 }}>
                                        🔍 Filtrer
                                    </span>
                                    <input
                                        type="month"
                                        value={paiementFiltreMois}
                                        onChange={e => setPaiementFiltreMois(e.target.value)}
                                        style={{ ...inputStyle, width: 180 }}
                                    />
                                    <select
                                        value={historiqueFiltreCampus}
                                        onChange={e => setHistoriqueFiltreCampus(e.target.value)}
                                        style={{ ...inputStyle, width: 160 }}>
                                        <option value="">Tous les campus</option>
                                        {campusHistorique.map(c => (
                                            <option key={c} value={c}>{c}</option>
                                        ))}
                                    </select>
                                    <select
                                        value={historiqueFiltreSociete}
                                        onChange={e => setHistoriqueFiltreSociete(e.target.value)}
                                        style={{ ...inputStyle, width: 220 }}>
                                        <option value="">Toutes les sociétés</option>
                                        {societesHistorique.map(s => (
                                            <option key={s} value={s}>{s}</option>
                                        ))}
                                    </select>
                                    {hasFiltre && (
                                        <>
                                            <button
                                                onClick={() => {
                                                    setPaiementFiltreMois('');
                                                    setHistoriqueFiltreCampus('');
                                                    setHistoriqueFiltreSociete('');
                                                }}
                                                style={btnDanger}>
                                                Réinitialiser
                                            </button>
                                            {(historiqueFiltreCampus || historiqueFiltreSociete) && (
                                                <span style={{ fontSize: 12, color: 'var(--text-muted)', fontStyle: 'italic' }}>
                                                    {historiqueFiltres.length} / {historiquePaiements.length} note(s)
                                                </span>
                                            )}
                                        </>
                                    )}
                                    <div style={{ marginLeft: 'auto', display: 'flex', alignItems: 'center', gap: 10 }}>
                                        {/* Toggle vue groupée / liste */}
                                        <button
                                            onClick={() => setHistoriqueGroupeParXml(v => !v)}
                                            style={{
                                                padding: '8px 14px',
                                                background: historiqueGroupeParXml ? '#eef2ff' : 'var(--bg-input)',
                                                border: `1px solid ${historiqueGroupeParXml ? '#c7d2fe' : 'var(--border-input)'}`,
                                                borderRadius: 8, cursor: 'pointer', fontSize: 12,
                                                fontWeight: 700,
                                                color: historiqueGroupeParXml ? '#6366f1' : 'var(--text-secondary)',
                                                fontFamily: 'inherit', transition: 'all 0.15s',
                                            }}>
                                            {historiqueGroupeParXml ? '📅 Par virement' : '📋 Liste'}
                                        </button>
                                        <button
                                            onClick={genererExcel}
                                            disabled={historiqueFiltres.length === 0}
                                            style={{
                                                ...btnPrimary,
                                                background: 'linear-gradient(135deg,#16a34a,#15803d)',
                                                boxShadow: '0 4px 14px rgba(22,163,74,.35)',
                                                opacity: historiqueFiltres.length === 0 ? 0.5 : 1,
                                            }}>
                                            <span>📊</span>
                                            <span>Générer Excel ({historiqueFiltres.length})</span>
                                        </button>
                                    </div>
                                </div>
                            </div>

                            {/* ── VUE GROUPÉE PAR DATE DE VIREMENT ── */}
                            {historiqueGroupeParXml ? (
                                historiqueFiltres.length === 0 ? (
                                    <div style={{ ...cardStyle, padding: '48px 24px', textAlign: 'center', color: 'var(--text-muted)' }}>
                                        <div style={{ fontSize: 36, marginBottom: 12 }}>💶</div>
                                        <p style={{ fontSize: 14 }}>
                                            {hasFiltre ? 'Aucun paiement pour les filtres sélectionnés' : 'Aucun paiement trouvé'}
                                        </p>
                                    </div>
                                ) : (
                                    <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
                                        {groupesTries.map(([dateKey, notesGroupe]) => {
                                            const totalGroupe = notesGroupe.reduce((s, n) => s + (n.montant || 0), 0);
                                            const dateLabel = dateKey === 'sans-date'
                                                ? 'Date inconnue'
                                                : new Date(dateKey).toLocaleDateString('fr-FR', {
                                                    weekday: 'long', day: '2-digit', month: 'long', year: 'numeric'
                                                });

                                            return (
                                                <div key={dateKey} style={cardStyle}>
                                                    {/* En-tête du groupe */}
                                                    <div style={{
                                                        padding: '12px 20px',
                                                        borderBottom: '1px solid var(--border-divider)',
                                                        display: 'flex', alignItems: 'center',
                                                        justifyContent: 'space-between', flexWrap: 'wrap', gap: 8,
                                                        background: 'var(--bg-thead)',
                                                    }}>
                                                        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                                                            <div style={{
                                                                width: 8, height: 8, borderRadius: '50%',
                                                                background: '#10b981', flexShrink: 0,
                                                            }} />
                                                            <div>
                                                                <div style={{ fontSize: 13, fontWeight: 800, color: 'var(--text-primary)', textTransform: 'capitalize' }}>
                                                                    Virement du {dateLabel}
                                                                </div>
                                                                <div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 1 }}>
                                                                    {notesGroupe.length} note{notesGroupe.length > 1 ? 's' : ''}
                                                                </div>
                                                            </div>
                                                        </div>
                                                        <div style={{
                                                            fontSize: 15, fontWeight: 900, color: '#15803d',
                                                            background: '#f0fdf4', border: '1px solid #86efac',
                                                            padding: '4px 14px', borderRadius: 8,
                                                        }}>
                                                            {fmt(totalGroupe)}
                                                        </div>
                                                    </div>

                                                    {/* Tableau du groupe */}
                                                    <div style={{ overflowX: 'auto' }}>
                                                        <table style={{ width: '100%', borderCollapse: 'collapse' }}>
                                                            <thead>
                                                                <tr style={{ background: 'var(--bg-thead)' }}>
                                                                    {['Référence', 'Collaborateur', 'Campus', 'Société', 'Libellé', 'Montant TTC'].map(h => (
                                                                        <th key={h} style={{
                                                                            padding: '8px 16px', textAlign: 'left', fontSize: 11,
                                                                            fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase',
                                                                            letterSpacing: '0.6px', borderBottom: '1px solid var(--border-divider)',
                                                                            whiteSpace: 'nowrap',
                                                                        }}>{h}</th>
                                                                    ))}
                                                                </tr>
                                                            </thead>
                                                            <tbody>
                                                                {notesGroupe.map((n, i) => (
                                                                    <tr key={i} style={{ borderTop: '1px solid var(--border-divider)' }}>
                                                                        <td style={{ padding: '11px 16px', fontFamily: 'monospace', fontSize: 12, color: '#6366f1', fontWeight: 700 }}>
                                                                            {n.reference}
                                                                        </td>
                                                                        <td style={{ padding: '11px 16px', fontSize: 13, fontWeight: 600, color: 'var(--text-primary)' }}>
                                                                            {n.collaborateur}
                                                                        </td>
                                                                        <td style={{ padding: '11px 16px', fontSize: 12 }}>
                                                                            {n.campus ? (
                                                                                <span style={{ background: '#eef2ff', color: '#6366f1', padding: '2px 8px', borderRadius: 6, fontSize: 11, fontWeight: 700 }}>
                                                                                    {normalizeCampus(n.campus)}
                                                                                </span>
                                                                            ) : <span style={{ color: 'var(--text-muted)' }}>—</span>}
                                                                        </td>
                                                                        <td style={{ padding: '11px 16px', fontSize: 12, color: 'var(--text-muted)' }}>
                                                                            {n.societe || '—'}
                                                                        </td>
                                                                        <td style={{ padding: '11px 16px', fontSize: 13, color: 'var(--text-secondary)', maxWidth: 200 }}>
                                                                            <div style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                                                                                {n.libelle || '—'}
                                                                            </div>
                                                                        </td>
                                                                        <td style={{ padding: '11px 16px', fontWeight: 800, fontSize: 14, color: '#15803d', whiteSpace: 'nowrap' }}>
                                                                            {fmt(n.montant || 0)}
                                                                        </td>
                                                                    </tr>
                                                                ))}
                                                            </tbody>
                                                            {notesGroupe.length > 1 && (
                                                                <tfoot>
                                                                    <tr style={{ borderTop: '2px solid var(--border-divider)', background: 'var(--bg-thead)' }}>
                                                                        <td colSpan={5} style={{ padding: '8px 16px', fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '0.5px' }}>
                                                                            Sous-total virement
                                                                        </td>
                                                                        <td style={{ padding: '8px 16px', fontWeight: 900, fontSize: 14, color: '#15803d', whiteSpace: 'nowrap' }}>
                                                                            {fmt(totalGroupe)}
                                                                        </td>
                                                                    </tr>
                                                                </tfoot>
                                                            )}
                                                        </table>
                                                    </div>
                                                </div>
                                            );
                                        })}
                                    </div>
                                )
                            ) : (
                                /* ── VUE LISTE CLASSIQUE ── */
                                <div style={cardStyle}>
                                    <div style={{ padding: '14px 24px', borderBottom: '1px solid var(--border-divider)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                                        <h3 style={{ fontSize: 14, fontWeight: 700, margin: 0 }}>
                                            Notes payées
                                            <span style={{ marginLeft: 8, background: '#f0fdf4', color: '#15803d', fontSize: 11, fontWeight: 800, padding: '2px 8px', borderRadius: 10 }}>
                                                {historiqueFiltres.length}
                                                {hasFiltre && historiqueFiltres.length !== historiquePaiements.length && (
                                                    <span style={{ opacity: 0.6 }}> / {historiquePaiements.length}</span>
                                                )}
                                            </span>
                                        </h3>
                                        <span style={{ fontSize: 13, fontWeight: 800, color: '#15803d' }}>
                                            {fmt(totalFiltres)}
                                        </span>
                                    </div>

                                    {historiqueFiltres.length === 0 ? (
                                        <div style={{ padding: '48px 24px', textAlign: 'center', color: 'var(--text-muted)' }}>
                                            <div style={{ fontSize: 36, marginBottom: 12 }}>💶</div>
                                            <p style={{ fontSize: 14 }}>
                                                {hasFiltre ? 'Aucun paiement pour les filtres sélectionnés' : 'Aucun paiement trouvé'}
                                            </p>
                                        </div>
                                    ) : (
                                        <div style={{ overflowX: 'auto' }}>
                                            <table style={{ width: '100%', borderCollapse: 'collapse' }}>
                                                <thead>
                                                    <tr style={{ background: 'var(--bg-thead)' }}>
                                                        {['Référence', 'Collaborateur', 'Campus', 'Société', 'Libellé', 'Montant TTC', 'Date de paiement'].map(h => (
                                                            <th key={h} style={{
                                                                padding: '10px 16px', textAlign: 'left', fontSize: 11,
                                                                fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase',
                                                                letterSpacing: '0.6px', borderBottom: '1px solid var(--border-divider)',
                                                                whiteSpace: 'nowrap'
                                                            }}>{h}</th>
                                                        ))}
                                                    </tr>
                                                </thead>
                                                <tbody>
                                                    {historiqueFiltres.map((n, i) => (
                                                        <tr key={i} style={{ borderTop: '1px solid var(--border-divider)' }}>
                                                            <td style={{ padding: '12px 16px', fontFamily: 'monospace', fontSize: 12, color: '#6366f1', fontWeight: 700 }}>
                                                                {n.reference}
                                                            </td>
                                                            <td style={{ padding: '12px 16px', fontSize: 13, fontWeight: 600, color: 'var(--text-primary)' }}>
                                                                {n.collaborateur}
                                                            </td>
                                                            <td style={{ padding: '12px 16px', fontSize: 12 }}>
                                                                {n.campus ? (
                                                                    <span style={{ background: '#eef2ff', color: '#6366f1', padding: '2px 8px', borderRadius: 6, fontSize: 11, fontWeight: 700 }}>
                                                                        {normalizeCampus(n.campus)}
                                                                    </span>
                                                                ) : <span style={{ color: 'var(--text-muted)' }}>—</span>}
                                                            </td>
                                                            <td style={{ padding: '12px 16px', fontSize: 12, color: 'var(--text-muted)' }}>
                                                                {n.societe || '—'}
                                                            </td>
                                                            <td style={{ padding: '12px 16px', fontSize: 13, color: 'var(--text-secondary)', maxWidth: 200 }}>
                                                                <div style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                                                                    {n.libelle || '—'}
                                                                </div>
                                                            </td>
                                                            <td style={{ padding: '12px 16px', fontWeight: 800, fontSize: 14, color: '#15803d', whiteSpace: 'nowrap' }}>
                                                                {fmt(n.montant || 0)}
                                                            </td>
                                                            <td style={{ padding: '12px 16px', fontSize: 12, color: 'var(--text-muted)', whiteSpace: 'nowrap' }}>
                                                                💶 {n.datePaiement
                                                                    ? new Date(n.datePaiement).toLocaleDateString('fr-FR', { day: '2-digit', month: 'short', year: 'numeric' })
                                                                    : '—'}
                                                            </td>
                                                        </tr>
                                                    ))}
                                                </tbody>
                                            </table>
                                        </div>
                                    )}
                                </div>
                            )}
                        </div>
                    );
                })()}
                {/* ════════════════════════════════════════ */}
                {/* XML VIREMENTS GÉNÉRÉS                   */}
                {/* ════════════════════════════════════════ */}
                {section === 'xmlgenerés' && (isRHAdmin || isValidateurFinance) && (
                    <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>

                        {/* Bandeau info */}
                        <div style={{
                            display: 'flex', alignItems: 'center', gap: 14,
                            padding: '14px 20px',
                            background: 'linear-gradient(135deg,#1e3a5f,#1d4ed8)',
                            borderRadius: 12, border: '1px solid #3b82f6',
                        }}>
                            <span style={{ fontSize: 28 }}>🏦</span>
                            <div>
                                <div style={{ color: '#bfdbfe', fontSize: 12, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.6px' }}>
                                    Historique des XML de virements
                                </div>
                                <div style={{ color: '#dbeafe', fontSize: 13, marginTop: 2 }}>
                                    Retrouvez et re-téléchargez tous les fichiers XML générés pour votre banque
                                </div>
                            </div>
                        </div>

                        {/* Filtres */}
                        <div style={{ ...cardStyle, padding: '14px 20px' }}>
                            <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
                                <span style={{ fontSize: 12, fontWeight: 700, color: 'var(--text-secondary)', textTransform: 'uppercase', letterSpacing: '0.5px', flexShrink: 0 }}>
                                    🔍 Filtrer
                                </span>
                                <select
                                    value={xmlFiltreAnnee}
                                    onChange={e => setXmlFiltreAnnee(e.target.value)}
                                    style={{ ...inputStyle, width: 140 }}>
                                    <option value="">Toutes les années</option>
                                    {[2024, 2025, 2026, 2027].map(a => (
                                        <option key={a} value={String(a)}>{a}</option>
                                    ))}
                                </select>
                                <select
                                    value={xmlFiltreMois}
                                    onChange={e => setXmlFiltreMois(e.target.value)}
                                    style={{ ...inputStyle, width: 160 }}>
                                    <option value="">Tous les mois</option>
                                    {[
                                        ['1', 'Janvier'], ['2', 'Février'], ['3', 'Mars'], ['4', 'Avril'],
                                        ['5', 'Mai'], ['6', 'Juin'], ['7', 'Juillet'], ['8', 'Août'],
                                        ['9', 'Septembre'], ['10', 'Octobre'], ['11', 'Novembre'], ['12', 'Décembre']
                                    ].map(([v, l]) => <option key={v} value={v}>{l}</option>)}
                                </select>
                                {(xmlFiltreAnnee || xmlFiltreMois) && (
                                    <button onClick={() => { setXmlFiltreAnnee(''); setXmlFiltreMois(''); }} style={btnDanger}>
                                        Réinitialiser
                                    </button>
                                )}
                                <button
                                    onClick={() => {
                                        setXmlLoading(true);
                                        const params = new URLSearchParams();
                                        if (xmlFiltreAnnee) params.append('annee', xmlFiltreAnnee);
                                        if (xmlFiltreMois) params.append('mois', xmlFiltreMois);
                                        fetch(`${API}/api/paiements/xml-historique?${params}`, { headers: hdrs })
                                            .then(r => r.ok ? r.json() : [])
                                            .then(d => Array.isArray(d) && setXmlHistorique(d))
                                            .catch(() => { })
                                            .finally(() => setXmlLoading(false));
                                    }}
                                    style={{ ...btnPrimary, fontSize: 13, padding: '9px 18px' }}>
                                    🔄 Actualiser
                                </button>
                            </div>
                        </div>

                        {/* Contenu */}
                        {xmlLoading ? (
                            <div style={{ ...cardStyle, padding: '48px 24px', textAlign: 'center', color: 'var(--text-muted)' }}>
                                ⏳ Chargement...
                            </div>
                        ) : xmlHistorique.length === 0 ? (
                            <div style={{ ...cardStyle, padding: '48px 24px', textAlign: 'center', color: 'var(--text-muted)' }}>
                                <div style={{ fontSize: 40, marginBottom: 16 }}>📂</div>
                                <div style={{ fontSize: 15, fontWeight: 700, marginBottom: 8 }}>Aucun XML généré</div>
                                <div style={{ fontSize: 13 }}>Les fichiers XML apparaîtront ici après chaque génération de virement.</div>
                            </div>
                        ) : (
                            <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
                                {xmlHistorique.map((batch: any, i: number) => {
                                    const dateXml = new Date(batch.dateXmlExacte || batch.premierXml);
                                    const dateLabel = dateXml.toLocaleDateString('fr-FR', {
                                        weekday: 'long', day: '2-digit', month: 'long', year: 'numeric'
                                    });
                                    const heureLabel = dateXml.toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' });
                                    const noteIdsList = (batch.noteIds || '').split(',').map((id: string) => parseInt(id.trim())).filter(Boolean);
                                    const batchKey = batch.dateXmlJour;
                                    const isLoadingRegen = xmlRegenLoading === batchKey;

                                    return (
                                        <div key={i} style={{ ...cardStyle, overflow: 'visible' }}>
                                            <div style={{
                                                padding: '14px 20px',
                                                display: 'flex', alignItems: 'center',
                                                justifyContent: 'space-between', gap: 16, flexWrap: 'wrap',
                                            }}>
                                                {/* Infos batch */}
                                                <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
                                                    <div style={{
                                                        width: 44, height: 44, borderRadius: 10,
                                                        background: 'linear-gradient(135deg,#1d4ed8,#1e40af)',
                                                        display: 'flex', alignItems: 'center', justifyContent: 'center',
                                                        fontSize: 20, flexShrink: 0,
                                                    }}>
                                                        🏦
                                                    </div>
                                                    <div>
                                                        <div style={{ fontSize: 14, fontWeight: 800, color: 'var(--text-primary)', textTransform: 'capitalize' }}>
                                                            XML du {dateLabel}
                                                        </div>
                                                        <div style={{ fontSize: 12, color: 'var(--text-muted)', marginTop: 2 }}>
                                                            Généré à {heureLabel} · {batch.nbNotes} virement{batch.nbNotes > 1 ? 's' : ''}
                                                        </div>
                                                        <div style={{ fontSize: 11, color: '#6366f1', marginTop: 3, fontFamily: 'monospace' }}>
                                                            {(batch.listeReferences || '')?.length > 80
                                                                ? (batch.listeReferences || '').slice(0, 80) + '...'
                                                                : (batch.listeReferences || '')}
                                                        </div>
                                                    </div>
                                                </div>

                                                {/* Montant + bouton */}
                                                <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexShrink: 0 }}>
                                                    <div style={{ textAlign: 'right' }}>
                                                        <div style={{
                                                            fontSize: 18, fontWeight: 900, color: '#1d4ed8',
                                                        }}>
                                                            {fmt(parseFloat(batch.totalMontant) || 0)}
                                                        </div>
                                                        <div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 2 }}>
                                                            total du batch
                                                        </div>
                                                    </div>
                                                    <button
                                                        disabled={isLoadingRegen}
                                                        onClick={async () => {
                                                            if (!noteIdsList.length) return;
                                                            setXmlRegenLoading(batchKey);
                                                            try {
                                                                const res = await fetch(`${API}/api/paiements/regenerer-xml`, {
                                                                    method: 'POST',
                                                                    headers: hdrs,
                                                                    body: JSON.stringify({ noteIds: noteIdsList })
                                                                });
                                                                if (!res.ok) {
                                                                    const e = await res.json();
                                                                    throw new Error(e.error);
                                                                }
                                                                const blob = await res.blob();
                                                                const url = URL.createObjectURL(blob);
                                                                const a = document.createElement('a');
                                                                a.href = url;
                                                                a.download = `virements-ndf-${batch.dateXmlJour}.xml`;
                                                                a.click();
                                                                URL.revokeObjectURL(url);
                                                                showToast(`✅ XML téléchargé — ${batch.nbNotes} virement(s)`, 'success');
                                                            } catch (e: any) {
                                                                showToast(e.message || 'Erreur lors du téléchargement', 'error');
                                                            } finally {
                                                                setXmlRegenLoading(null);
                                                            }
                                                        }}
                                                        style={{
                                                            display: 'flex', alignItems: 'center', gap: 8,
                                                            padding: '10px 20px',
                                                            background: isLoadingRegen
                                                                ? '#e2e8f0'
                                                                : 'linear-gradient(135deg,#1d4ed8,#1e40af)',
                                                            color: isLoadingRegen ? 'var(--text-muted)' : '#fff',
                                                            border: 'none', borderRadius: 9,
                                                            cursor: isLoadingRegen ? 'not-allowed' : 'pointer',
                                                            fontFamily: 'inherit', fontSize: 13, fontWeight: 700,
                                                            boxShadow: isLoadingRegen ? 'none' : '0 4px 12px rgba(29,78,216,.35)',
                                                            transition: 'all 0.15s',
                                                            whiteSpace: 'nowrap',
                                                        }}>
                                                        {isLoadingRegen ? (
                                                            <>⏳ Génération...</>
                                                        ) : (
                                                            <>⬇️ Télécharger XML</>
                                                        )}
                                                    </button>
                                                </div>
                                            </div>

                                            {/* Détail des références */}
                                            <div style={{
                                                padding: '10px 20px',
                                                borderTop: '1px solid var(--border-divider)',
                                                background: 'var(--bg-thead)',
                                                display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap',
                                            }}>
                                                <span style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '0.5px' }}>
                                                    Virements inclus :
                                                </span>
                                                {(batch.listeReferences || '').split(', ').slice(0, 8).map((ref: string, ri: number) => (
                                                    <span key={ri} style={{
                                                        fontSize: 11, fontWeight: 700,
                                                        background: '#eef2ff', color: '#6366f1',
                                                        padding: '2px 8px', borderRadius: 6,
                                                        fontFamily: 'monospace',
                                                    }}>
                                                        {ref.trim()}
                                                    </span>
                                                ))}
                                                {(batch.listeReferences || '').split(', ').length > 8 && (
                                                    <span style={{ fontSize: 11, color: 'var(--text-muted)', fontStyle: 'italic' }}>
                                                        +{(batch.listeReferences || '').split(', ').length - 8} autres
                                                    </span>
                                                )}
                                            </div>
                                        </div>
                                    );
                                })}
                            </div>
                        )}
                    </div>
                )}
            </main>

         

            {/* ── COMPARAISON ANCIENNE NOTE ── */}  
            {ancienneNoteComparaison && (
                <div style={{
                    position: 'fixed', inset: 0, zIndex: 9999,
                    background: 'rgba(0,0,0,0.7)', display: 'flex',
                    alignItems: 'center', justifyContent: 'center', padding: 20
                }}>
                    <div style={{
                        background: 'var(--bg-card)', borderRadius: 16,
                        padding: 24, maxWidth: 800, width: '100%',
                        maxHeight: '85vh', overflowY: 'auto'
                    }}>
                        <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 16 }}>
                            <h3 style={{ margin: 0, fontSize: 15, fontWeight: 800 }}>
                                🔄 Comparaison — Note originale refusée
                            </h3>
                            <button onClick={() => setAncienneNoteComparaison(null)}
                                style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 20 }}>✕</button>
                        </div>
                        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12, marginBottom: 16 }}>
                            {[
                                { label: 'Référence', value: ancienneNoteComparaison.reference },
                                { label: 'Statut', value: ancienneNoteComparaison.statut },
                                { label: 'Montant', value: fmt(ancienneNoteComparaison.montant || 0) },
                                {
                                    label: 'Date', value: ancienneNoteComparaison.date
                                        ? new Date(ancienneNoteComparaison.date).toLocaleDateString('fr-FR') : '—'
                                },
                                {
                                    label: 'Motif de refus', value:
                                        ancienneNoteComparaison.motifRefus ||
                                        (ancienneNoteComparaison as any).ancienMotifRefus ||
                                      
                                        ancienneNoteComparaison.commentaireN1 || '— Non renseigné'
                                },
                            ].map(({ label, value }) => (
                                <div key={label} style={{ background: '#fef2f2', borderRadius: 8, padding: '8px 12px' }}>
                                    <div style={{
                                        fontSize: 10, fontWeight: 700, color: '#dc2626',
                                        textTransform: 'uppercase', marginBottom: 2
                                    }}>{label}</div>
                                    <div style={{ fontSize: 13, fontWeight: 600 }}>{value}</div>
                                </div>
                            ))}
                        </div>
                        <LignesDetail
                            note={noteDetail!}
                            tarifKm={tarifKm}
                            onPreview={(url, name) => setPreviewUrl({ url: proxyUrl(url), name })}
                        />
                    </div>
                </div>
            )}
            {/* ── MODALE VALIDATION / REFUS ── */}
            {modalValidation && (
                <div style={{
                    position: 'fixed', inset: 0, zIndex: 10001,
                    background: 'rgba(0,0,0,0.6)', backdropFilter: 'blur(4px)',
                    display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 20
                }}>
                    <div style={{
                        background: 'var(--bg-card)', borderRadius: 16,
                        padding: 28, maxWidth: 460, width: '100%',
                        boxShadow: '0 24px 60px rgba(0,0,0,0.3)',
                    }}>
                        {/* En-tête */}
                        <div style={{
                            display: 'flex', alignItems: 'center', gap: 14, marginBottom: 24,
                            paddingBottom: 16, borderBottom: '1px solid var(--border-divider)'
                        }}>
                            <div style={{
                                width: 44, height: 44, borderRadius: 12, flexShrink: 0,
                                background: modalValidation.action === 'valider'
                                    ? 'linear-gradient(135deg,#10b981,#059669)'
                                    : 'linear-gradient(135deg,#ef4444,#dc2626)',
                                display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 22
                            }}>
                                {modalValidation.action === 'valider' ? '✅' : '❌'}
                            </div>
                            <div>
                                <div style={{ fontSize: 16, fontWeight: 800, color: 'var(--text-primary)' }}>
                                    {modalValidation.action === 'valider' ? 'Valider la note' : 'Refuser la note'}
                                </div>
                                <div style={{ fontSize: 12, color: 'var(--text-muted)', marginTop: 2 }}>
                                    {modalValidation.action === 'valider'
                                        ? 'La note passera à l\'étape suivante du circuit de validation.'
                                        : 'La note sera retournée au collaborateur pour correction.'}
                                </div>
                            </div>
                        </div>

                        {/* Champ commentaire — obligatoire pour refus, optionnel pour validation */}
                        <div style={{ marginBottom: 20 }}>
                            <label style={{
                                display: 'block', fontSize: 12, fontWeight: 700,
                                color: 'var(--text-secondary)', textTransform: 'uppercase',
                                letterSpacing: '0.6px', marginBottom: 8
                            }}>
                                {modalValidation.action === 'refuser'
                                    ? 'Motif de refus *'
                                    : 'Commentaire (optionnel)'}
                            </label>
                            <textarea
                                autoFocus
                                value={motifRefusInput}
                                onChange={e => setMotifRefusInput(e.target.value)}
                                placeholder={modalValidation.action === 'refuser'
                                    ? 'Ex : Justificatif manquant, montant incorrect...'
                                    : 'Ex : Dossier complet, bon pour accord...'}
                                rows={3}
                                style={{
                                    width: '100%', padding: '10px 14px',
                                    border: `1.5px solid ${modalValidation.action === 'refuser' && !motifRefusInput.trim()
                                        ? '#fca5a5' : 'var(--border-input)'
                                        }`,
                                    borderRadius: 8, resize: 'vertical',
                                    background: 'var(--bg-input)',
                                    fontFamily: '"Inter","Segoe UI",sans-serif',
                                    fontSize: 13, color: 'var(--text-primary)',
                                    outline: 'none', boxSizing: 'border-box',
                                    transition: 'border-color 0.2s'
                                }}
                                onFocus={e => e.currentTarget.style.borderColor =
                                    modalValidation.action === 'valider' ? '#86efac' : '#6366f1'}
                                onBlur={e => e.currentTarget.style.borderColor = 'var(--border-input)'}
                            />
                            {modalValidation.action === 'refuser' && !motifRefusInput.trim() && (
                                <div style={{ fontSize: 11, color: '#ef4444', marginTop: 4 }}>
                                    Le motif de refus est obligatoire
                                </div>
                            )}
                        </div>

                        {/* Boutons */}
                        <div style={{ display: 'flex', gap: 10 }}>
                            <button
                                onClick={() => { setModalValidation(null); setMotifRefusInput(''); }}
                                style={{
                                    flex: 1, padding: '11px 16px',
                                    background: 'var(--bg-input)',
                                    border: '1px solid var(--border-input)',
                                    borderRadius: 9, cursor: 'pointer',
                                    fontFamily: 'inherit', fontSize: 13, fontWeight: 600,
                                    color: 'var(--text-secondary)'
                                }}>
                                Annuler
                            </button>
                            <button
                                disabled={
                                    validationLoading ||
                                    (modalValidation.action === 'refuser' && !motifRefusInput.trim())
                                }
                                onClick={async () => {
                                    setValidationLoading(true);
                                    try {
                                        await handleValider(
                                            modalValidation.noteId,
                                            modalValidation.action,
                                            motifRefusInput.trim() || undefined
                                        );
                                        setModalValidation(null);
                                        setMotifRefusInput('');
                                        modalValidation.onClose();
                                    } catch { }
                                    finally { setValidationLoading(false); }
                                }}
                                style={{
                                    flex: 2, padding: '11px 16px',
                                    background: modalValidation.action === 'valider'
                                        ? 'linear-gradient(135deg,#10b981,#059669)'
                                        : 'linear-gradient(135deg,#ef4444,#dc2626)',
                                    color: '#fff', border: 'none', borderRadius: 9,
                                    cursor: (validationLoading || (modalValidation.action === 'refuser' && !motifRefusInput.trim()))
                                        ? 'not-allowed' : 'pointer',
                                    fontFamily: 'inherit', fontSize: 13, fontWeight: 700,
                                    opacity: (validationLoading || (modalValidation.action === 'refuser' && !motifRefusInput.trim()))
                                        ? 0.6 : 1,
                                    display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
                                    transition: 'opacity 0.15s'
                                }}>
                                {validationLoading
                                    ? <><div style={{ width: 14, height: 14, border: '2px solid rgba(255,255,255,0.4)', borderTop: '2px solid #fff', borderRadius: '50%', animation: 'spin 0.7s linear infinite' }} /> Traitement...</>
                                    : modalValidation.action === 'valider' ? '✅ Confirmer la validation' : '❌ Confirmer le refus'
                                }
                            </button>
                        </div>
                    </div>
                </div>
            )}
            <NDFChatbot />

           

            {/* ── URL PREVIEW ── */}
            {previewUrl && <UrlPreviewPopup item={previewUrl} onClose={() => setPreviewUrl(null)} />}

            {/* ── TOAST ── */}
            {toast && (
                <div style={{ position: 'fixed', bottom: 24, right: 24, zIndex: 9999, background: toast.type === 'error' ? '#dc2626' : '#15803d', color: '#fff', borderRadius: 10, padding: '14px 22px', fontSize: 14, fontWeight: 600, maxWidth: 400, boxShadow: '0 8px 24px rgba(0,0,0,.18)' }}>
                    {toast.msg}
                </div>
            )}
        </div>
    );
};

export default Dashboard;