/* ───────────────────────────────────────────────────────────
   IbanApp.jsx — Orchestrateur du parcours « Attestation IBAN »
   Acte 1 — Émission   : Banque Démo → wallet (OpenID4VCI)
   Acte 2 — Réutilisation : wallet → Téléo Mobile (OpenID4VP)
   Scène cross-device : application web (desktop) + téléphone (wallet).
   ─────────────────────────────────────────────────────────── */

const { useState: useStateI, useEffect: useEffectI, useRef: useRefI } = React;
const { PROFILES: PROF_I, Ic: AppIc, IIc: AppI2, ChromeWindow: ChromeI, IOSDevice: IOSI,
        IbanBankApp, IbanTelecomApp, WalletApp: WalletI, IbanArfDiagram,
        IWHome, IWOffer, IWConsent2, IWAuth, IWWorking, IWDone,
        useTweaks: useTweaksI, TweaksPanel: TweaksPanelI, TweakSection: TweakSectionI,
        TweakSelect: TweakSelectI, TweakButton: TweakButtonI, TweakToggle: TweakToggleI } = window;

const IBAN_DEFAULTS = /*EDITMODE-BEGIN*/{
  "profile": "camille",
  "annot": true
}/*EDITMODE-END*/;

// ── machine à états : un entier `step` 0..13 pilote toute la scène ──
function deriveIban(step) {
  const act = step <= 6 ? 'issue' : 'reuse';
  // application web visible + son sous-état
  let bank = null, telecom = null;
  if (act === 'issue') bank = step === 0 ? 'account' : step === 6 ? 'issued' : 'offer';
  else telecom = step === 7 ? 'plan' : step === 12 ? 'verifying' : step === 13 ? 'done' : 'request';
  // état du wallet
  const W = {
    0: 'home', 1: 'home', 2: 'scan', 3: 'offer', 4: 'authAdd', 5: 'adding', 6: 'added',
    7: 'home', 8: 'home', 9: 'scan', 10: 'consent', 11: 'auth2', 12: 'sharing', 13: 'success',
  }[step];
  // statut affiché côté application web (pour le QR)
  const bankWallet = { 1: 'pending', 3: 'offer', 4: 'auth', 5: 'adding' }[step] || 'pending';
  const telWallet = { 8: 'pending', 10: 'consent', 11: 'auth' }[step] || 'pending';
  // flux de la liaison
  const flow =
    [1, 2, 8, 9].includes(step) ? 'idle' :
    [3, 4, 10, 11].includes(step) ? 'soft' :
    [5, 12].includes(step) ? 'strong' : 'none';
  const incoming = step === 1 || step === 8;
  const hasIban = step >= 6;
  const scan = step === 2 || step === 9;
  return { act, bank, telecom, W, bankWallet, telWallet, flow, incoming, hasIban, scan };
}

