/* ───────────────────────────────────────────────────────────
   IbanArfDiagram.jsx — Schéma ARF dynamique du parcours « Attestation IBAN »
   Cadre séparé sous la scène, calqué sur ArfDiagram (Entrée en relation).
   Illustre les échanges de flux entre les parties prenantes, acte par acte :

     Acte 1 — ÉMISSION (OpenID4VCI)
       Banque Démo (Issuer) → Doxallia (intermédiaire d'émission) → ID Wallet (Holder)

     Acte 2 — RÉUTILISATION (OpenID4VP)
       ID Wallet (Holder) → Doxallia (vérificateur) → Téléo Mobile (Relying Party)

   Disposition fixe : Holder (gauche) · Doxallia (centre) · partenaire métier (droite).
   Le sens des flèches s'inverse selon l'acte (délivrance ⟵ / présentation ⟶).
   Réagit à l'entier `step` (0..13) piloté par IbanApp.
   ─────────────────────────────────────────────────────────── */

const { Ic: DIc, IIc: DIIc } = window;

const IDOX  = '#e8513a';   // corail Doxallia (intermédiaire)
const IRF   = '#222834';   // Bleu France (holder / wallet)
const IBANK = '#1657c8';   // bleu Banque Démo (émetteur)
const ITEL  = '#7a23c4';   // violet Téléo Mobile (relying party)
const ILINE = '#d8dee8';

// icône « relais / échange » pour le proxy (identique à ArfDiagram)
function IRelay({ s = 22, c = '#fff' }) {
  return (
    <svg viewBox="0 0 24 24" width={s} height={s} fill="none" stroke={c}
      strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <path d="M4 8.5h12l-3.2-3.2M16 8.5l-3.2 3.2" />
      <path d="M20 15.5H8l3.2-3.2M8 15.5l3.2 3.2" />
    </svg>
  );
}

/* ── résolution de l'étape ARF à partir de l'entier `step` ──
   on{holder,dox,biz}, L/R {dir,msg}, caption, tech, accent
   L = lien Holder(gauche)↔Doxallia(centre) ; dir>0 vers Doxallia, dir<0 vers Holder
   R = lien Doxallia(centre)↔partenaire(droite) ; dir>0 vers partenaire, dir<0 vers Doxallia */
