// Onboarding — 4 écrans au premier lancement, une seule fois.
//
// Passe après la connexion : on ne présente pas l'app à quelqu'un qui n'est
// pas encore entré. Mémorisé en localStorage sous `vasco_onboarded` ; le
// panneau Tweaks sait le remettre à zéro pour rejouer la séquence en démo.
//
// Navigation : balayage horizontal, tap sur « Suivant », ou « Passer ».

const OB_VT = window.VT || {};
const OB_INK = OB_VT.ink || '#0a0a0a';
const OB_SUB = OB_VT.sub || '#6b7280';
const OB_BG = OB_VT.paper || '#f6f5f1';
const OB_SURF = OB_VT.surface || '#ffffff';
const OB_HAIR = OB_VT.hair || 'rgba(10,10,10,0.06)';
const OB_HAIR2 = OB_VT.hair2 || 'rgba(10,10,10,0.10)';
const OB_MED = OB_VT.medBlue || '#3d6b8f';
const OB_MED_TINT = OB_VT.medBlueTint || 'rgba(61,107,143,0.10)';
const OB_OK = OB_VT.success || '#059669';
const OB_OK_TINT = OB_VT.successTint || 'rgba(5,150,105,0.10)';

const VASCO_ONBOARD_KEY = 'vasco_onboarded';

// `?onboarding` dans l'URL force la relecture — c'est le chemin de démo.
// Le panneau Tweaks ne s'ouvre que depuis un hôte d'aperçu (il attend un
// postMessage) : dans un navigateur normal son bouton est inatteignable.
const obForced = () => {
  try { return /(^|[?&])onboarding(=|&|$)/.test(window.location.search); }
  catch (e) { return false; }
};

// Même prudence que pour l'auth : localStorage lève en navigation privée.
const obRead = () => {
  if (obForced()) return null;
  try { return window.localStorage.getItem(VASCO_ONBOARD_KEY); } catch (e) { return null; }
};
const obWrite = () => {
  try { window.localStorage.setItem(VASCO_ONBOARD_KEY, '1'); } catch (e) { /* sans mémoire */ }
};
const obClear = () => {
  try { window.localStorage.removeItem(VASCO_ONBOARD_KEY); } catch (e) { /* rien à faire */ }
};

// ─────────────────────────────────────────────────────────────
// Illustrations — géométriques, sur la palette de l'app.
// Pas d'images : tout est vectoriel, donc net à toutes les tailles.
// ─────────────────────────────────────────────────────────────

