// InstantDevis — Écran Catalogue Prestations

function AfCatalogue({ t, onBack }) {
  const [items, setItems] = React.useState(() => AF_CATALOG_STORE.getAll());
  const [mode, setMode]   = React.useState('list'); // list | add | edit
  const [editItem, setEditItem] = React.useState(null);
  const [filter, setFilter]     = React.useState('all');
  const [search, setSearch]     = React.useState('');

  const [importPhase, setImportPhase] = React.useState('idle');
  const [importResult, setImportResult] = React.useState('');
  const [previewItems, setPreviewItems] = React.useState([]);
  const [isDragging, setIsDragging] = React.useState(false);
  const fileInputRef = React.useRef(null);

  React.useEffect(() => AF_CATALOG_STORE.subscribe(setItems), []);

  const handleDragOver = (e) => { e.preventDefault(); setIsDragging(true); };
  const handleDragLeave = () => setIsDragging(false);
  const handleDrop = (e) => {
    e.preventDefault();
    setIsDragging(false);
    const file = e.dataTransfer.files?.[0];
    if (file) processFile(file);
  };
  const handleFileChange = (e) => {
    const file = e.target.files?.[0];
    if (file) processFile(file);
  };

  const guessColumns = (rows) => {
    if (!rows || !rows.length) return null;
    const keys = Object.keys(rows[0]);
    if (!keys.length) return null;
    const low = (s) => String(s).toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '');
    const find = (hints) => {
      for (const h of hints) {
        const k = keys.find((x) => low(x).includes(h));
        if (k) return k;
      }
      return null;
    };
    const labelKey = find(['design', 'libell', 'article', 'prestation', 'intitul', 'nom', 'description', 'label']) || keys[0];
    const restKeys = keys.filter((k) => k !== labelKey);
    return {
      label: labelKey,
      pu: find(['prix', 'pu ht', 'pu', 'montant', 'ht', 'tarif', 'euro', 'euros']) || restKeys[0],
      unit: find(['unit', 'unite', 'u.', 'um', 'm2', 'm²']) || restKeys[1] || 'u',
      tva: find(['tva', 'taxe', 't.v.a']),
    };
  };

  const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5 Mo
  const XLSX_CDN = 'https://unpkg.com/xlsx@0.18.5/dist/xlsx.full.min.js';

  const _loadScript = (src) => new Promise((resolve, reject) => {
    const s = document.createElement('script');
    s.src = src;
    s.onload = resolve;
    s.onerror = () => reject(new Error('Échec du chargement : ' + src));
    document.head.appendChild(s);
  });

  const processFile = async (file) => {
    if (file.size > MAX_FILE_SIZE) {
      alert(`Fichier trop volumineux (${(file.size / 1024 / 1024).toFixed(1)} Mo). Limite : 5 Mo.`);
      return;
    }

    if (typeof XLSX === 'undefined') {
      setImportPhase('reading');
      try {
        await _loadScript(XLSX_CDN);
      } catch {
        const off = typeof navigator !== 'undefined' && !navigator.onLine;
        alert(
          off
            ? "Import fichier : la bibliothèque XLSX n'est pas chargée. Ouvrez l'app une fois avec connexion (ou rechargez la page en ligne) pour la télécharger, puis l'import pourra fonctionner hors ligne."
            : "Impossible de charger la bibliothèque d'import. Vérifiez votre connexion internet."
        );
        setImportPhase('idle');
        return;
      }
    }

    setImportPhase('reading');
    const prof = typeof AF_PROFILE_STORE !== 'undefined' ? AF_PROFILE_STORE.get() : {};
    const reader = new FileReader();

    reader.onload = async (e) => {
      try {
        const data = new Uint8Array(e.target.result);

        let workbook;
        try {
          workbook = XLSX.read(data, { type: 'array' });
        } catch (parseErr) {
          throw new Error(`Fichier illisible ou corrompu : ${parseErr.message}`);
        }

        const firstSheetName = workbook.SheetNames[0];
        const worksheet = workbook.Sheets[firstSheetName];
        const json = XLSX.utils.sheet_to_json(worksheet, { defval: "" });

        if (json.length === 0) throw new Error("Fichier vide ou sans données dans le premier onglet.");

        setImportPhase('parsing');
        const mapping = guessColumns(json);
        if (!mapping || !mapping.label) {
          const found = json[0] ? Object.keys(json[0]).slice(0, 5).join(', ') : '(aucune)';
          throw new Error(`Colonne désignation introuvable.\nColonnes détectées : ${found}.\nRenommez la colonne principale en "Désignation" ou "Label".`);
        }

        const parsedItems = [];
        let rejectedCount = 0;
        json.forEach((row) => {
          const rowLabel = row[mapping.label];
          if (!rowLabel || String(rowLabel).trim() === '') return;

          const colPu = mapping.pu && row[mapping.pu] !== undefined && row[mapping.pu] !== '' ? row[mapping.pu] : null;
          let rowPu;
          if (colPu === null) {
            rowPu = 0;
          } else {
            rowPu = parseFloat(String(colPu).replace(/\s/g, '').replace(',', '.'));
            if (isNaN(rowPu)) {
              rejectedCount++;
              return;
            }
          }

          let rowTva = prof.defaultTva !== undefined ? prof.defaultTva : 20;
          if (mapping.tva && row[mapping.tva] !== undefined && String(row[mapping.tva]).trim() !== '') {
            const parsedTva = parseFloat(String(row[mapping.tva]).replace(',', '.'));
            if (!isNaN(parsedTva)) rowTva = parsedTva;
          }

          const rawUnit = mapping.unit && row[mapping.unit] !== undefined ? row[mapping.unit] : 'u';
          const rowUnit = String(rawUnit).trim().toLowerCase();

          parsedItems.push({
            id: `temp-${Date.now()}-${Math.random()}`,
            label: String(rowLabel).trim(),
            pu: rowPu,
            unit: rowUnit,
            tva: rowTva,
            trade: 'multi',
            keywords: [],
          });
        });

        if (parsedItems.length === 0) {
          const reason = rejectedCount > 0
            ? `Aucun article importé — ${rejectedCount} ligne(s) ignorée(s) car le prix est non numérique.`
            : "Aucun article valide trouvé.";
          throw new Error(reason);
        }

        if (rejectedCount > 0) {
          console.warn(`[Import XLSX] ${rejectedCount} ligne(s) ignorée(s) — prix non numérique.`);
        }

        setPreviewItems(parsedItems);
        setImportPhase('preview');
      } catch (err) {
        console.error('[Import XLSX]', err);
        alert("Erreur lors de l'importation :\n" + err.message);
        setImportPhase('idle');
      }
    };

    reader.onerror = () => {
      alert("Impossible de lire le fichier. Vérifiez les permissions ou réessayez.");
      setImportPhase('idle');
    };

    reader.readAsArrayBuffer(file);
  };

  const confirmImport = () => {
    previewItems.forEach(item => {
      const { id, ...itemData } = item;
      AF_CATALOG_STORE.add(itemData);
    });
    setImportResult(`Catalogue importé avec succès : ${previewItems.length} articles ajoutés.`);
    setImportPhase('done');
    setTimeout(() => { setImportPhase('idle'); setImportResult(''); setPreviewItems([]); }, 4000);
  };

  const cancelImport = () => {
    setImportPhase('idle');
    setPreviewItems([]);
  };

  const trades = [
    { id: 'all',         label: 'Tous' },
    { id: 'multi',       label: 'Multi' },
    { id: 'plomberie',   label: 'Plomberie' },
    { id: 'electricite', label: 'Électricité' },
    { id: 'peinture',    label: 'Peinture' },
  ];

  const visible = items.filter(it => {
    const matchTrade = filter === 'all' || it.trade === filter;
    const matchSearch = !search || it.label.toLowerCase().includes(search.toLowerCase());
    return matchTrade && matchSearch;
  });

  const startAdd  = () => {
    const prof = typeof AF_PROFILE_STORE !== 'undefined' ? AF_PROFILE_STORE.get() : {};
    setEditItem({ label:'', unit:'h', pu:'', tva: prof.defaultTva !== undefined ? prof.defaultTva : 20, trade:'multi', keywords:[] });
    setMode('add');
  };
  const startEdit = (it) => { setEditItem({ ...it }); setMode('edit'); };
  const cancel    = () => { setEditItem(null); setMode('list'); };

  const saveItem = () => {
    if (!editItem.label || !editItem.pu) return;
    const item = { ...editItem, pu: parseFloat(editItem.pu) || 0, tva: parseInt(editItem.tva) || 20,
      keywords: typeof editItem.keywords === 'string'
        ? editItem.keywords.split(',').map(k => k.trim()).filter(Boolean)
        : editItem.keywords };
    if (mode === 'add') AF_CATALOG_STORE.add(item);
    else AF_CATALOG_STORE.update(item.id, item);
    cancel();
  };

  const removeItem = (id) => {
    if (window.confirm('Supprimer cette prestation ?')) AF_CATALOG_STORE.remove(id);
  };

  const resetCatalog = () => {
    if (window.confirm('Réinitialiser le catalogue avec les 16 prestations par défaut ?'))
      AF_CATALOG_STORE.reset();
  };

  // ── Formulaire Add/Edit ─────────────────────────────────────
  if (mode === 'add' || mode === 'edit') {
    const upd = (k, v) => setEditItem(f => ({ ...f, [k]: v }));
    const unitOptions = ['h', 'm²', 'ml', 'm³', 'pce', 'forfait', 'jour'];
    const tvaOptions  = [0, 5.5, 10, 20];
    const tradeOpts   = [
      { id: 'multi',       label: 'Multi-métier' },
      { id: 'plomberie',   label: 'Plomberie' },
      { id: 'electricite', label: 'Électricité' },
      { id: 'peinture',    label: 'Peinture' },
    ];
    return (
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', background: t.bg }}>
        <AfScreenHeader
          title={mode === 'add' ? 'Nouvelle prestation' : 'Modifier prestation'}
          subtitle="Catalogue" t={t} back onBack={cancel}
        />
        <div style={{ flex: 1, overflowY: 'auto', padding: '14px 16px 100px', display: 'flex', flexDirection: 'column', gap: 12 }}>
          <AfProfileField label="Désignation" value={editItem.label} onChange={v => upd('label', v)} t={t}
            placeholder="Ex : Pose WC suspendu" required />
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
            <div>
              <label style={{ fontSize: 11, fontWeight: 700, color: t.textMuted, textTransform: 'uppercase', display: 'block', marginBottom: 6 }}>Unité</label>
              <select value={editItem.unit} onChange={e => upd('unit', e.target.value)}
                style={{ width: '100%', padding: '11px 12px', borderRadius: 8, background: t.bgElevated, border: `1.5px solid ${t.border}`, fontSize: 14, color: t.text, fontWeight: 600 }}>
                {unitOptions.map(u => <option key={u} value={u}>{u}</option>)}
              </select>
            </div>
            <AfProfileField label="Prix unitaire HT (€)" value={String(editItem.pu)} onChange={v => upd('pu', v)} t={t} placeholder="0.00" type="number" />
          </div>
          <div>
            <label style={{ fontSize: 11, fontWeight: 700, color: t.textMuted, textTransform: 'uppercase', display: 'block', marginBottom: 6 }}>Taux TVA</label>
            <div style={{ display: 'flex', gap: 8 }}>
              {tvaOptions.map(r => (
                <button key={r} onClick={() => upd('tva', r)} style={{
                  flex: 1, padding: '11px 0', borderRadius: 8, cursor: 'pointer', fontWeight: 700, fontSize: 14,
                  background: editItem.tva === r ? t.primary : t.bgElevated,
                  color: editItem.tva === r ? '#fff' : t.text,
                  border: `1.5px solid ${editItem.tva === r ? t.primary : t.border}`,
                }}>{r}%</button>
              ))}
            </div>
          </div>
          <div>
            <label style={{ fontSize: 11, fontWeight: 700, color: t.textMuted, textTransform: 'uppercase', display: 'block', marginBottom: 6 }}>Métier</label>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
              {tradeOpts.map(tr => {
                const meta = AF_TRADE_META[tr.id] || AF_TRADE_META.multi;
                return (
                  <button key={tr.id} onClick={() => upd('trade', tr.id)} style={{
                    padding: '7px 12px', borderRadius: 20, fontSize: 12, fontWeight: 700, cursor: 'pointer',
                    border: `1.5px solid ${editItem.trade === tr.id ? meta.color : t.border}`,
                    background: editItem.trade === tr.id ? meta.color + '22' : t.bgElevated,
                    color: editItem.trade === tr.id ? meta.color : t.textMuted,
                  }}>{tr.label}</button>
                );
              })}
            </div>
          </div>
          <AfProfileField label="Mots-clés (séparés par virgule)"
            value={Array.isArray(editItem.keywords) ? editItem.keywords.join(', ') : editItem.keywords}
            onChange={v => upd('keywords', v)} t={t}
            placeholder="wc, toilette, sanitaire, cuvette"
            hint="Utilisés par la dictée vocale pour trouver cette prestation automatiquement"
          />
        </div>
        <div style={{ padding: '12px 16px', background: t.bg, borderTop: `1px solid ${t.border}`, display: 'flex', gap: 8 }}>
          <button onClick={cancel} style={{ flex: 1, height: 52, borderRadius: 10, background: t.bgElevated, border: `1.5px solid ${t.border}`, fontSize: 14, fontWeight: 700, color: t.textMuted, cursor: 'pointer' }}>
            Annuler
          </button>
          <button onClick={saveItem} disabled={!editItem.label || !editItem.pu} style={{
            flex: 2, height: 52, borderRadius: 10, border: 'none', cursor: 'pointer',
            background: editItem.label && editItem.pu ? t.safety : t.bgSunken,
            fontSize: 14, fontWeight: 800, color: editItem.label && editItem.pu ? '#0D1520' : t.textMuted,
            display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 7,
          }}>
            <lucide.Check size={18} />
            {mode === 'add' ? 'Ajouter au catalogue' : 'Enregistrer'}
          </button>
        </div>
      </div>
    );
  }

  // ── Liste ────────────────────────────────────────────────────
  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflowY: 'auto', background: t.bg }}>
      <AfScreenHeader
        title="Catalogue"
        subtitle={`${items.length} prestations`}
        t={t} back onBack={onBack}
        tape
        rightAction={
          <button onClick={startAdd} style={{
            display: 'flex', alignItems: 'center', gap: 5, padding: '7px 12px', borderRadius: 8,
            background: t.safety, border: 'none', cursor: 'pointer', fontSize: 12, fontWeight: 800, color: '#0D1520',
          }}>
            <lucide.Plus size={16} /> Ajouter
          </button>
        }
      />

      {/* Import Zone */}
      <div style={{ padding: '14px 16px 4px' }}>
        {importPhase === 'preview' ? (
          <div style={{ background: t.bgElevated, borderRadius: 12, border: `1px solid ${t.border}`, overflow: 'hidden', animation: 'af-slide-up 0.3s both' }}>
            <div style={{ padding: '12px 16px', borderBottom: `1px solid ${t.border}`, background: 'rgba(11,61,92,0.06)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
              <div style={{ fontSize: 13, fontWeight: 800, color: t.primary }}>Aperçu de l'importation</div>
              <div style={{ fontSize: 11, fontWeight: 700, color: t.primary, background: '#fff', padding: '2px 8px', borderRadius: 12, border: `1px solid rgba(11,61,92,0.2)` }}>
                {previewItems.length} articles
              </div>
            </div>
            <div style={{ maxHeight: 240, overflowY: 'auto' }}>
              <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12 }}>
                <thead style={{ position: 'sticky', top: 0, background: t.bgElevated, boxShadow: `0 1px 0 ${t.border}` }}>
                  <tr>
                    <th style={{ padding: '8px 12px', textAlign: 'left', color: t.textMuted, fontWeight: 700 }}>Désignation</th>
                    <th style={{ padding: '8px 12px', textAlign: 'right', color: t.textMuted, fontWeight: 700 }}>Prix HT</th>
                    <th style={{ padding: '8px 12px', textAlign: 'center', color: t.textMuted, fontWeight: 700 }}>Unité</th>
                    <th style={{ padding: '8px 12px', textAlign: 'right', color: t.textMuted, fontWeight: 700 }}>TVA</th>
                  </tr>
                </thead>
                <tbody>
                  {previewItems.slice(0, 30).map((it, i) => (
                    <tr key={i} style={{ borderBottom: i === 29 || i === previewItems.length - 1 ? 'none' : `1px solid ${t.border}` }}>
                      <td style={{ padding: '8px 12px', color: t.text, fontWeight: 600 }}>{it.label}</td>
                      <td style={{ padding: '8px 12px', textAlign: 'right', color: t.text, whiteSpace: 'nowrap' }} className="af-mono">{it.pu.toFixed(2)} €</td>
                      <td style={{ padding: '8px 12px', textAlign: 'center', color: t.textMuted }}>{it.unit}</td>
                      <td style={{ padding: '8px 12px', textAlign: 'right', color: t.textMuted }}>{it.tva}%</td>
                    </tr>
                  ))}
                </tbody>
              </table>
              {previewItems.length > 30 && (
                <div style={{ padding: '10px', textAlign: 'center', fontSize: 11, color: t.textMuted, fontStyle: 'italic', background: 'linear-gradient(to bottom, rgba(255,255,255,0), rgba(255,255,255,1))' }}>
                  ... et {previewItems.length - 30} autres articles
                </div>
              )}
            </div>
            <div style={{ padding: '12px 16px', display: 'flex', gap: 10, background: t.bgElevated, borderTop: `1px solid ${t.border}` }}>
              <button onClick={cancelImport} style={{ flex: 1, padding: '10px', borderRadius: 8, background: t.bgSunken, border: `1px solid ${t.border}`, fontSize: 13, fontWeight: 700, color: t.textMuted, cursor: 'pointer' }}>
                Annuler
              </button>
              <button onClick={confirmImport} style={{ flex: 2, padding: '10px', borderRadius: 8, background: '#10B981', border: 'none', fontSize: 13, fontWeight: 800, color: '#fff', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6, boxShadow: '0 4px 12px rgba(16,185,129,0.3)' }}>
                <lucide.CheckCircle size={16} /> Confirmer ({previewItems.length})
              </button>
            </div>
          </div>
        ) : importPhase === 'idle' ? (
          <div 
            onDragOver={handleDragOver} onDragLeave={handleDragLeave} onDrop={handleDrop}
            onClick={() => fileInputRef.current?.click()}
            style={{
              border: `2px dashed ${isDragging ? t.safety : t.border}`,
              background: isDragging ? 'rgba(255,107,0,0.05)' : t.bgElevated,
              borderRadius: 12, padding: '16px', textAlign: 'center', cursor: 'pointer',
              transition: 'all 0.2s', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6
            }}
          >
            <lucide.CloudUpload size={24} color={isDragging ? t.safety : t.textMuted} />
            <div style={{ fontSize: 13, fontWeight: 700, color: isDragging ? t.safety : t.text }}>
              Glissez un fichier Excel / CSV
            </div>
            <div style={{ fontSize: 11, color: t.textMuted }}>ou cliquez — détection de colonnes automatique (local)</div>
            <input type="file" accept=".xlsx,.csv" ref={fileInputRef} onChange={handleFileChange} style={{ display: 'none' }} />
          </div>
        ) : importPhase === 'done' ? (
          <div style={{ padding: '12px', borderRadius: 10, background: 'rgba(16,185,129,0.1)', border: '1px solid #10B981', display: 'flex', alignItems: 'center', gap: 10 }}>
            <lucide.CheckCircle size={20} color="#10B981" />
            <span style={{ fontSize: 13, color: '#10B981', fontWeight: 700 }}>{importResult}</span>
          </div>
        ) : (
          <div style={{ padding: '16px', borderRadius: 12, background: t.bgElevated, border: `1px solid ${t.border}`, display: 'flex', alignItems: 'center', gap: 12 }}>
            <lucide.Loader size={20} color={t.safety} style={{ animation: 'af-pulse 1s infinite' }} />
            <div>
              <div style={{ fontSize: 13, fontWeight: 700, color: t.text }}>
                {importPhase === 'reading' ? 'Lecture du fichier...' : 'Détection des colonnes (local)...'}
              </div>
              <div style={{ fontSize: 11, color: t.textMuted }}>Merci de patienter</div>
            </div>
          </div>
        )}
      </div>

      {/* Search + filter */}
      <div style={{ padding: '10px 16px', borderBottom: `1px solid ${t.border}`, display: 'flex', flexDirection: 'column', gap: 8 }}>
        <div style={{ position: 'relative' }}>
          <lucide.Search size={15} color={t.textMuted} style={{ position: 'absolute', left: 12, top: '50%', transform: 'translateY(-50%)' }} />
          <input value={search} onChange={e => setSearch(e.target.value)} placeholder="Rechercher une prestation…"
            style={{ width: '100%', padding: '9px 12px 9px 34px', borderRadius: 8, background: t.bgElevated, border: `1.5px solid ${t.border}`, fontSize: 13, color: t.text, outline: 'none', fontWeight: 500 }} />
        </div>
        <div style={{ display: 'flex', gap: 5, overflowX: 'auto' }}>
          {trades.map(tr => (
            <button key={tr.id} onClick={() => setFilter(tr.id)} style={{
              flexShrink: 0, padding: '5px 10px', borderRadius: 16,
              background: filter === tr.id ? t.primary : t.bgElevated,
              color: filter === tr.id ? '#fff' : t.textMuted,
              border: `1px solid ${filter === tr.id ? t.primary : t.border}`,
              fontSize: 11, fontWeight: 700, cursor: 'pointer',
            }}>{tr.label}</button>
          ))}
        </div>
      </div>

      {/* Liste items */}
      <div style={{ flex: 1, overflowY: 'auto', padding: '10px 16px 80px', display: 'flex', flexDirection: 'column', gap: 6 }}>
        {visible.map(it => {
          const meta = AF_TRADE_META[it.trade] || AF_TRADE_META.multi;
          return (
            <div key={it.id} style={{
              background: t.bgElevated, borderRadius: 10, border: `1px solid ${t.border}`, padding: '11px 14px',
              display: 'flex', alignItems: 'center', gap: 10,
            }}>
              <div style={{ width: 6, height: 36, borderRadius: 3, background: meta.color, flexShrink: 0 }} />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 13, fontWeight: 700, color: t.text }}>{it.label}</div>
                <div style={{ fontSize: 11, color: t.textMuted, marginTop: 2 }}>
                  <span className="af-mono">{it.pu} €</span> / {it.unit}
                  <span style={{ marginLeft: 8, padding: '1px 5px', borderRadius: 3, background: `rgba(11,61,92,0.1)`, color: t.primary, fontSize: 10, fontWeight: 700 }}>TVA {it.tva}%</span>
                </div>
              </div>
              <div style={{ display: 'flex', gap: 4, flexShrink: 0 }}>
                <button onClick={() => startEdit(it)} aria-label={`Modifier ${it.label}`} style={{ width: 34, height: 34, borderRadius: 7, background: t.bgSunken, border: `1px solid ${t.border}`, display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer' }}>
                  <lucide.PenTool size={14} color={t.primary} />
                </button>
                <button onClick={() => removeItem(it.id)} aria-label={`Supprimer ${it.label}`} style={{ width: 34, height: 34, borderRadius: 7, background: 'rgba(239,68,68,0.08)', border: '1px solid rgba(239,68,68,0.3)', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer' }}>
                  <lucide.Trash2 size={14} color="#EF4444" />
                </button>
              </div>
            </div>
          );
        })}
        {visible.length === 0 && (
          <div style={{ textAlign: 'center', padding: '40px 20px', color: t.textMuted }}>
            <lucide.Package size={32} color={t.border} style={{ margin: '0 auto 10px' }} />
            <div style={{ fontSize: 13, fontWeight: 600 }}>Aucune prestation trouvée</div>
          </div>
        )}
      </div>

      {/* Footer reset */}
      <div style={{ padding: '10px 16px', borderTop: `1px solid ${t.border}`, background: t.bg }}>
        <button onClick={resetCatalog} style={{ width: '100%', padding: '10px', borderRadius: 8, background: 'none', border: `1px solid ${t.border}`, fontSize: 11, fontWeight: 700, color: t.textMuted, cursor: 'pointer' }}>
          ↺ Réinitialiser le catalogue par défaut
        </button>
      </div>
    </div>
  );
}

Object.assign(window, { AfCatalogue });