function resolveIbanArf(step) {
  switch (step) {
    // ── ACTE 1 — ÉMISSION ──
    case 0: return {
      on: { biz: 1 }, L: { dir: 0 }, R: { dir: 0 },
      caption: "L'utilisateur consulte son espace Banque Démo. Aucune attestation n'est encore demandée — la brique d'identité reste inactive.",
      tech: 'espace client', accent: IBANK };
    case 1: return {
      on: { dox: 1, biz: 1 }, L: { dir: 0, msg: 'en attente du scan' }, R: { dir: -1, msg: 'credential_offer' },
      caption: "Banque Démo demande à Doxallia de préparer une offre d'attestation (credential_offer) et publie le QR code — un composant marque blanche injecté dans la page.",
      tech: 'OpenID4VCI · offer', accent: IDOX };
    case 2: return {
      on: { holder: 1, dox: 1 }, L: { dir: 1, msg: 'GET credential_offer' }, R: { dir: 0 },
      caption: "Le wallet scanne le QR et récupère l'offre d'attestation auprès du point d'entrée d'émission Doxallia.",
      tech: 'GET offer', accent: IDOX };
    case 3: return {
      on: { holder: 1, dox: 1 }, L: { dir: -1, msg: "offre d'attestation" }, R: { dir: 0 },
      caption: "Doxallia a transmis l'offre au wallet ; l'utilisateur vérifie l'attestation IBAN proposée avant de l'ajouter à son portefeuille.",
      tech: 'credential metadata', accent: IRF };
    case 4: return {
      on: { holder: 1 }, L: { dir: 0 }, R: { dir: 0 },
      caption: "Le wallet authentifie l'utilisateur (code personnel) pour autoriser l'ajout de l'attestation. Rien n'est encore délivré.",
      tech: 'authorize add', accent: IRF };
    case 5: return {
      on: { holder: 1, dox: 1, biz: 1 }, L: { dir: -1, msg: 'credential (SD-JWT)' }, R: { dir: -1, msg: 'IBAN signé' },
      caption: "Émission : la banque délivre l'attestation IBAN signée (SD-JWT VC) via Doxallia. Le wallet la reçoit et la stocke de façon chiffrée.",
      tech: 'issue credential', accent: IDOX };
    case 6: return {
      on: { holder: 1, biz: 1 }, L: { dir: 0 }, R: { dir: 0 },
      caption: "L'attestation IBAN est délivrée et stockée dans ID Wallet. Elle pourra être réutilisée auprès de n'importe quel service — sans repasser par la banque.",
      tech: 'credential stored', accent: IRF };
    // ── ACTE 2 — RÉUTILISATION ──
    case 7: return {
      on: { biz: 1 }, L: { dir: 0 }, R: { dir: 0 },
      caption: "L'utilisateur souscrit une offre chez Téléo Mobile. Aucune donnée d'identité n'est encore sollicitée.",
      tech: 'site opérateur', accent: ITEL };
    case 8: return {
      on: { dox: 1, biz: 1 }, L: { dir: 0, msg: 'en attente du scan' }, R: { dir: -1, msg: 'init présentation' },
      caption: "Téléo Mobile demande à Doxallia d'initier une présentation (identité + IBAN) et publie le QR code marque blanche dans sa page.",
      tech: 'Authorization Request', accent: IDOX };
    case 9: return {
      on: { holder: 1, dox: 1 }, L: { dir: 1, msg: 'GET request_uri' }, R: { dir: 0 },
      caption: "Le wallet scanne le QR et récupère la demande de présentation auprès du vérificateur Doxallia.",
      tech: 'GET request_uri', accent: IDOX };
    case 10: return {
      on: { holder: 1, dox: 1 }, L: { dir: -1, msg: 'presentation_definition' }, R: { dir: 0 },
      caption: "Doxallia a transmis la demande (identité PID + attestation IBAN) ; l'utilisateur choisit les attributs à partager.",
      tech: 'presentation_definition', accent: IRF };
    case 11: return {
      on: { holder: 1 }, L: { dir: 0 }, R: { dir: 0 },
      caption: "Le wallet signe la présentation vérifiable (identité + IBAN) avec le code personnel. Rien n'est encore transmis.",
      tech: 'sign vp_token', accent: IRF };
    case 12: return {
      on: { holder: 1, dox: 1, biz: 1 }, L: { dir: 1, msg: 'vp_token' }, R: { dir: 1, msg: 'données vérifiées' },
      caption: "Doxallia reçoit la présentation, contrôle signatures, émetteurs (eIDAS2) et révocation, puis transmet à Téléo uniquement les données vérifiées.",
      tech: 'verify → claims', accent: IDOX };
    case 13: return {
      on: { dox: 1, biz: 1 }, L: { dir: 0 }, R: { dir: 1, msg: 'attributs vérifiés' },
      caption: "Téléo Mobile reçoit l'identité et l'IBAN vérifiés et préremplit le mandat SEPA. L'attestation émise par la banque a été réutilisée — sans ressaisie.",
      tech: 'claims (verified)', accent: ITEL };
    default: return { on: {}, L: { dir: 0 }, R: { dir: 0 }, caption: '', tech: '', accent: IBANK };
  }
}

