/* global React */
// FOST library + Signatures + Command palette + Copilot sidebar

function FostPage() {
  const [q, setQ] = useState('');
  const catalog = FOST_CATALOG || [];
  const [sel, setSel] = useState(catalog[0] || null);
  const filtered = catalog.filter(f => (f.code + f.name).toLowerCase().includes(q.toLowerCase()));

  // Empty state si catalogue vide (vault non sync)
  if (catalog.length === 0) {
    return (
      <div style={{ padding: '16px 24px 80px' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 16 }}>
          <h1 style={{ fontSize: 20, fontWeight: 600, letterSpacing: '-0.02em', margin: 0 }}>Bibliothèque FOST</h1>
        </div>
        {window.EmptyState ? (
          <window.EmptyState
            icon="📚"
            title="Catalogue FOST vide"
            sub="Le vault Obsidian n'est pas encore synchronisé ou aucune fiche FOST n'a été chargée. Synchronisez le vault ou utilisez le module Audit énergétique pour tester les 55 FOSTs intégrées."
            cta={{ label: '⚡ Audit énergétique', onClick: () => window.AE_NAV?.('audit') }}
            secondaryCta={{ label: 'Étude réglementaire', onClick: () => window.AE_NAV?.('etudes-reg') }}
          />
        ) : <div style={{ padding: 40, color: 'var(--ink-4)', textAlign: 'center' }}>Catalogue vide</div>}
      </div>
    );
  }

  return (
    <div style={{ padding: '16px 24px 80px' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 16 }}>
        <h1 style={{ fontSize: 20, fontWeight: 600, letterSpacing: '-0.02em', margin: 0 }}>Bibliothèque FOST</h1>
        <span className="mono" style={{ fontSize: 11, color: 'var(--ink-4)' }}>{catalog.length} fiches · vault Obsidian synchronisé</span>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: '420px 1fr', gap: 16 }}>
        <div style={{ border: '1px solid var(--line)', borderRadius: 8, background: 'var(--paper-2)' }}>
          <div style={{ padding: 10, borderBottom: '1px solid var(--hairline)', display: 'flex', gap: 6, alignItems: 'center' }}>
            <Icon.search style={{ color: 'var(--ink-4)' }} />
            <input value={q} onChange={e => setQ(e.target.value)} placeholder="BAR-TH-104, pompe à chaleur…"
              style={{ flex: 1, border: 'none', background: 'transparent', fontSize: 13, color: 'var(--ink)', outline: 'none', fontFamily: 'inherit' }} />
            <span className="mono" style={{ fontSize: 10, color: 'var(--ink-4)' }}>{filtered.length}</span>
          </div>
          <div style={{ maxHeight: 640, overflowY: 'auto' }}>
            {filtered.length === 0 && (
              <div style={{ padding: '40px 20px', textAlign: 'center', color: 'var(--ink-4)', fontSize: 12 }}>
                Aucune fiche pour "<strong>{q}</strong>". Essayez un autre code ou mot-clé.
              </div>
            )}
            {filtered.map(f => (
              <button key={f.code} onClick={() => setSel(f)} style={{
                width: '100%', display: 'grid', gridTemplateColumns: '90px 1fr 40px', gap: 10, alignItems: 'center',
                padding: '10px 14px', borderBottom: '1px solid var(--hairline)', textAlign: 'left',
                background: sel?.code === f.code ? 'var(--signal-tint)' : 'transparent',
              }}>
                <span className="mono" style={{ fontSize: 11, fontWeight: 600 }}>{f.code}</span>
                <div>
                  <div style={{ fontSize: 11, fontWeight: 500, lineHeight: 1.25 }}>{f.name}</div>
                  <div style={{ fontSize: 10, color: 'var(--ink-4)', marginTop: 2 }}>{f.sector} · {f.usage}{f.coupdepouce ? ' · coup de pouce' : ''}</div>
                </div>
                <span className="num" style={{ fontSize: 11, color: 'var(--ink-3)', textAlign: 'right' }}>{f.count}</span>
              </button>
            ))}
          </div>
        </div>

        <div style={{ border: '1px solid var(--line)', borderRadius: 8, background: 'var(--paper-2)', padding: 24 }}>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 10, marginBottom: 4 }}>
            <span className="mono" style={{ fontSize: 22, fontWeight: 600, letterSpacing: '-0.02em' }}>{sel.code}</span>
            <Badge tone="signal">Actif</Badge>
            {sel.coupdepouce && <Badge tone="plasma">Coup de pouce</Badge>}
          </div>
          <h2 style={{ fontSize: 18, fontWeight: 500, margin: '0 0 20px', color: 'var(--ink-2)' }}>{sel.name}</h2>

          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 0, border: '1px solid var(--line)', borderRadius: 6, background: 'var(--paper)', overflow: 'hidden', marginBottom: 20 }}>
            <MiniKpi label="Secteur" value={sel.sector} accent="var(--ink)" />
            <MiniKpi label="Usage" value={sel.usage} accent="var(--ink)" divider />
            <MiniKpi label="Cumac moyen" value={fmtMWh(sel.avgCumac)} accent="var(--signal)" divider />
            <MiniKpi label="Dossiers" value={sel.count} accent="var(--signal)" divider />
          </div>

          <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 10 }}>Formule de calcul</div>
          <div style={{ padding: 16, background: 'var(--paper)', border: '1px solid var(--line)', borderRadius: 6, fontFamily: 'var(--font-mono)', fontSize: 13 }}>
            kWh_cumac = <span style={{ color: 'var(--signal-deep)' }}>forfait</span> × <span style={{ color: 'var(--signal-deep)' }}>puissance_kW</span> × <span style={{ color: 'var(--signal-deep)' }}>zone[{sel.zones.join('|')}]</span>{sel.coupdepouce ? <> × <span style={{ color: 'var(--plasma)' }}>coup_de_pouce</span></> : null}
          </div>

          <div style={{ fontSize: 13, fontWeight: 600, margin: '20px 0 10px' }}>Historique des arrêtés</div>
          <div>
            {[
              { v: 'v5 (consolidée)', d: '04/2026', active: true },
              { v: 'v4', d: '07/2024', active: false },
              { v: 'v3', d: '12/2022', active: false },
            ].map((h, i) => (
              <div key={i} style={{ display: 'grid', gridTemplateColumns: '120px 120px 1fr', padding: '8px 12px', fontSize: 12, borderBottom: '1px solid var(--hairline)' }}>
                <span className="mono" style={{ color: h.active ? 'var(--ink)' : 'var(--ink-4)', fontWeight: h.active ? 600 : 400 }}>{h.v}</span>
                <span className="mono" style={{ color: 'var(--ink-3)' }}>{h.d}</span>
                <span style={{ color: 'var(--ink-3)' }}>{h.active ? 'Bonification précarité prolongée 2028' : 'archivé'}</span>
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

// ───────────── Signature screens ─────────────
function SignaturesPage({ onOpenSigner }) {
  const API = (window.AE_API && window.AE_API.BASE) || '';
  const [liveSigs, setLiveSigs] = useState(null); // null = loading, [] = backend empty
  const [actionState, setActionState] = useState({}); // { [sigId]: 'resending'|'revoking'|null }

  const refresh = async () => {
    if (!window.AE_API?.listSignatures) {
      setLiveSigs([]); // backend not available → empty state, pas de fixtures
      return;
    }
    const res = await window.AE_API.listSignatures();
    if (res?.ok && Array.isArray(res.signatures)) {
      setLiveSigs(res.signatures.map(s => ({
        id: s.id,
        ref: s.ref,
        doc: s.title || s.documentKind || '—',
        who: s.signerName || s.signerEmail,
        dossier: s.relatedRef || '—',
        status: s.status,
        at: s.signedAt ? 'signé ' + new Date(s.signedAt).toLocaleString('fr-FR') : s.createdAt ? 'créé ' + new Date(s.createdAt).toLocaleString('fr-FR') : '—',
        token: s.token,
        proofHash: s.proofHash,
      })));
    } else {
      setLiveSigs([]); // erreur backend → empty state, pas de fixtures
    }
  };

  const handleResend = async (s) => {
    if (!s.id) return;
    setActionState(p => ({ ...p, [s.id]: 'resending' }));
    try {
      const r = await fetch(`${API}/api/signatures/${s.id}/resend`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({}) }).then(r => r.json());
      if (r.ok && r.signUrl) {
        if (window.confirm(`Nouveau lien généré :\n${r.signUrl}\n\nCopier dans le presse-papier ?`)) {
          navigator.clipboard?.writeText(r.signUrl).catch(() => {});
        }
        await refresh();
      } else {
        alert(r.error || 'Erreur renvoi');
      }
    } finally {
      setActionState(p => ({ ...p, [s.id]: null }));
    }
  };

  const handleRevoke = async (s) => {
    if (!s.id) return;
    if (!window.confirm(`Révoquer définitivement la signature ${s.ref} ?\nCette action est irréversible, même si la signature a déjà été apposée.`)) return;
    setActionState(p => ({ ...p, [s.id]: 'revoking' }));
    try {
      const r = await fetch(`${API}/api/signatures/${s.id}/revoke`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({}) }).then(r => r.json());
      if (r.ok) {
        await refresh();
      } else {
        alert(r.error || 'Erreur révocation');
      }
    } finally {
      setActionState(p => ({ ...p, [s.id]: null }));
    }
  };

  // Édition signataire (avant signature)
  const handleEdit = async (s) => {
    if (!s.id) return;
    const newName = window.prompt(`Nouveau nom du signataire pour ${s.ref} ?`, s.who || '');
    if (newName === null) return; // Annulé
    const newEmail = window.prompt(`Nouvel email du signataire ?`, s.who && s.who.includes('@') ? s.who : '');
    if (newEmail === null) return;
    setActionState(p => ({ ...p, [s.id]: 'editing' }));
    try {
      const body = {};
      if (newName.trim()) body.signerName = newName.trim();
      if (newEmail.trim()) body.signerEmail = newEmail.trim();
      const r = await fetch(`${API}/api/signatures/${s.id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }).then(r => r.json());
      if (r.ok) {
        await refresh();
      } else {
        alert(r.error || 'Erreur édition');
      }
    } finally {
      setActionState(p => ({ ...p, [s.id]: null }));
    }
  };

  // Re-créer (duplique une signature expirée/annulée/révoquée en une nouvelle)
  const handleDuplicate = async (s) => {
    if (!s.id) return;
    if (!window.confirm(`Re-créer une nouvelle demande de signature à partir de ${s.ref} ?\n\nLe signataire et le document seront repris, un nouveau lien sera généré.`)) return;
    setActionState(p => ({ ...p, [s.id]: 'duplicating' }));
    try {
      const r = await fetch(`${API}/api/signatures/${s.id}/duplicate`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({}) }).then(r => r.json());
      if (r.ok && r.signUrl) {
        if (window.confirm(`✓ Nouvelle signature créée (${r.signature?.ref || ''}).\n\nLien :\n${r.signUrl}\n\nCopier dans le presse-papier ?`)) {
          navigator.clipboard?.writeText(r.signUrl).catch(() => {});
        }
        await refresh();
      } else {
        alert(r.error || 'Erreur duplication');
      }
    } finally {
      setActionState(p => ({ ...p, [s.id]: null }));
    }
  };

  useEffect(() => { refresh(); }, []);
  const sigs = liveSigs || [];
  const isLoading = liveSigs === null;
  const statusMeta = {
    signed:    { tone: 'signal', label: 'Signé' },
    opened:    { tone: 'amber',  label: 'Consulté' },
    sent:      { tone: 'muted',  label: 'Envoyé' },
    created:   { tone: 'muted',  label: 'Créé' },
    cancelled: { tone: 'rouge',  label: 'Annulé' },
    expired:   { tone: 'rouge',  label: 'Expiré' },
    revoked:   { tone: 'rouge',  label: 'Révoqué' },
    viewed:    { tone: 'amber',  label: 'Consulté' },
    pending:   { tone: 'muted',  label: 'En attente' },
  };
  return (
    <div style={{ padding: '16px 24px 80px' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 16 }}>
        <h1 style={{ fontSize: 20, fontWeight: 600, letterSpacing: '-0.02em', margin: 0 }}>Signatures natives</h1>
        <Badge tone="signal"><Icon.shield /> eIDAS simple · horodatage interne · hash chaîné</Badge>
        <span style={{ flex: 1 }} />
        <Btn variant="outline" size="sm">Gabarits</Btn>
        <Btn variant="signal" size="sm" icon={<Icon.plus />}>Demander signature</Btn>
      </div>

      {/* KPI band */}
      {(() => {
        const total = sigs.length;
        const signed = sigs.filter(s => s.status === 'signed').length;
        const pending = sigs.filter(s => ['created', 'sent', 'opened', 'pending'].includes(s.status)).length;
        const rate = total > 0 ? Math.round(signed / total * 1000) / 10 : 0;
        return (
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 0, border: '1px solid var(--line)', borderRadius: 8, background: 'var(--paper-2)', overflow: 'hidden', marginBottom: 16 }}>
            <MiniKpi label="En attente" value={String(pending)} sub={liveSigs ? 'live backend' : 'mock'} accent="var(--amber)" />
            <MiniKpi label="Signées" value={String(signed)} sub={liveSigs ? 'ledger chaîné' : 'mock'} accent="var(--signal)" divider />
            <MiniKpi label="Taux de signature" value={rate + ' %'} sub="sur l'échantillon" accent="var(--signal-deep)" divider />
            <MiniKpi label="Preuves archivées" value={String(signed)} sub={liveSigs ? 'hash SHA-256' : 'mock'} accent="var(--ink)" divider />
          </div>
        );
      })()}

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 340px', gap: 16 }}>
        <div style={{ border: '1px solid var(--line)', borderRadius: 8, background: 'var(--paper-2)', overflow: 'hidden' }}>
          <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12 }}>
            <thead>
              <tr style={{ borderBottom: '1px solid var(--line)' }}>
                {['Référence', 'Document', 'Signataire', 'Dossier', 'Statut', 'Activité', ''].map(h => (
                  <th key={h} style={{ padding: '10px 12px', textAlign: 'left', fontSize: 10, color: 'var(--ink-4)', textTransform: 'uppercase', letterSpacing: 0.6, fontWeight: 600 }}>{h}</th>
                ))}
              </tr>
            </thead>
            <tbody>
              {isLoading && (
                <tr><td colSpan={7} style={{ padding: 40, textAlign: 'center', color: 'var(--ink-4)', fontSize: 12 }}>⏳ Chargement…</td></tr>
              )}
              {!isLoading && sigs.length === 0 && (
                <tr><td colSpan={7} style={{ padding: '60px 20px', textAlign: 'center', color: 'var(--ink-4)' }}>
                  <div style={{ fontSize: 36, marginBottom: 12 }}>✍️</div>
                  <div style={{ fontSize: 14, fontWeight: 600, color: 'var(--ink-2)', marginBottom: 6 }}>Aucune signature</div>
                  <div style={{ fontSize: 12, maxWidth: 380, margin: '0 auto' }}>Cliquez sur <strong>« Demander signature »</strong> ou générez une signature depuis un rapport de visite ou un dossier CEE.</div>
                </td></tr>
              )}
              {!isLoading && sigs.map((s, i) => {
                const busy = actionState[s.id];
                const canResend    = s.id && !['signed','cancelled','expired','revoked'].includes(s.status);
                const canRevoke    = s.id && !['cancelled','revoked'].includes(s.status);
                const canEdit      = s.id && !['signed','revoked'].includes(s.status);
                const canDuplicate = s.id && ['cancelled','expired','revoked'].includes(s.status);
                const sm = statusMeta[s.status] || { tone: 'muted', label: s.status };
                return (
                  <tr key={s.ref} style={{ borderBottom: '1px solid var(--hairline)' }}>
                    <td style={{ padding: '10px 12px' }}><span className="mono" style={{ fontSize: 10 }}>{s.ref}</span></td>
                    <td style={{ padding: '10px 12px' }} className="mono">{s.doc}</td>
                    <td style={{ padding: '10px 12px', fontWeight: 500 }}>{s.who}</td>
                    <td style={{ padding: '10px 12px' }} className="mono">{s.dossier}</td>
                    <td style={{ padding: '10px 12px' }}>
                      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
                        <Dot tone={sm.tone} pulse={s.status === 'pending'} size={6} />
                        <span style={{ fontSize: 11 }}>{sm.label}</span>
                      </span>
                    </td>
                    <td style={{ padding: '10px 12px', fontSize: 11, color: 'var(--ink-3)' }}>{s.at}</td>
                    <td style={{ padding: '8px 12px' }}>
                      <div style={{ display: 'flex', gap: 4, flexWrap: 'nowrap' }}>
                        {s.status === 'signed' && (
                          <Btn size="sm" variant="ghost">Preuve</Btn>
                        )}
                        {!s.id && s.status !== 'signed' && (
                          <Btn size="sm" variant="outline" onClick={onOpenSigner}>Prévisualiser</Btn>
                        )}
                        {canEdit && (
                          <Btn
                            size="sm" variant="outline"
                            disabled={!!busy}
                            onClick={() => handleEdit(s)}
                            title="Éditer le signataire (nom / email)"
                          >{busy === 'editing' ? '…' : '✏️ Éditer'}</Btn>
                        )}
                        {canResend && (
                          <Btn
                            size="sm" variant="outline"
                            disabled={!!busy}
                            onClick={() => handleResend(s)}
                            title="Générer un nouveau lien de signature"
                          >{busy === 'resending' ? '…' : '🔁 Renvoyer'}</Btn>
                        )}
                        {canDuplicate && (
                          <Btn
                            size="sm" variant="outline"
                            disabled={!!busy}
                            onClick={() => handleDuplicate(s)}
                            title="Re-créer une nouvelle demande à partir de celle-ci"
                          >{busy === 'duplicating' ? '…' : '♻️ Re-créer'}</Btn>
                        )}
                        {canRevoke && (
                          <Btn
                            size="sm"
                            disabled={!!busy}
                            onClick={() => handleRevoke(s)}
                            title="Révoquer définitivement"
                            style={{ color: 'var(--rouge)', background: 'var(--rouge-tint)', border: '1px solid var(--rouge)', borderRadius: 4, padding: '3px 8px', fontSize: 11, cursor: 'pointer' }}
                          >{busy === 'revoking' ? '…' : '🚫 Révoquer'}</Btn>
                        )}
                      </div>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>

        {/* Proof card — affichée seulement si au moins 1 signature signée */}
        {(() => {
          const lastSigned = sigs.find(s => s.status === 'signed');
          if (!lastSigned) {
            return (
              <div style={{ border: '1px dashed var(--line-2)', borderRadius: 8, background: 'var(--paper-2)', padding: 18, textAlign: 'center' }}>
                <div style={{ fontSize: 22, marginBottom: 8 }}>🔒</div>
                <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--ink-3)', marginBottom: 4 }}>Aucune preuve disponible</div>
                <div style={{ fontSize: 11, color: 'var(--ink-4)' }}>Une fois une signature finalisée, sa preuve légale (hash chaîné, IP, OTP, horodatage) apparaîtra ici.</div>
              </div>
            );
          }
          return (
            <div style={{ border: '1px solid var(--line)', borderRadius: 8, background: 'var(--paper-2)', padding: 16 }}>
              <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 4 }}>Preuve légale · {lastSigned.ref}</div>
              <div style={{ fontSize: 11, color: 'var(--ink-4)', marginBottom: 14 }}>téléchargeable en PDF + JSON audit</div>
              <div style={{ padding: 12, background: 'var(--paper)', border: '1px solid var(--line)', borderRadius: 5, fontFamily: 'var(--font-mono)', fontSize: 10, lineHeight: 1.7, color: 'var(--ink-2)' }}>
                <div><span style={{ color: 'var(--ink-4)' }}>signer:</span> {lastSigned.who || '—'}</div>
                <div><span style={{ color: 'var(--ink-4)' }}>document:</span> {lastSigned.doc || '—'}</div>
                <div><span style={{ color: 'var(--ink-4)' }}>activité:</span> {lastSigned.at || '—'}</div>
                {lastSigned.proofHash && (
                  <div><span style={{ color: 'var(--ink-4)' }}>hash:</span> <span style={{ color: 'var(--signal-deep)' }}>{(lastSigned.proofHash || '').slice(0, 12)}…</span></div>
                )}
                {lastSigned.token && (
                  <div><span style={{ color: 'var(--ink-4)' }}>token:</span> {(lastSigned.token || '').slice(0, 12)}…</div>
                )}
              </div>
              <Btn variant="outline" size="sm" style={{ width: '100%', marginTop: 12, justifyContent: 'center' }}
                onClick={() => window.open(`${API}/api/signatures/${lastSigned.id}/proof.pdf`, '_blank')}>
                Télécharger preuve PDF
              </Btn>
            </div>
          );
        })()}
      </div>
    </div>
  );
}

// ───────────── Mobile signer screen ─────────────
function SignerScreen({ onClose }) {
  const [step, setStep] = useState('review'); // review → sign → done
  const [signature, setSignature] = useState(null);
  const canvasRef = useRef(null);
  const drawing = useRef(false);

  const startDraw = (e) => {
    drawing.current = true;
    const r = canvasRef.current.getBoundingClientRect();
    const ctx = canvasRef.current.getContext('2d');
    ctx.beginPath();
    ctx.moveTo(e.clientX - r.left, e.clientY - r.top);
  };
  const moveDraw = (e) => {
    if (!drawing.current) return;
    const r = canvasRef.current.getBoundingClientRect();
    const ctx = canvasRef.current.getContext('2d');
    ctx.strokeStyle = '#0E1010';
    ctx.lineWidth = 2;
    ctx.lineCap = 'round';
    ctx.lineTo(e.clientX - r.left, e.clientY - r.top);
    ctx.stroke();
    setSignature(true);
  };
  const endDraw = () => { drawing.current = false; };
  const clear = () => {
    const ctx = canvasRef.current.getContext('2d');
    ctx.clearRect(0, 0, canvasRef.current.width, canvasRef.current.height);
    setSignature(null);
  };

  return (
    <div style={{ position: 'fixed', inset: 0, background: 'rgba(14,16,16,0.6)', display: 'grid', placeItems: 'center', zIndex: 100, padding: 20 }}
         onClick={onClose}>
      <div onClick={e => e.stopPropagation()} style={{
        width: 380, maxWidth: '100%', background: 'var(--paper)',
        borderRadius: 20, boxShadow: 'var(--shadow-3)', overflow: 'hidden',
        border: '1px solid var(--line-2)',
        maxHeight: '92vh', display: 'flex', flexDirection: 'column',
      }}>
        {/* mobile status bar mock */}
        <div style={{ padding: '8px 16px', display: 'flex', justifyContent: 'space-between', fontSize: 11, fontWeight: 600, background: 'var(--paper)' }}>
          <span className="mono">15:47</span>
          <span style={{ display: 'flex', gap: 5, alignItems: 'center' }}>
            <span style={{ width: 14, height: 8, border: '1px solid var(--ink)', borderRadius: 2, position: 'relative' }}>
              <span style={{ position: 'absolute', inset: 1, background: 'var(--signal-deep)', width: '70%' }} />
            </span>
          </span>
        </div>

        {/* Brand header */}
        <div style={{ padding: '14px 20px 10px', borderBottom: '1px solid var(--hairline)', display: 'flex', alignItems: 'center', gap: 10 }}>
          <div style={{ width: 24, height: 24, borderRadius: 4, background: 'var(--ink)', color: 'var(--signal)', display: 'grid', placeItems: 'center', fontSize: 11, fontWeight: 700 }} className="mono">Æ</div>
          <div style={{ lineHeight: 1.1 }}>
            <div style={{ fontSize: 12, fontWeight: 600 }}>Audits Énergies</div>
            <div style={{ fontSize: 10, color: 'var(--ink-4)' }}>signature sécurisée · aucun compte requis</div>
          </div>
          <span style={{ flex: 1 }} />
          <Badge tone="signal" icon={<Icon.lock />}>TLS</Badge>
        </div>

        {step === 'review' && (
          <>
            <div style={{ padding: '20px 20px 14px', overflowY: 'auto' }}>
              <div style={{ fontSize: 11, color: 'var(--ink-4)', textTransform: 'uppercase', letterSpacing: 0.6, fontWeight: 500 }}>Document à signer</div>
              <div style={{ fontSize: 16, fontWeight: 600, marginTop: 2 }}>Attestation sur l'Honneur</div>
              <div style={{ fontSize: 12, color: 'var(--ink-3)', marginTop: 2 }}>dossier <span className="mono">DOS-2026-024</span> · Résidence Mirabeau</div>

              {/* Doc preview */}
              <div style={{ marginTop: 14, padding: 16, background: '#fff', border: '1px solid var(--line-2)', borderRadius: 6, fontSize: 10.5, lineHeight: 1.55, color: '#2B2D2E', maxHeight: 200, overflow: 'hidden', position: 'relative' }}>
                <div style={{ fontWeight: 700, fontSize: 12, marginBottom: 6 }}>ATTESTATION SUR L'HONNEUR</div>
                <div>Je soussigné <strong>Jean Mirabeau</strong>, agissant en qualité de syndic bénévole de la Résidence Mirabeau (SIRET 891 334 108 00014), atteste sur l'honneur :</div>
                <div style={{ marginTop: 8 }}>— que les travaux d'installation d'une pompe à chaleur air/eau (BAR-TH-104) ont bien été réalisés à l'adresse du chantier ;</div>
                <div>— que l'opération a été induite par le dispositif des Certificats d'Économies d'Énergie ;</div>
                <div>— que je n'ai pas sollicité d'autre valorisation CEE pour cette opération…</div>
                <div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 40, background: 'linear-gradient(transparent, #fff)' }} />
              </div>

              <div style={{ marginTop: 12, display: 'flex', alignItems: 'center', gap: 8, padding: '8px 10px', background: 'var(--signal-tint)', border: '1px solid var(--signal-soft)', borderRadius: 5 }}>
                <Icon.check style={{ color: 'var(--signal-deep)' }} />
                <span style={{ fontSize: 11, color: 'var(--signal-deep)', fontWeight: 500 }}>Code OTP envoyé · 06 ** ** 42 79</span>
              </div>

              <input placeholder="● ● ● ● ● ●" className="mono" style={{
                width: '100%', marginTop: 10, padding: '12px 14px',
                border: '1px solid var(--line-2)', borderRadius: 6,
                background: 'var(--paper)', fontSize: 16, textAlign: 'center', letterSpacing: '0.5em',
                fontFamily: 'var(--font-mono)', color: 'var(--ink)',
              }} defaultValue="✓ 842 179" />
            </div>
            <div style={{ padding: '14px 20px', borderTop: '1px solid var(--hairline)', display: 'flex', gap: 8 }}>
              <Btn variant="ghost" onClick={onClose} style={{ flex: 1, justifyContent: 'center' }}>Annuler</Btn>
              <Btn variant="signal" onClick={() => setStep('sign')} style={{ flex: 2, justifyContent: 'center' }} iconRight={<Icon.arrow />}>Signer</Btn>
            </div>
          </>
        )}

        {step === 'sign' && (
          <>
            <div style={{ padding: '20px 20px 14px' }}>
              <div style={{ fontSize: 11, color: 'var(--ink-4)', textTransform: 'uppercase', letterSpacing: 0.6, fontWeight: 500 }}>Dessinez votre signature</div>
              <div style={{ fontSize: 12, color: 'var(--ink-3)', marginTop: 2, marginBottom: 12 }}>avec le doigt ou le stylet</div>
              <div style={{ position: 'relative', background: '#fff', border: '1.5px dashed var(--line-2)', borderRadius: 8, height: 180 }}>
                <canvas
                  ref={canvasRef} width={600} height={360}
                  onPointerDown={startDraw} onPointerMove={moveDraw} onPointerUp={endDraw} onPointerLeave={endDraw}
                  style={{ width: '100%', height: '100%', display: 'block', touchAction: 'none', borderRadius: 8 }}
                />
                <div style={{ position: 'absolute', bottom: 8, left: 8, right: 8, display: 'flex', alignItems: 'center', gap: 6 }}>
                  <div style={{ flex: 1, height: 1, background: 'var(--line-2)' }} />
                  <span className="mono" style={{ fontSize: 9, color: 'var(--ink-4)' }}>× signature</span>
                </div>
              </div>
              <div style={{ display: 'flex', gap: 8, marginTop: 10, fontSize: 11, color: 'var(--ink-4)' }}>
                <button onClick={clear} style={{ color: 'var(--ink-2)', fontWeight: 500 }}>Effacer</button>
                <span style={{ flex: 1 }} />
                <span>horodatage serveur · scellement immédiat</span>
              </div>
            </div>
            <div style={{ padding: '14px 20px', borderTop: '1px solid var(--hairline)', display: 'flex', gap: 8 }}>
              <Btn variant="ghost" onClick={() => setStep('review')} style={{ flex: 1, justifyContent: 'center' }}>Retour</Btn>
              <Btn variant="signal" onClick={() => setStep('done')} disabled={!signature} style={{ flex: 2, justifyContent: 'center' }} iconRight={<Icon.check />}>Valider la signature</Btn>
            </div>
          </>
        )}

        {step === 'done' && (
          <div style={{ padding: '40px 20px', textAlign: 'center', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 14 }}>
            <div style={{ width: 56, height: 56, borderRadius: '50%', background: 'var(--signal-tint)', border: '1.5px solid var(--signal)', display: 'grid', placeItems: 'center' }}>
              <svg width="26" height="26" viewBox="0 0 26 26" fill="none" stroke="var(--signal-deep)" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" style={{ animation: 'fade-up 400ms both' }}>
                <path d="M5 13l5 5 11-11" style={{ strokeDasharray: 30, strokeDashoffset: 0, animation: 'draw-line 500ms 100ms both' }} />
              </svg>
            </div>
            <div>
              <div style={{ fontSize: 16, fontWeight: 600 }}>Signature validée</div>
              <div style={{ fontSize: 12, color: 'var(--ink-3)', marginTop: 4 }}>scellée · horodatée · chaînée #1284</div>
            </div>
            <div style={{ padding: 12, background: 'var(--paper-2)', border: '1px solid var(--line)', borderRadius: 6, fontFamily: 'var(--font-mono)', fontSize: 10, width: '100%', textAlign: 'left' }}>
              <div>sha256: <span style={{ color: 'var(--signal-deep)' }}>c8f4…e02a</span></div>
              <div>ts : 2026-04-20T15:47:02Z</div>
            </div>
            <Btn variant="outline" size="sm" onClick={onClose}>Télécharger preuve</Btn>
          </div>
        )}
      </div>
    </div>
  );
}

// ───────────── Command palette ─────────────
function CommandPalette({ open, onClose, onNav, onOpenDossier }) {
  const [q, setQ] = useState('');
  const [modal, setModal] = useState(null); // 'orgs' | 'products' | 'devis' | 'comm'
  useEffect(() => { if (open) setQ(''); }, [open]);
  const openModal = (k) => { setModal(k); onClose(); };

  const dossiers = DOSSIERS.filter(d => (d.ref + d.client + d.fost).toLowerCase().includes(q.toLowerCase())).slice(0, 4);
  const fost = FOST_CATALOG.filter(f => (f.code + f.name).toLowerCase().includes(q.toLowerCase())).slice(0, 3);

  if (!open && !modal) return null;
  return (
    <>
    {modal === 'orgs' && window.OrganizationsModal && <window.OrganizationsModal onClose={() => setModal(null)} />}
    {modal === 'products' && window.ProductsModal && <window.ProductsModal onClose={() => setModal(null)} />}
    {modal === 'devis' && window.DevisDrawer && <window.DevisDrawer onClose={() => setModal(null)} />}
    {modal === 'comm' && window.CommunicationDrawer && <window.CommunicationDrawer onClose={() => setModal(null)} />}
    {!open ? null : (
    <div onClick={onClose} style={{ position: 'fixed', inset: 0, background: 'rgba(14,16,16,0.5)', backdropFilter: 'blur(4px)', zIndex: 90, display: 'grid', placeItems: 'start center', paddingTop: '14vh' }}>
      <div onClick={e => e.stopPropagation()} style={{
        width: 640, maxWidth: '92vw',
        background: 'var(--paper)',
        border: '1px solid var(--line-2)', borderRadius: 10,
        boxShadow: 'var(--shadow-3)', overflow: 'hidden',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '14px 16px', borderBottom: '1px solid var(--line)' }}>
          <Icon.search style={{ color: 'var(--ink-4)' }} />
          <input autoFocus value={q} onChange={e => setQ(e.target.value)}
            placeholder="Rechercher ou exécuter… (ex: « score bas », « DOS-2026-024 »)"
            style={{ flex: 1, border: 'none', background: 'transparent', fontSize: 15, color: 'var(--ink)', outline: 'none', fontFamily: 'inherit' }} />
          <span className="mono" style={{ fontSize: 10, padding: '2px 6px', border: '1px solid var(--line-2)', borderRadius: 3, color: 'var(--ink-4)' }}>esc</span>
        </div>
        <div style={{ maxHeight: '55vh', overflowY: 'auto' }}>
          {/* Copilot suggestion */}
          {q.length > 2 && (
            <Section title="Co-pilote">
              <PaletteRow icon={<Icon.copilot style={{ color: 'var(--plasma)' }} />} label={`Demander à Claude : « ${q} »`} sub="contexte dossier courant + vault Obsidian" kbd="↵" />
            </Section>
          )}
          {dossiers.length > 0 && (
            <Section title="Dossiers">
              {dossiers.map(d => (
                <PaletteRow key={d.ref}
                  icon={<Sigil seed={d.ref} size={16} />}
                  label={<><span className="mono">{d.ref}</span> <span style={{ color: 'var(--ink-4)', marginLeft: 6 }}>·</span> <span style={{ marginLeft: 6 }}>{d.client}</span></>}
                  sub={`${d.fost} · ${fmtMWh(d.cumac)} · score ${d.risk}`}
                  onClick={() => { onOpenDossier(d); onClose(); }} />
              ))}
            </Section>
          )}
          {fost.length > 0 && (
            <Section title="Fiches FOST">
              {fost.map(f => (
                <PaletteRow key={f.code}
                  icon={<Icon.book style={{ color: 'var(--ink-4)' }} />}
                  label={<span><span className="mono">{f.code}</span> <span style={{ marginLeft: 6 }}>{f.name}</span></span>}
                  sub={`${f.count} dossiers actifs`}
                  onClick={() => { onNav('fost'); onClose(); }} />
              ))}
            </Section>
          )}
          <Section title="Modules (CRM · Produits · Devis · Comm)">
            <PaletteRow icon={<Icon.people style={{ color: 'var(--plasma)' }} />} label="Clients Odoo + Organisations Discovery" sub="partners Odoo synchronisés · sync à la demande" onClick={() => openModal('orgs')} />
            <PaletteRow icon={<Icon.book style={{ color: 'var(--signal-deep)' }} />} label="Catalogue produits" sub="EPREL + Odoo + seeds · recherche live" onClick={() => openModal('products')} />
            <PaletteRow icon={<Icon.doc style={{ color: 'var(--amber)' }} />} label="Devis Odoo" sub="liste et création" onClick={() => openModal('devis')} />
            <PaletteRow icon={<Icon.mail style={{ color: 'var(--plasma)' }} />} label="Communication IMAP" sub="inbox emails + pièces jointes" onClick={() => openModal('comm')} />
          </Section>
          <Section title="Actions">
            <PaletteRow icon={<Icon.plus style={{ color: 'var(--ink-4)' }} />} label="Créer un nouveau dossier" kbd="⌘N" onClick={() => { onNav('dossiers'); onClose(); }} />
            <PaletteRow icon={<Icon.sign style={{ color: 'var(--ink-4)' }} />} label="Demander une signature" kbd="⌘S" onClick={() => { onNav('signatures'); onClose(); }} />
            <PaletteRow icon={<Icon.refresh style={{ color: 'var(--ink-4)' }} />} label="Synchroniser Odoo maintenant" onClick={async () => { onClose(); if (window.triggerOdooSync) await window.triggerOdooSync(); if (window.AE_API?.hydrate) window.AE_API.hydrate(); }} />
          </Section>
          <Section title="Aller à">
            {[['dashboard', 'Cockpit', Icon.home], ['dossiers', 'Dossiers CEE', Icon.folder], ['fost', 'Fiches FOST', Icon.book], ['signatures', 'Signatures', Icon.sign], ['ledger', 'Ledger cumac', Icon.lock]].map(([k, l, I]) => (
              <PaletteRow key={k} icon={<I style={{ color: 'var(--ink-4)' }} />} label={l} onClick={() => { onNav(k); onClose(); }} />
            ))}
          </Section>
        </div>
        <div style={{ padding: '8px 14px', borderTop: '1px solid var(--line)', display: 'flex', alignItems: 'center', gap: 16, fontSize: 10, color: 'var(--ink-4)' }}>
          <span><span className="mono" style={{ padding: '0 4px', border: '1px solid var(--line-2)', borderRadius: 2 }}>↑↓</span> naviguer</span>
          <span><span className="mono" style={{ padding: '0 4px', border: '1px solid var(--line-2)', borderRadius: 2 }}>↵</span> sélectionner</span>
          <span><span className="mono" style={{ padding: '0 4px', border: '1px solid var(--line-2)', borderRadius: 2 }}>⌘↵</span> demander Claude</span>
          <span style={{ flex: 1 }} />
          <Dot tone="plasma" size={5} /> <span>co-pilote · actif</span>
        </div>
      </div>
    </div>
    )}
    </>
  );
}
function Section({ title, children }) {
  return (
    <div>
      <div style={{ padding: '10px 16px 4px', fontSize: 10, color: 'var(--ink-4)', textTransform: 'uppercase', letterSpacing: 0.8, fontWeight: 600 }}>{title}</div>
      {children}
    </div>
  );
}
function PaletteRow({ icon, label, sub, kbd, onClick }) {
  return (
    <button onClick={onClick} style={{
      width: '100%', display: 'grid', gridTemplateColumns: '24px 1fr auto', gap: 12, alignItems: 'center',
      padding: '9px 16px', textAlign: 'left',
    }}
      onMouseEnter={e => e.currentTarget.style.background = 'var(--paper-2)'}
      onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
    >
      <span style={{ display: 'grid', placeItems: 'center' }}>{icon}</span>
      <div>
        <div style={{ fontSize: 13, color: 'var(--ink)' }}>{label}</div>
        {sub && <div style={{ fontSize: 11, color: 'var(--ink-4)' }}>{sub}</div>}
      </div>
      {kbd && <span className="mono" style={{ fontSize: 10, padding: '1px 5px', border: '1px solid var(--line-2)', borderRadius: 3, color: 'var(--ink-4)' }}>{kbd}</span>}
    </button>
  );
}

// ───────────── Copilot sidebar drawer ─────────────
function CopilotDrawer({ open, onClose }) {
  const [messages, setMessages] = useState([
    { role: 'ai', text: 'Bonjour Nils. Ce matin sur votre périmètre :' },
    { role: 'ai', cards: [
      { k: 'Alerte', tone: 'rouge', text: '3 dossiers score < 60 — rejet PNCEE probable.' },
      { k: 'Opportunité', tone: 'signal', text: 'Bonification précarité prolongée sur BAR-TH-104 : 18 dossiers requalifiables · +4 200 € estimés.' },
      { k: 'Signatures', tone: 'amber', text: '4 signatures > 48 h — relances recommandées.' },
    ]},
    { role: 'ai', text: 'Que souhaitez-vous faire ?' },
  ]);
  const [input, setInput] = useState('');
  const [loading, setLoading] = useState(false);
  const send = async () => {
    if (!input.trim() || loading) return;
    const userText = input;
    setInput('');
    setMessages(m => [...m, { role: 'user', text: userText }]);
    setLoading(true);
    try {
      const history = [...messages, { role: 'user', text: userText }]
        .filter(m => m.text && (m.role === 'user' || m.role === 'ai'))
        .map(m => ({ role: m.role === 'ai' ? 'assistant' : 'user', content: m.text }));
      const res = await window.AE_API?.copilotChat(history, {});
      const reply = res?.ok
        ? res.reply
        : res?.error
        ? `⚠️ Copilote indisponible : ${res.error}. Configure ANTHROPIC_API_KEY dans le .env serveur.`
        : '⚠️ Aucune réponse du serveur copilote.';
      setMessages(m => [...m, { role: 'ai', text: reply }]);
    } catch (e) {
      setMessages(m => [...m, { role: 'ai', text: `⚠️ Erreur réseau : ${e.message}` }]);
    } finally {
      setLoading(false);
    }
  };
  return (
    <div style={{
      position: 'fixed', top: 0, right: 0, height: '100vh',
      width: open ? 420 : 0, zIndex: 50,
      transition: 'width 260ms cubic-bezier(.2,.8,.2,1)',
      overflow: 'hidden',
    }}>
      <div style={{
        width: 420, height: '100%',
        background: 'var(--paper)',
        borderLeft: '1px solid var(--line-2)',
        display: 'flex', flexDirection: 'column',
        boxShadow: 'var(--shadow-3)',
      }}>
        <div style={{ padding: '14px 16px', borderBottom: '1px solid var(--line)', display: 'flex', alignItems: 'center', gap: 10 }}>
          <div style={{ position: 'relative', width: 10, height: 10 }}>
            <span style={{ position: 'absolute', inset: 0, borderRadius: '50%', background: 'var(--plasma)', animation: 'breathe 2.4s infinite' }} />
          </div>
          <div style={{ lineHeight: 1.1 }}>
            <div style={{ fontSize: 13, fontWeight: 600 }}>Co-pilote CEE</div>
            <div className="mono" style={{ fontSize: 10, color: 'var(--ink-4)' }}>claude-sonnet-4.5 · contexte chargé</div>
          </div>
          <span style={{ flex: 1 }} />
          <button onClick={onClose} style={{ padding: 4, color: 'var(--ink-4)' }}><Icon.cross /></button>
        </div>
        <div style={{ flex: 1, overflowY: 'auto', padding: '16px', display: 'flex', flexDirection: 'column', gap: 12 }}>
          {messages.map((m, i) => m.role === 'ai' ? (
            m.cards ? (
              <div key={i} style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                {m.cards.map((c, j) => (
                  <div key={j} style={{ padding: 10, background: 'var(--paper-2)', border: '1px solid var(--line)', borderRadius: 6, display: 'flex', gap: 8, alignItems: 'flex-start' }}>
                    <Dot tone={c.tone} size={6} />
                    <div>
                      <div style={{ fontSize: 11, fontWeight: 600, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: 0.6 }}>{c.k}</div>
                      <div style={{ fontSize: 12, color: 'var(--ink-2)', marginTop: 2, lineHeight: 1.45 }}>{c.text}</div>
                    </div>
                  </div>
                ))}
              </div>
            ) : (
              <div key={i} className="fade-up" style={{ fontSize: 13, color: 'var(--ink-2)', lineHeight: 1.55, maxWidth: '90%' }}>{m.text}</div>
            )
          ) : (
            <div key={i} style={{ alignSelf: 'flex-end', padding: '8px 12px', background: 'var(--ink)', color: 'var(--paper)', borderRadius: '12px 12px 2px 12px', fontSize: 13, maxWidth: '80%' }}>{m.text}</div>
          ))}
        </div>
        <div style={{ borderTop: '1px solid var(--line)', padding: 14, display: 'flex', flexDirection: 'column', gap: 10 }}>
          <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
            {['Requalifier les 18 dossiers', 'Relancer les signatures', 'Audit inversé batch'].map(s => (
              <button key={s} onClick={() => setInput(s)} style={{ fontSize: 11, padding: '4px 8px', border: '1px solid var(--line)', borderRadius: 999, color: 'var(--ink-3)' }}>{s}</button>
            ))}
          </div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '8px 12px', border: '1px solid var(--line-2)', borderRadius: 6, background: 'var(--paper-2)' }}>
            <input value={input} onChange={e => setInput(e.target.value)} onKeyDown={e => e.key === 'Enter' && send()}
              placeholder={loading ? 'Claude réfléchit…' : 'Demander au co-pilote…'}
              disabled={loading}
              style={{ flex: 1, border: 'none', background: 'transparent', fontSize: 13, outline: 'none', color: 'var(--ink)', fontFamily: 'inherit', opacity: loading ? 0.5 : 1 }} />
            <button onClick={send} disabled={loading} style={{ color: loading ? 'var(--ink-5)' : 'var(--ink-3)' }}><Icon.arrow /></button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ─── Ledger cumac — page dédiée, branchée sur /api/ledger ─────────────
function LedgerPage() {
  const [data, setData] = useState({ loading: true, entries: [], total: 0, head: null, verify: null });
  useEffect(() => {
    (async () => {
      const [entries, verify] = await Promise.all([
        window.AE_API?.ledgerEntries(),
        window.AE_API?.ledgerVerify(),
      ]);
      setData({
        loading: false,
        entries: entries?.entries || [],
        total: entries?.total || 0,
        head: entries?.head || 'genesis',
        verify,
      });
    })();
  }, []);
  const valid = data.verify?.valid;
  return (
    <div style={{ padding: '16px 24px 80px', maxWidth: 1400, margin: '0 auto' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 16 }}>
        <h1 style={{ fontSize: 20, fontWeight: 600, letterSpacing: '-0.02em', margin: 0 }}>Ledger cumac</h1>
        <Badge tone="plasma"><Icon.lock /> SHA-256 · chaînage non-répudiable</Badge>
        <span style={{ flex: 1 }} />
        {data.verify && (
          <Badge tone={valid ? 'signal' : 'rouge'} icon={valid ? <Icon.check /> : <Icon.cross />}>
            {valid ? `Intégrité OK · ${data.verify.totalEntries} blocs` : `⚠ ${data.verify.brokenLinks?.length || 0} liens rompus`}
          </Badge>
        )}
      </div>

      {/* KPI band */}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 0, border: '1px solid var(--line)', borderRadius: 8, background: 'var(--paper-2)', overflow: 'hidden', marginBottom: 16 }}>
        <MiniKpi label="Blocs scellés" value={String(data.total)} sub="depuis genesis" accent="var(--signal)" />
        <MiniKpi label="Tête de chaîne" value={data.head ? data.head.slice(0, 10) + '…' : '—'} sub={data.head === 'genesis' ? 'ledger vide' : 'dernier hash'} accent="var(--plasma)" divider />
        <MiniKpi label="Preuve d'intégrité" value={valid ? '✓ OK' : data.verify ? '⚠' : '…'} sub="vérification chaîne" accent={valid ? 'var(--signal-deep)' : 'var(--amber)'} divider />
      </div>

      {data.loading && <div style={{ padding: 40, textAlign: 'center', color: 'var(--ink-4)' }}>Chargement du ledger…</div>}
      {!data.loading && !data.total && (
        <div style={{ padding: 60, textAlign: 'center', background: 'var(--paper-2)', border: '1px dashed var(--line-2)', borderRadius: 10 }}>
          <div style={{ fontSize: 14, color: 'var(--ink-3)', marginBottom: 8 }}>Ledger vide</div>
          <div style={{ fontSize: 12, color: 'var(--ink-4)', lineHeight: 1.5 }}>
            Chaque signature électronique signée ajoute automatiquement un bloc chaîné au ledger.<br/>
            Signe un document via l'écran "Signatures natives" pour démarrer la chaîne.
          </div>
        </div>
      )}
      {!data.loading && data.total > 0 && (
        <div style={{ border: '1px solid var(--line)', borderRadius: 8, background: 'var(--paper-2)', overflow: 'hidden' }}>
          <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12 }}>
            <thead>
              <tr style={{ borderBottom: '1px solid var(--line)' }}>
                {['Bloc', 'Document', 'Signataire', 'Dossier', 'Hash preuve', 'Prev', 'Signé'].map(h => (
                  <th key={h} style={{ padding: '10px 12px', textAlign: 'left', fontSize: 10, color: 'var(--ink-4)', textTransform: 'uppercase', letterSpacing: 0.6, fontWeight: 600 }}>{h}</th>
                ))}
              </tr>
            </thead>
            <tbody>
              {data.entries.map((e) => (
                <tr key={e.proofHash} style={{ borderBottom: '1px solid var(--hairline)' }}>
                  <td style={{ padding: '10px 12px', fontWeight: 600 }} className="mono">#{String(e.blockNumber).padStart(4, '0')}</td>
                  <td style={{ padding: '10px 12px' }}>
                    <div style={{ fontWeight: 500 }}>{e.title}</div>
                    <div className="mono" style={{ fontSize: 10, color: 'var(--ink-4)' }}>{e.ref} · {e.documentKind}</div>
                  </td>
                  <td style={{ padding: '10px 12px' }}>{e.signer}</td>
                  <td style={{ padding: '10px 12px' }} className="mono">{e.relatedRef || '—'}</td>
                  <td style={{ padding: '10px 12px' }} className="mono" title={e.proofHash} style={{ fontSize: 10, color: 'var(--signal-deep)' }}>{(e.proofHash || '').slice(0, 14)}…</td>
                  <td style={{ padding: '10px 12px' }} className="mono" title={e.previousProofHash} style={{ fontSize: 10, color: 'var(--ink-4)' }}>{e.previousProofHash === 'genesis' ? 'genesis' : (e.previousProofHash || '').slice(0, 10) + '…'}</td>
                  <td style={{ padding: '10px 12px', fontSize: 11, color: 'var(--ink-3)' }}>{e.signedAt ? new Date(e.signedAt).toLocaleString('fr-FR') : '—'}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { FostPage, SignaturesPage, SignerScreen, CommandPalette, CopilotDrawer, LedgerPage });