function IbanApp({ onHome }) {
  const [t, setTweak] = useTweaksI(IBAN_DEFAULTS);
  const profile = PROF_I.find(p => p.id === t.profile) || PROF_I[0];

  const [step, setStep] = useStateI(() => {
    const n = parseInt(localStorage.getItem('iban-step') || '0', 10);
    return Number.isFinite(n) && n >= 0 && n <= 13 ? n : 0;
  });
  const [modal, setModal] = useStateI(false);
  const [arfOpen, setArfOpen] = useStateI(true);   // schéma ARF déplié
  const timers = useRefI([]);
  const clearTimers = () => { timers.current.forEach(clearTimeout); timers.current = []; };
  const after = (ms, fn) => { const id = setTimeout(fn, ms); timers.current.push(id); };

  const go = (n) => { clearTimers(); setStep(n); };
  useEffectI(() => { localStorage.setItem('iban-step', String(step)); }, [step]);

  const S = deriveIban(step);

  // auto-avances (scan détecté, émission, vérification)
  useEffectI(() => {
    if (step === 2) after(1800, () => setStep(3));        // scan → offre reçue
    if (step === 5) after(1500, () => setStep(6));        // ajout → attestation émise
    if (step === 9) after(1800, () => setStep(10));       // scan → consentement
    if (step === 12) after(1700, () => setStep(13));      // vérification → confirmé
    return clearTimers;
  }, [step]);

  const reset = () => { go(0); setModal(false); };

  // handlers d'avancement (déclenchés par les boutons des UIs)
  const H = {
    onIssue:      () => go(1),                  // banque : obtenir l'attestation
    onScan:       () => go(S.act === 'issue' ? 2 : 9),
    onAdd:        () => go(4),                  // wallet : ajouter l'attestation → code
    onAuthAdd:    () => go(5),                  // code saisi → ajout
    onContinue:   () => go(7),                  // banque : passer à l'acte 2
    onSubscribe:  () => go(8),                  // télécom : souscrire
    onAllow:      () => go(11),                 // wallet : autoriser → code
    onAuth2:      () => go(12),                 // code saisi → partage
    onFinish:     () => setModal(true),
    onRefuseAdd:  () => go(1),
    onRefuseShare:() => go(8),
  };

  // ── wallet : écran selon l'état ──
  function walletNode() {
    switch (S.W) {
      case 'scan':    return <WalletI walletStage="scan" />;
      case 'offer':   return <IWOffer profile={profile} onAdd={H.onAdd} onRefuse={H.onRefuseAdd} />;
      case 'authAdd': return <IWAuth title="Saisissez votre code pour signer l'ajout de l'attestation." onDone={H.onAuthAdd} />;
      case 'adding':  return <IWWorking title="Ajout à votre portefeuille…" sub="Réception et stockage chiffré" />;
      case 'added':   return <IWDone title="Attestation ajoutée">Votre attestation IBAN est disponible dans ID Wallet.</IWDone>;
      case 'consent': return <IWConsent2 profile={profile} onAllow={H.onAllow} onRefuse={H.onRefuseShare} />;
      case 'auth2':   return <IWAuth title="Saisissez votre code pour signer le partage." onDone={H.onAuth2} />;
      case 'sharing': return <IWWorking title="Partage en cours…" sub="Signature et envoi sécurisé" />;
      case 'success': return <IWDone title="Partage réussi">Vos données ont été transmises à Téléo Mobile. Reprenez sur votre ordinateur.</IWDone>;
      default:        return <IWHome profile={profile} hasIban={S.hasIban} incoming={S.incoming} onScan={H.onScan} />;
    }
  }

  // ── application web : banque (acte 1) ou télécom (acte 2) ──
  const webNode = S.act === 'issue'
    ? <IbanBankApp stage={S.bank} walletStage={S.bankWallet} profile={profile} onIssue={H.onIssue} onContinue={H.onContinue} />
    : <IbanTelecomApp stage={S.telecom} walletStage={S.telWallet} profile={profile} onSubscribe={H.onSubscribe} onFinish={H.onFinish} />;
  const webMeta = S.act === 'issue'
    ? { url: 'banque-demo.fr/espace-client', tab: 'Banque Démo — Espace client', label: 'Application web — Banque Démo', sub: 'émetteur de l\'attestation IBAN' }
    : { url: 'teleo-mobile.fr/souscription', tab: 'Téléo Mobile — Souscription', label: 'Application web — Téléo Mobile', sub: 'opérateur · vérificateur de l\'IBAN' };

  // ── scale-to-fit (réserve la place du schéma ARF sous la scène) ──
  const DW = 1480, DH = 916;
  const [scale, setScale] = useStateI(1);
  const bandH = t.annot ? (arfOpen ? 250 : 52) : 0;
  useEffectI(() => {
    const fit = () => setScale(Math.min(window.innerWidth / DW, (window.innerHeight - bandH) / DH, 1));
    fit(); window.addEventListener('resize', fit);
    return () => window.removeEventListener('resize', fit);
  }, [bandH]);

  return (
    <div style={{ width: '100vw', height: '100vh', background: 'var(--stage-bg)',
      display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      <div style={{ flex: '1 1 auto', minHeight: 0, display: 'flex', alignItems: 'center',
        justifyContent: 'center', overflow: 'hidden' }}>
      <div style={{ width: DW, height: DH, transform: `scale(${scale})`, transformOrigin: 'center',
        position: 'relative', flexShrink: 0 }}>

        {/* barre démo */}
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', height: 50, padding: '0 6px' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
            <button onClick={onHome} style={{ display: 'inline-flex', alignItems: 'center', gap: 7,
              padding: '8px 13px', borderRadius: 9, border: '1px solid rgba(14,23,38,.16)', background: '#fff',
              fontSize: 13.5, fontWeight: 700, color: '#0e1726', cursor: 'pointer' }}>
              <AppI2.back s={16} /> Démonstrateurs
            </button>
            <span style={{ fontSize: 17, fontWeight: 800, color: '#0e1726', letterSpacing: '-.01em' }}>
              Attestation IBAN — émission & réutilisation
            </span>
          </div>
          <div style={{ display: 'flex', gap: 8 }}>
            <button onClick={() => go(Math.max(0, step - 1))} disabled={step === 0}
              style={{ padding: '9px 14px', borderRadius: 9, border: '1px solid rgba(14,23,38,.16)',
                background: '#fff', fontSize: 14, fontWeight: 700, color: step === 0 ? '#aab' : '#0e1726',
                cursor: step === 0 ? 'not-allowed' : 'pointer' }}>Précédent</button>
            <button onClick={reset} style={{ display: 'inline-flex', alignItems: 'center', gap: 8,
              padding: '9px 16px', borderRadius: 9, border: '1px solid rgba(14,23,38,.16)', background: '#fff',
              fontSize: 14, fontWeight: 700, color: '#0e1726', cursor: 'pointer' }}>
              <AppIc.refresh s={16} /> Recommencer
            </button>
          </div>
        </div>

        {/* ruban des deux actes */}
        <ActRibbon act={S.act} step={step} />

        {/* scène cross-device */}
        <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'center', marginTop: 8 }}>
          <Labeled label={webMeta.label} sub={webMeta.sub}>
            <ChromeI width={880} height={700} url={webMeta.url} tabs={[{ title: webMeta.tab }]}>
              {webNode}
            </ChromeI>
          </Labeled>
          <IbanConnector flow={S.flow} protocol={S.act === 'issue' ? 'OpenID4VCI' : 'OpenID4VP'}
            caption={S.act === 'issue' ? 'émission' : 'présentation'} />
          <Labeled label="Smartphone — ID Wallet" sub="portefeuille d'identité de l'utilisateur">
            <div style={{ transform: 'translateY(-4px)' }}>
              <IOSI width={344} height={724} dark={S.scan}>{walletNode()}</IOSI>
            </div>
          </Labeled>
        </div>

        {modal && <IbanEndModal onReset={reset} onHome={onHome} onClose={() => setModal(false)} />}
      </div>
      </div>

      {/* schéma ARF dynamique — cadre séparé sous la scène */}
      {t.annot && (
        <IbanArfDiagram step={step} open={arfOpen} onToggle={() => setArfOpen(o => !o)} />
      )}

      {/* Tweaks */}
      <TweaksPanelI>
        <TweakSectionI label="Jeu de données" />
        <TweakSelectI label="Profil client" value={t.profile}
          options={PROF_I.map(p => ({ value: p.id, label: `${p.prenom} ${p.nom}` }))}
          onChange={(v) => setTweak('profile', v)} />
        <TweakSectionI label="Lecture pédagogique" />
        <TweakToggleI label="Schéma ARF — flux entre parties prenantes" value={t.annot}
          onChange={(v) => setTweak('annot', v)} />
        <TweakSectionI label="Démo" />
        <TweakButtonI label="Recommencer le parcours" onClick={reset} />
      </TweaksPanelI>
    </div>
  );
}