/* ── carte d'un rôle ── */
function IArfNode({ role, name, sub, color, icon, active }) {
  return (
    <div style={{ position: 'relative', flex: '0 0 232px', maxWidth: 232,
      padding: '13px 15px', borderRadius: 14, background: active ? '#fff' : '#fbfcfe',
      border: `1.5px solid ${active ? color : ILINE}`,
      boxShadow: active ? `0 10px 26px -18px ${color}77` : 'none', transition: 'all .25s' }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 9 }}>
        <span style={{ fontSize: 9.5, fontWeight: 800, letterSpacing: '.07em', textTransform: 'uppercase',
          color: active ? color : '#9aa4b4' }}>{role}</span>
        <span style={{ width: 8, height: 8, borderRadius: '50%', flexShrink: 0,
          background: active ? color : '#cdd5e0',
          boxShadow: active ? `0 0 0 3px ${color}26` : 'none',
          animation: active ? 'pulse-soft 1.4s infinite' : 'none' }} />
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 11 }}>
        <div style={{ width: 40, height: 40, borderRadius: 11, flexShrink: 0,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          background: active ? color : '#e7ecf3', transition: 'background .25s' }}>
          {icon(active ? '#fff' : '#8a93a6')}
        </div>
        <div style={{ minWidth: 0 }}>
          <div style={{ fontSize: 15, fontWeight: 800, color: '#0e1726', letterSpacing: '-.01em',
            lineHeight: 1.15, whiteSpace: 'nowrap' }}>{name}</div>
          <div style={{ fontSize: 11, color: '#5b6678', marginTop: 1, lineHeight: 1.25 }}>{sub}</div>
        </div>
      </div>
    </div>
  );
}

/* ── connecteur animé entre deux rôles ── */
function IArfLink({ protocol, color, dir = 0, msg }) {
  const live = dir !== 0;
  const active = live;
  const railCol = live ? color : ILINE;
  return (
    <div style={{ flex: '1 1 70px', minWidth: 64, maxWidth: 188, position: 'relative',
      display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 7,
      padding: '0 4px', alignSelf: 'center' }}>
      <div style={{ display: 'inline-flex', alignItems: 'center', gap: 5, padding: '3px 9px', borderRadius: 999,
        background: active ? `${color}14` : '#eef1f6', transition: 'background .25s',
        fontSize: 9.5, fontWeight: 800, letterSpacing: '.02em', whiteSpace: 'nowrap',
        color: active ? color : '#8a93a6' }}>
        <DIc.lock s={11} c={active ? color : '#8a93a6'} /> {protocol}
      </div>
      <div style={{ position: 'relative', width: '100%', height: 2,
        borderTop: `2px ${live ? 'solid' : 'dashed'} ${railCol}`, transition: 'border-color .25s' }}>
        {live && (
          <span style={{ position: 'absolute', top: -4, width: 8, height: 8, borderRadius: '50%',
            background: color, boxShadow: `0 0 10px ${color}`,
            animation: `${dir > 0 ? 'arf-r' : 'arf-l'} 1.35s linear infinite` }} />
        )}
        {live && (
          <span style={{ position: 'absolute', top: -4,
            [dir > 0 ? 'right' : 'left']: -1, width: 0, height: 0,
            borderTop: '5px solid transparent', borderBottom: '5px solid transparent',
            [dir > 0 ? 'borderLeft' : 'borderRight']: `7px solid ${color}` }} />
        )}
      </div>
      <div style={{ fontSize: 9.5, fontFamily: 'ui-monospace, monospace', textAlign: 'center',
        color: live ? color : '#aab4c4', minHeight: 12, lineHeight: 1.2,
        fontWeight: live ? 700 : 500, whiteSpace: 'nowrap', maxWidth: '100%', overflow: 'hidden',
        textOverflow: 'ellipsis' }}>{msg || ''}</div>
    </div>
  );
}