function ObArtDictee() {
  return (
    <div style={{ position: 'relative', width: 200, height: 200, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
      {/* Halos concentriques — la même respiration que le micro du dashboard */}
      {[0, 1, 2].map((i) => (
        <div key={i} style={{
          position: 'absolute', inset: 0, borderRadius: '50%',
          border: `1.5px solid ${OB_MED}`,
          animation: `obHalo 2.8s cubic-bezier(.4,0,.2,1) ${i * 900}ms infinite`,
        }} />
      ))}
      <div style={{
        width: 108, height: 108, borderRadius: '50%', background: OB_MED,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        boxShadow: OB_VT.shadowFab, position: 'relative', zIndex: 2,
      }}>
        <svg width="44" height="44" viewBox="0 0 24 24" fill="none" stroke="#fff"
          strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
          <rect x="9" y="3" width="6" height="12" rx="3" />
          <path d="M5 11a7 7 0 0 0 14 0" />
          <path d="M12 18v3" />
        </svg>
      </div>
      {/* Onde — barres qui pulsent sous le micro */}
      <div style={{
        position: 'absolute', bottom: 4, left: 0, right: 0, zIndex: 2,
        display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 4, height: 26,
      }}>
        {[0, 1, 2, 3, 4, 5, 6, 7, 8].map((i) => (
          <div key={i} style={{
            width: 3, borderRadius: 2, background: OB_MED, opacity: 0.55,
            animation: `obWave 1.1s ease-in-out ${i * 90}ms infinite`,
          }} />
        ))}
      </div>
    </div>
  );
}

function ObArtPatients() {
  // Reprend trois teintes de la palette de dossiers (manila / mint / sky).
  const cards = [
    { body: '#dbeafe', spine: '#94bff0', rot: -9, x: -46, y: 10, z: 1 },
    { body: '#dcfce7', spine: '#a7e8be', rot: 5, x: 44, y: 4, z: 2 },
    { body: '#fdf3c4', spine: '#f5d97a', rot: -2, x: 0, y: -6, z: 3 },
  ];
  return (
    <div style={{ position: 'relative', width: 220, height: 200 }}>
      {cards.map((c, i) => (
        // Deux niveaux : l'extérieur anime l'entrée, l'intérieur porte la
        // position et l'inclinaison. Sur un seul élément, le transform de
        // l'animation écraserait le rotate et les cartes s'empileraient.
        <div key={i} style={{
          position: 'absolute', left: '50%', top: '50%', zIndex: c.z,
          width: 116, height: 142, marginLeft: -58, marginTop: -71,
          animation: `obCardIn .55s cubic-bezier(.16,1,.3,1) ${i * 90}ms both`,
        }}>
          <div style={{
            width: '100%', height: '100%', position: 'relative',
            transform: `translate(${c.x}px, ${c.y}px) rotate(${c.rot}deg)`,
            background: c.body, border: `1.5px solid ${c.spine}`,
            borderRadius: 16, boxShadow: OB_VT.shadowMd,
            padding: '14px 12px',
          }}>
            {/* Onglet du dossier */}
            <div style={{
              position: 'absolute', top: -9, left: 14, width: 46, height: 10,
              background: c.spine, borderRadius: '6px 6px 0 0',
            }} />
            <div style={{
              width: 30, height: 30, borderRadius: 10,
              background: 'rgba(255,255,255,0.65)',
            }} />
            <div style={{ height: 7, width: '78%', borderRadius: 4, background: 'rgba(10,10,10,0.13)', marginTop: 12 }} />
            <div style={{ height: 6, width: '54%', borderRadius: 4, background: 'rgba(10,10,10,0.09)', marginTop: 7 }} />
            <div style={{ height: 6, width: '66%', borderRadius: 4, background: 'rgba(10,10,10,0.09)', marginTop: 7 }} />
          </div>
        </div>
      ))}
    </div>
  );
}

function ObArtAssistant() {
  const chips = ['Courrier', 'CCAM', 'RDV'];
  return (
    <div style={{
      width: 240, height: 200, display: 'flex', flexDirection: 'column',
      justifyContent: 'center', gap: 10,
    }}>
      {/* Demande du praticien */}
      <div style={{
        alignSelf: 'flex-end', maxWidth: '82%',
        background: OB_INK, color: '#fff',
        borderRadius: '18px 18px 4px 18px', padding: '10px 14px',
        fontSize: 12.5, fontWeight: 500, lineHeight: 1.4,
        animation: 'obBubble .45s cubic-bezier(.16,1,.3,1) both',
      }}>
        Code CCAM du pontage ?
      </div>
      {/* Réponse de l'assistant */}
      <div style={{
        alignSelf: 'flex-start', maxWidth: '86%',
        background: OB_SURF, border: `1px solid ${OB_HAIR}`,
        borderRadius: '18px 18px 18px 4px', padding: '11px 14px',
        boxShadow: OB_VT.shadowSm,
        animation: 'obBubble .45s cubic-bezier(.16,1,.3,1) 260ms both',
      }}>
        <div className="mono" style={{ fontSize: 13, fontWeight: 700, color: OB_INK, letterSpacing: '0.3px' }}>
          EBAF003
        </div>
        <div style={{ fontSize: 11.5, fontWeight: 500, color: OB_SUB, marginTop: 3, lineHeight: 1.35 }}>
          Pontage fémoro-poplité
        </div>
      </div>
      {/* Actions proposées */}
      <div style={{ display: 'flex', gap: 6, alignSelf: 'flex-start', marginTop: 2 }}>
        {chips.map((c, i) => (
          <span key={c} style={{
            padding: '6px 11px', borderRadius: 999,
            background: OB_MED_TINT, color: OB_MED,
            fontSize: 11, fontWeight: 700,
            animation: `obBubble .4s cubic-bezier(.16,1,.3,1) ${480 + i * 100}ms both`,
          }}>{c}</span>
        ))}
      </div>
    </div>
  );
}

function ObArtPret() {
  return (
    <div style={{ position: 'relative', width: 200, height: 200, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
      <div style={{
        width: 124, height: 124, borderRadius: '50%', background: OB_OK_TINT,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        animation: 'obPop .5s cubic-bezier(.16,1,.3,1) both',
      }}>
        <div style={{
          width: 84, height: 84, borderRadius: '50%', background: OB_OK,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          boxShadow: '0 8px 24px rgba(5,150,105,0.28)',
        }}>
          <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="#fff"
            strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
            {/* Le tracé se dessine plutôt que d'apparaître d'un coup */}
            <path d="M20 6L9 17l-5-5" style={{
              strokeDasharray: 32, strokeDashoffset: 32,
              animation: 'obCheck .5s cubic-bezier(.4,0,.2,1) 320ms forwards',
            }} />
          </svg>
        </div>
      </div>
    </div>
  );
}

const OB_SLIDES = [
  {
    id: 'dictee',
    art: <ObArtDictee />,
    title: 'Dictez,\non rédige.',
    body: "Un compte rendu opératoire complet en parlant deux minutes. Vous relisez, vous corrigez, vous validez.",
  },
  {
    id: 'patients',
    art: <ObArtPatients />,
    title: 'Vos dossiers,\nen un geste.',
    body: "Wallet, liste ou grille — chaque patient à portée de pouce, avec ses alertes et son prochain rendez-vous.",
  },
  {
    id: 'assistant',
    art: <ObArtAssistant />,
    title: 'Un assistant\nqui agit.',
    body: "Courrier au correspondant, codage CCAM, contrôle à programmer : vous demandez, c'est préparé.",
  },
  {
    id: 'pret',
    art: <ObArtPret />,
    title: 'Tout est prêt,\nDocteur.',
    body: "Les données affichées sont fictives. Rien ne quitte l'appareil tant que la connexion n'est pas établie.",
  },
];

// ─────────────────────────────────────────────────────────────
// Écran
// ─────────────────────────────────────────────────────────────
function OnboardingScreen({ accent, onDone }) {
  const [idx, setIdx] = React.useState(0);
  const [drag, setDrag] = React.useState(0);
  const startX = React.useRef(null);
  const width = React.useRef(1);
  const last = OB_SLIDES.length - 1;
  const tint = accent || OB_MED;

  const finish = () => { obWrite(); onDone(); };
  const next = () => (idx === last ? finish() : setIdx(idx + 1));

  // ── Balayage ──
  const onDown = (e) => {
    startX.current = e.clientX;
    width.current = e.currentTarget.getBoundingClientRect().width || 1;
    e.currentTarget.setPointerCapture && e.currentTarget.setPointerCapture(e.pointerId);
  };
  const onMove = (e) => {
    if (startX.current === null) return;
    const dx = e.clientX - startX.current;
    // Résistance aux deux extrémités : on sent le bout de la pile.
    const overshoot = (idx === 0 && dx > 0) || (idx === last && dx < 0);
    setDrag(overshoot ? dx * 0.28 : dx);
  };
  const onUp = () => {
    if (startX.current === null) return;
    const seuil = width.current * 0.18;
    if (drag < -seuil && idx < last) setIdx(idx + 1);
    else if (drag > seuil && idx > 0) setIdx(idx - 1);
    startX.current = null;
    setDrag(0);
  };

  const n = OB_SLIDES.length;
  const dragging = startX.current !== null;

  return (
    <div data-vasco="onboarding" style={{
      // 5 et pas plus : la barre d'état du châssis est à 10 et l'île dynamique
      // à 50. Au-dessus, l'onboarding masquait l'heure et l'encoche. Les
      // écrans de l'app sont à 1-2, donc 5 les couvre bien.
      position: 'absolute', inset: 0, zIndex: 5,
      background: OB_BG, color: OB_INK,
      display: 'flex', flexDirection: 'column',
      paddingTop: 62, paddingBottom: 34,
      fontFamily: "'Inter Tight', -apple-system, system-ui, sans-serif",
      overflow: 'hidden',
    }}>
      {/* Passer */}
      <div style={{ display: 'flex', justifyContent: 'flex-end', padding: '4px 20px 0', flexShrink: 0 }}>
        <button onClick={finish} className="press" style={{
          background: 'none', border: 'none', cursor: 'pointer', padding: '6px 2px',
          fontFamily: 'inherit', fontSize: 13, fontWeight: 600, color: OB_SUB,
          visibility: idx === last ? 'hidden' : 'visible',
        }}>Passer</button>
      </div>

      {/* Piste des écrans */}
      <div
        onPointerDown={onDown}
        onPointerMove={onMove}
        onPointerUp={onUp}
        onPointerCancel={onUp}
        style={{ flex: 1, minHeight: 0, overflow: 'hidden', touchAction: 'pan-y', cursor: 'grab' }}>
        <div style={{
          display: 'flex', height: '100%', width: `${n * 100}%`,
          transform: `translateX(calc(${(-idx * 100) / n}% + ${drag}px))`,
          transition: dragging ? 'none' : 'transform .42s cubic-bezier(.16,1,.3,1)',
        }}>
          {OB_SLIDES.map((s, i) => (
            <div key={s.id} style={{
              width: `${100 / n}%`, flexShrink: 0, height: '100%',
              display: 'flex', flexDirection: 'column',
              alignItems: 'center', justifyContent: 'center',
              padding: '0 34px', gap: 4,
            }}>
              {/* L'illustration est toujours rendue — sinon l'écran voisin
                  serait vide pendant le balayage. Le `key` la remonte quand
                  elle devient active, ce qui rejoue son animation d'entrée
                  pile au moment où elle arrive à l'écran. */}
              <div key={idx === i ? 'live' : 'idle'} style={{
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                height: 210, flexShrink: 0,
              }}>
                {s.art}
              </div>

              <div style={{
                fontSize: 34, fontWeight: 700, letterSpacing: '-1.1px',
                lineHeight: 1.08, color: OB_INK,
                textAlign: 'center', whiteSpace: 'pre-line', marginTop: 10,
              }}>{s.title}</div>

              <div style={{
                fontSize: 14.5, fontWeight: 500, color: OB_SUB,
                lineHeight: 1.5, textAlign: 'center', marginTop: 12,
                maxWidth: 300,
              }}>{s.body}</div>
            </div>
          ))}
        </div>
      </div>

      {/* Progression + action */}
      <div style={{ padding: '0 24px', flexShrink: 0 }}>
        <div style={{
          display: 'flex', justifyContent: 'center', alignItems: 'center', gap: 6,
          marginBottom: 22,
        }}>
          {OB_SLIDES.map((s, i) => (
            <button key={s.id} onClick={() => setIdx(i)} aria-label={`Écran ${i + 1}`} style={{
              // La pastille active s'allonge : la position se lit sans compter.
              width: i === idx ? 22 : 7, height: 7, borderRadius: 999, padding: 0,
              background: i === idx ? tint : OB_HAIR2,
              border: 'none', cursor: 'pointer',
              transition: 'width .3s cubic-bezier(.16,1,.3,1), background .3s ease',
            }} />
          ))}
        </div>

        <button onClick={next} className="press" style={{
          width: '100%', height: OB_VT.hLg || 48, borderRadius: OB_VT.rLg || 16,
          background: OB_INK, border: 'none',
          fontFamily: 'inherit', fontSize: 14, fontWeight: 700, color: '#fff',
          cursor: 'pointer',
          display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
        }}>
          {idx === last ? 'Commencer' : 'Suivant'}
          {idx !== last && (
            <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="#fff"
              strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
              <path d="M9 6l6 6-6 6" />
            </svg>
          )}
        </button>
      </div>

      <style>{`
        @keyframes obHalo {
          0%   { transform: scale(.62); opacity: .5; }
          70%  { transform: scale(1);   opacity: 0;  }
          100% { transform: scale(1);   opacity: 0;  }
        }
        @keyframes obWave {
          0%, 100% { height: 7px; }
          50%      { height: 24px; }
        }
        @keyframes obCardIn {
          from { opacity: 0; transform: translateY(28px) scale(.93); }
          to   { opacity: 1; transform: translateY(0) scale(1); }
        }
        @keyframes obBubble {
          from { opacity: 0; transform: translateY(10px) scale(.96); }
          to   { opacity: 1; transform: translateY(0) scale(1); }
        }
        @keyframes obPop {
          from { opacity: 0; transform: scale(.72); }
          to   { opacity: 1; transform: scale(1); }
        }
        @keyframes obCheck { to { stroke-dashoffset: 0; } }
      `}</style>
    </div>
  );
}

window.OnboardingScreen = OnboardingScreen;
window.vascoOnboardRead = obRead;
window.vascoOnboardClear = obClear;
console.log('%c[VASCO] onboarding.jsx chargé', 'color:#3d6b8f;font-weight:bold');