// ── ruban : Acte 1 émission · Acte 2 réutilisation ──
function ActRibbon({ act, step }) {
  const acts = [
    { id: 'issue', n: '1', t: 'Émission de l\'attestation', s: 'Banque Démo → portefeuille · OpenID4VCI' },
    { id: 'reuse', n: '2', t: 'Réutilisation de l\'IBAN', s: 'Portefeuille → Téléo Mobile · OpenID4VP' },
  ];
  return (
    <div style={{ display: 'flex', gap: 12, marginTop: 2 }}>
      {acts.map((a, i) => {
        const active = a.id === act;
        const done = a.id === 'issue' && act === 'reuse';
        return (
          <div key={a.id} style={{ flex: 1, display: 'flex', alignItems: 'center', gap: 12, padding: '10px 16px',
            borderRadius: 12, background: active ? '#fff' : 'rgba(255,255,255,.5)',
            border: `1px solid ${active ? 'rgba(22,87,200,.4)' : 'rgba(14,23,38,.1)'}`,
            boxShadow: active ? '0 8px 24px -16px rgba(22,87,200,.6)' : 'none', transition: 'all .25s',
            opacity: active || done ? 1 : .6 }}>
            <div style={{ width: 30, height: 30, borderRadius: '50%', flexShrink: 0, fontSize: 13, fontWeight: 800,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              background: done ? 'var(--bank-ok)' : active ? 'var(--bank-primary)' : '#e7ebf2',
              color: done || active ? '#fff' : '#8a93a6' }}>
              {done ? <AppIc.check s={15} c="#fff" /> : a.n}
            </div>
            <div style={{ minWidth: 0 }}>
              <div style={{ fontSize: 14, fontWeight: 800, color: '#0e1726' }}>{a.t}</div>
              <div style={{ fontSize: 11.5, color: '#5b6678', whiteSpace: 'nowrap' }}>{a.s}</div>
            </div>
          </div>
        );
      })}
    </div>
  );
}