/* ── popover « ce que fournit Doxallia » sur ce parcours ── */
function IDoxInfo({ onClose }) {
  const items = [
    ['Émission marque blanche', "QR code et écrans d'offre intégrés dans la page de la banque (Web Elements). Doxallia orchestre la délivrance OpenID4VCI de l'attestation IBAN."],
    ['Vérification OpenID4VP', "Côté opérateur, Doxallia dialogue avec le wallet à la place de Téléo : génération de la requête, réception de la présentation (identité + IBAN)."],
    ['Contrôle de confiance', 'Vérifie signature, émetteur (eIDAS2) et révocation, puis ne transmet au partenaire que des données vérifiées.'],
  ];
  return (
    <div style={{ position: 'absolute', bottom: 'calc(100% + 10px)', left: '50%', transform: 'translateX(-50%)',
      width: 340, background: '#fff', borderRadius: 14, padding: 16, zIndex: 30,
      border: `1.5px solid ${IDOX}`, boxShadow: '0 26px 60px -26px rgba(14,23,38,.55)' }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10 }}>
        <div style={{ display: 'inline-flex', alignItems: 'center', gap: 8, fontSize: 12.5, fontWeight: 800, color: IDOX }}>
          <span style={{ width: 22, height: 22, borderRadius: 6, background: IDOX, display: 'grid', placeItems: 'center' }}>
            <IRelay s={14} c="#fff" /></span>
          Le rôle de Doxallia
        </div>
        <button onClick={onClose} style={{ border: 'none', background: 'none', cursor: 'pointer',
          fontSize: 15, color: '#8a93a6', lineHeight: 1 }}>✕</button>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        {items.map(([t, d]) => (
          <div key={t} style={{ display: 'flex', gap: 9 }}>
            <span style={{ width: 6, height: 6, borderRadius: '50%', background: IDOX, flexShrink: 0, marginTop: 6 }} />
            <div>
              <div style={{ fontSize: 12.5, fontWeight: 700, color: '#0e1726' }}>{t}</div>
              <div style={{ fontSize: 11.5, lineHeight: 1.45, color: '#56627a', marginTop: 1 }}>{d}</div>
            </div>
          </div>
        ))}
      </div>
      <span style={{ position: 'absolute', bottom: -8, left: '50%', transform: 'translateX(-50%) rotate(45deg)',
        width: 14, height: 14, background: '#fff', borderRight: `1.5px solid ${IDOX}`, borderBottom: `1.5px solid ${IDOX}` }} />
    </div>
  );
}