// ── liaison animée (cross-device) ──
function IbanConnector({ flow, protocol, caption }) {
  const active = flow === 'soft' || flow === 'strong';
  const stroke = active ? '#1657c8' : '#aab4c4';
  const W = 132, H = 700, cy = 296;
  return (
    <div style={{ width: W, height: H, position: 'relative', flexShrink: 0,
      display: 'flex', alignItems: 'flex-start', justifyContent: 'center' }}>
      <svg width={W} height={H} style={{ position: 'absolute', top: 0, left: 0 }}>
        <line x1={8} y1={cy} x2={W - 8} y2={cy} stroke="#cdd5e0" strokeWidth={2} />
        {active && (
          <line x1={8} y1={cy} x2={W - 8} y2={cy} stroke={stroke}
            strokeWidth={flow === 'strong' ? 3 : 2.4} strokeLinecap="round" strokeDasharray="2 12"
            style={{ animation: `flow-left ${flow === 'strong' ? 0.7 : 1.1}s linear infinite` }} />
        )}
        <circle cx={8} cy={cy} r={5} fill={active ? stroke : '#aab4c4'} />
        <circle cx={W - 8} cy={cy} r={5} fill={active ? stroke : '#aab4c4'} />
        {flow === 'idle' && (
          <circle cx={W / 2} cy={cy} r={4} fill="#1657c8" style={{ animation: 'pulse-soft 1.3s infinite' }} />
        )}
      </svg>
      <div style={{ position: 'absolute', top: cy + 14, left: '50%', transform: 'translateX(-50%)',
        display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6, width: 124 }}>
        <div style={{ display: 'inline-flex', alignItems: 'center', gap: 6, padding: '5px 10px', borderRadius: 999,
          background: active ? 'rgba(22,87,200,.1)' : '#e7ecf3', color: active ? '#1657c8' : '#8a93a6',
          fontSize: 10.5, fontWeight: 700, whiteSpace: 'nowrap', transition: 'all .2s' }}>
          <AppIc.lock s={12} c={active ? '#1657c8' : '#8a93a6'} /> {protocol}
        </div>
        <div style={{ fontSize: 10.5, color: '#8a93a6', textAlign: 'center', lineHeight: 1.3, fontFamily: 'monospace' }}>
          {flow === 'idle' && 'liaison établie'}
          {flow === 'soft' && caption + '…'}
          {flow === 'strong' && (caption === 'émission' ? 'délivrance\nvérifiable' : 'présentation\nvérifiable')}
          {flow === 'none' && caption}
        </div>
      </div>
    </div>
  );
}

function Labeled({ label, sub, children }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
      {children}
      <div style={{ textAlign: 'center', marginTop: 16, whiteSpace: 'nowrap' }}>
        <div style={{ fontSize: 13.5, fontWeight: 700, color: '#0e1726' }}>{label}</div>
        <div style={{ fontSize: 12, color: '#5b6678', marginTop: 1 }}>{sub}</div>
      </div>
    </div>
  );
}

function IbanEndModal({ onReset, onHome, onClose }) {
  return (
    <div onClick={onClose} style={{ position: 'absolute', inset: 0, zIndex: 100,
      background: 'rgba(10,16,26,.45)', backdropFilter: 'blur(3px)',
      display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
      <div onClick={e => e.stopPropagation()} className="rise" style={{ width: 460, background: '#fff',
        borderRadius: 18, padding: 32, boxShadow: '0 40px 90px -30px rgba(0,0,0,.5)', textAlign: 'center' }}>
        <div style={{ width: 56, height: 56, borderRadius: 14, background: 'rgba(21,122,82,.1)', margin: '0 auto 18px',
          display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <AppIc.check s={30} c="var(--bank-ok)" />
        </div>
        <h3 style={{ fontSize: 21, fontWeight: 800, color: '#0e1726', margin: '0 0 10px' }}>
          Parcours terminé — IBAN émis puis réutilisé
        </h3>
        <p style={{ fontSize: 14.5, lineHeight: 1.55, color: '#56627a', margin: '0 0 24px' }}>
          La banque a délivré l'attestation IBAN dans le portefeuille (OpenID4VCI), puis l'utilisateur l'a
          présentée — avec son identité — à un opérateur télécom pour ouvrir une ligne (OpenID4VP). La même
          attestation peut être réutilisée auprès de n'importe quel service.
        </p>
        <div style={{ display: 'flex', gap: 12, justifyContent: 'center' }}>
          <button onClick={onHome} style={{ padding: '13px 22px', borderRadius: 10, border: '1.5px solid var(--bank-line)',
            background: '#fff', fontSize: 15, fontWeight: 700, color: 'var(--bank-primary)', cursor: 'pointer' }}>
            Autres démonstrateurs
          </button>
          <button onClick={onReset} style={{ display: 'inline-flex', alignItems: 'center', gap: 8,
            padding: '13px 22px', borderRadius: 10, border: 'none', background: 'var(--bank-primary)',
            fontSize: 15, fontWeight: 700, color: '#fff', cursor: 'pointer' }}>
            <AppIc.refresh s={16} c="#fff" /> Rejouer le parcours
          </button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { IbanApp });