/* ── bande principale (cadre séparé) ── */
function IbanArfDiagram({ step, open, onToggle }) {
  const [info, setInfo] = React.useState(false);
  const issue = step <= 6;
  const A = resolveIbanArf(step);
  const on = A.on || {};

  // partenaire métier (nœud de droite) selon l'acte
  const biz = issue
    ? { role: 'Émetteur', name: 'Banque Démo', sub: 'Issuer · attestation IBAN', color: IBANK,
        icon: (c) => <DIc.bank s={21} c={c} /> }
    : { role: 'Relying Party', name: 'Téléo Mobile', sub: 'Vérificateur · opérateur', color: ITEL,
        icon: (c) => <DIIc.signal s={21} c={c} /> };

  const lProtocol = issue ? 'OpenID4VCI · QR' : 'OpenID4VP · QR';
  const actLabel = issue ? 'Acte 1 · Émission' : 'Acte 2 · Réutilisation';

  return (
    <div style={{ flexShrink: 0, padding: '0 clamp(12px,3vw,28px) 14px' }}>
      <div style={{ maxWidth: 1320, margin: '0 auto', background: '#fff', borderRadius: 16,
        border: '1px solid #e2e7ef', boxShadow: '0 18px 40px -28px rgba(14,23,38,.45)', overflow: 'visible' }}>
        {/* en-tête */}
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          padding: '11px 16px', borderBottom: open ? '1px solid #eef1f6' : 'none' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <span style={{ width: 8, height: 8, borderRadius: '50%', background: A.accent,
              animation: 'pulse-soft 1.4s infinite' }} />
            <span style={{ fontSize: 13, fontWeight: 800, color: '#0e1726', letterSpacing: '-.01em' }}>
              Architecture ARF — flux en temps réel
            </span>
            <span style={{ fontSize: 10.5, fontWeight: 800, color: biz.color, background: `${biz.color}14`,
              padding: '3px 9px', borderRadius: 999, whiteSpace: 'nowrap' }}>{actLabel}</span>
          </div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
              {[['Holder', IRF], ['Intermediary', IDOX], [biz.role, biz.color]].map(([l, c]) => (
                <span key={l} style={{ display: 'inline-flex', alignItems: 'center', gap: 5,
                  fontSize: 10.5, fontWeight: 700, color: '#56627a' }}>
                  <span style={{ width: 9, height: 9, borderRadius: 3, background: c }} /> {l}
                </span>
              ))}
            </div>
            <button onClick={onToggle} style={{ display: 'inline-flex', alignItems: 'center', gap: 6,
              border: '1px solid #e2e7ef', background: '#fff', borderRadius: 8, padding: '5px 9px',
              cursor: 'pointer', fontSize: 11.5, fontWeight: 700, color: '#56627a' }}>
              {open ? 'Réduire' : 'Afficher le schéma'}
              <span style={{ display: 'inline-block', transform: open ? 'rotate(180deg)' : 'none',
                transition: 'transform .2s' }}>⌄</span>
            </button>
          </div>
        </div>

        {open && (
          <div style={{ padding: '16px 18px 14px' }}>
            {/* rangée des rôles + flux */}
            <div style={{ display: 'flex', alignItems: 'stretch', justifyContent: 'center' }}>
              <IArfNode role="Holder" name="ID Wallet" sub="Wallet du citoyen · PID + IBAN"
                color={IRF} active={!!on.holder}
                icon={(c) => <DIc.shield s={21} c={c} />} />

              <IArfLink protocol={lProtocol} color={IDOX} dir={A.L.dir} msg={A.L.msg} />

              <div style={{ position: 'relative', flex: '0 0 232px', maxWidth: 232 }}>
                {info && <IDoxInfo onClose={() => setInfo(false)} />}
                <div onClick={() => setInfo(v => !v)} style={{ cursor: 'pointer' }}>
                  <IArfNode role="Relying Party Intermediary" name="Doxallia" sub="Intermédiaire & vérificateur ⓘ"
                    color={IDOX} active={!!on.dox}
                    icon={(c) => <IRelay s={21} c={c} />} />
                </div>
              </div>

              <IArfLink protocol="Marque blanche · API" color={biz.color} dir={A.R.dir} msg={A.R.msg} />

              <IArfNode role={biz.role} name={biz.name} sub={biz.sub}
                color={biz.color} active={!!on.biz} icon={biz.icon} />
            </div>

            {/* légende d'étape */}
            <div style={{ display: 'flex', alignItems: 'center', gap: 14, marginTop: 14, padding: '11px 14px',
              borderRadius: 12, background: `${A.accent}0c`, border: `1px solid ${A.accent}26` }}>
              <span style={{ flexShrink: 0, width: 26, height: 26, borderRadius: 8, background: A.accent,
                display: 'grid', placeItems: 'center', color: '#fff' }}>
                <DIc.arrow s={15} c="#fff" />
              </span>
              <div style={{ flex: 1, fontSize: 12.5, lineHeight: 1.45, color: '#26334a', fontWeight: 500 }}>
                {A.caption}
              </div>
              <span style={{ flexShrink: 0, fontSize: 10.5, fontFamily: 'ui-monospace, monospace', fontWeight: 700,
                color: A.accent, background: '#fff', border: `1px solid ${A.accent}33`,
                padding: '4px 9px', borderRadius: 7, whiteSpace: 'nowrap' }}>
                {A.tech}
              </span>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

Object.assign(window, { IbanArfDiagram });
