// web/flows.jsx — Account creation flow, Item wizard, Cart drawer

const { useState: wfS, useEffect: wfE, useRef: wfR } = React;

// ============================================================
// CART DRAWER
// ============================================================
function CartDrawer({ open, onClose, cart, setCart, onCheckout, unavail }) {
  // [ULTRA-AUDIT 2026-07-19 P2] Le 86/rupture n'était propagé qu'à la carte du menu, pas au panier :
  // un article qui passait en rupture pendant l'hésitation restait commandable jusqu'au paiement.
  // On le grise ici + on bloque « Passer commande » (la garde backend reste le rempart dur).
  const isSoldOut = (it) => !!(unavail && it && unavail[it.id]);
  const [slot, setSlot] = wfS('asap');
  const [promo, setPromo] = wfS('');
  const [notes, setNotes] = wfS('');
  // [T1-07 HEAL 2026-06-05 WCAG 2.1.2/2.4.3/4.1.2] The drawer is a translateX-hidden <div>:
  // when CLOSED its controls stayed in the tab order (keyboard ghost-focus), and when OPEN
  // it had no dialog semantics. We now: (1) mark the panel `inert` while closed so its
  // controls leave the tab order — React 18.3.1 has no `inert` JSX prop so we set the DOM
  // property imperatively; (2) add role=dialog/aria-modal + Escape-to-close; (3) move focus
  // into the panel on open and restore it to the opener on close.
  const panelRef = wfR(null);
  const openerRef = wfR(null);
  wfE(() => {
    const node = panelRef.current;
    if (node) node.inert = !open;
  }, [open]);
  wfE(() => {
    if (!open) return;
    openerRef.current = document.activeElement;
    const node = panelRef.current;
    if (node) {
      const focusable = node.querySelector('a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])');
      (focusable || node).focus();
    }
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('keydown', onKey);
    return () => {
      document.removeEventListener('keydown', onKey);
      const opener = openerRef.current;
      if (opener && typeof opener.focus === 'function') opener.focus();
    };
  }, [open]);
  const subtotal = cart.reduce((s, i) => s + i.price * i.qty, 0);
  // [PROMO-SSOT 2026-07-07] No client-side discount here. The cart drawer used to invent a
  // −10% (subtotal*0.1) shown up to payment while the REAL order (couponId null) was billed at
  // full price → "affiché ≠ facturé". Now the cart only CAPTURES the typed code and forwards it;
  // CheckoutPage.applyPromo (api.checkCoupon → backend) is the single source of ctx.discount +
  // ctx.couponId, so any discount is backend-revalidated before it is ever displayed.
  const total = subtotal;
  const updateQty = (idx, d) => setCart(c => c.map((it, i) => i === idx ? { ...it, qty: Math.max(1, it.qty + d) } : it));
  const remove = (idx) => setCart(c => c.filter((_, i) => i !== idx));
  // [OWNER 2026-07-19] Créneaux « au-delà de dès que prêt » RETIRÉS ici AUSSI (le panier avait son propre
  // sélecteur, cohérent maintenant avec le funnel). Le backend ne planifie pas (is_advance_order=0) →
  // « Dans 20/40 min » + heure absolue laissait croire à une planification jamais honorée (cuisine faite
  // tout de suite). V1 mono-resto = retrait IMMÉDIAT uniquement. (fmtAt supprimé, devenu inutile.)
  const slots = [
    { id: 'asap',  l: 'Dès que possible', sub: '~12 min' },
  ];
  return (
    <>
      {open && <div onClick={onClose} style={{ position: 'fixed', inset: 0, background: 'rgba(10,10,10,0.4)', zIndex: 69, animation: 'lc-fade-in var(--dur-base) var(--ease-spring)' }}/>}
      <div ref={panelRef} tabIndex={-1} role="dialog" aria-modal="true" aria-label="Panier" className={'lc-cart-drawer' + (open?' is-open':'')}>
        <div className="lc-cart-head">
          <div className="lc-cart-title">Panier</div>
          {/* [Z-7 HEAL 2026-05-18 axe-P0] button-name: aria-label for close icon button */}
          <button onClick={onClose} className="lc-acc-form-back" style={{ margin: 0 }} aria-label="Fermer le panier"><WC_I.close s={16}/></button>
        </div>
        <div className="lc-cart-body">
          {cart.length === 0 ? (
            <div style={{ textAlign: 'center', padding: '40px 0' }}>
              <div style={{ fontSize: 48 }}>🛒</div>
              <div style={{ fontWeight: 700, marginTop: 12 }}>Ton panier est vide</div>
              <div style={{ fontSize: 12, color: 'var(--gray-3)', marginTop: 4 }}>Faim ? Va voir le menu.</div>
            </div>
          ) : cart.map((it, idx) => (
            <div key={idx} className="lc-cart-row">
              <div className="lc-cart-row-thumb">
                {it.image && <img src={it.image} alt="" style={{ width: '100%', height: '100%', objectFit: 'contain' }} onError={(e) => { e.currentTarget.style.display = 'none'; const s = e.currentTarget.nextElementSibling; if (s) s.style.display = 'flex'; }}/>}
                <span style={{ display: it.image ? 'none' : 'flex', alignItems: 'center', justifyContent: 'center', width: '100%', height: '100%' }}>{it.emoji}</span>
              </div>
              <div className="lc-cart-row-body">
                <div className="lc-cart-row-name" style={isSoldOut(it) ? { opacity: 0.55 } : null}>{it.name}{isSoldOut(it) && <span style={{ marginLeft: 8, fontSize: 10, fontWeight: 800, color: 'var(--red-text, #C2410C)', background: 'rgba(194,65,12,.12)', padding: '1px 6px', borderRadius: 6, letterSpacing: '.04em' }}>ÉPUISÉ</span>}</div>
                {it.subs && <div className="lc-cart-row-meta">+ {it.subs}</div>}
                <div className="lc-cart-stepper">
                  {/* [Z-7 HEAL 2026-05-18 P2-3] aria-label so screen reader announces qty action */}
                  <button onClick={()=>updateQty(idx, -1)} aria-label={`Diminuer la quantité de ${it.name}`}>−</button>
                  <b>{it.qty}</b>
                  <button onClick={()=>updateQty(idx, +1)} aria-label={`Augmenter la quantité de ${it.name}`}>+</button>
                </div>
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 8 }}>
                <span className="lc-cart-row-price">{(it.price*it.qty).toFixed(2).replace('.', ',')} €</span>
                {/* [Z-7 HEAL 2026-05-18 axe-P0] button-name: aria-label for trash icon button */}
                <button onClick={()=>remove(idx)} style={{ background: 'transparent', border: 0, color: 'var(--gray-3)' }} aria-label={`Retirer ${it.name} du panier`}><WC_I.trash/></button>
              </div>
            </div>
          ))}
        </div>
        {cart.length > 0 && (
          <div style={{ padding: '0 24px' }}>
            <div className="lc-cart-section">
              <h5>// Quand récupérer ?</h5>
              <div className="lc-time-slots">
                {slots.map(s => (
                  <button key={s.id} onClick={()=>setSlot(s.id)} className={'lc-time-slot' + (slot===s.id?' is-on':'')}>
                    <div style={{ fontSize: 11, opacity: 0.7 }}>{s.l}</div>
                    <div style={{ marginTop: 2 }}>{s.sub}</div>
                  </button>
                ))}
              </div>
            </div>
            <div className="lc-cart-section">
              <h5>// Code promo</h5>
              <div className="lc-promo">
                <input value={promo} onChange={e=>setPromo(e.target.value)} placeholder="Ex: CAYENNE10" aria-label="Code promo"/>
              </div>
              {/* [PROMO-SSOT 2026-07-07] Le code est vérifié + chiffré par le backend à l'étape
                  paiement (aucune remise « fantôme » affichée avant validation serveur). */}
              {promo.trim() && <div style={{ marginTop: 8, fontSize: 12, color: 'var(--gray-3)', fontWeight: 600 }} role="status" aria-live="polite">Ton code sera vérifié et appliqué à l'étape paiement.</div>}
            </div>
            <div className="lc-cart-section">
              <h5>// Note pour la cuisine</h5>
              {/* [FULL-FLOW HEAL 2026-05-18 P1-1] 190 char limit aligned mobile spec */}
              <textarea className="lc-notes" value={notes} onChange={e=>setNotes(e.target.value.slice(0, 190))} placeholder="Une précision ? Sauce à part, sans oignon…" maxLength={190} aria-label="Note pour la cuisine" aria-describedby="cart-notes-counter"/>
              <div id="cart-notes-counter" aria-live="polite" style={{ fontSize: 10, color: 'var(--gray-3)', textAlign: 'right', marginTop: 2 }}>{notes.length} / 190</div>
            </div>
          </div>
        )}
        {cart.length > 0 && (
          <div className="lc-cart-foot">
            <div className="lc-cart-totals">
              <div className="lc-cart-totals-row"><span>Sous-total</span><span>{subtotal.toFixed(2).replace('.', ',')} €</span></div>
              {/* [PROMO-SSOT 2026-07-07] La remise éventuelle s'affiche au checkout après validation backend. */}
              {/* [GOAL-SYNC 2026-07-08] Estimation earn = Math.floor(total × config) via LC.loyalty.earnPoints (parité backend, plus de Math.round hardcodé). */}
              <div className="lc-cart-totals-row"><span>+ Fidélité</span><span style={{ color: 'var(--green-text)', fontWeight: 700 }}>+{(window.LC && window.LC.loyalty && window.LC.loyalty.earnPoints) ? window.LC.loyalty.earnPoints(total) : Math.floor(total)} pts</span></div>
              <div className="lc-cart-totals-row is-total"><span>Total</span><b>{total.toFixed(2).replace('.', ',')} €</b></div>
            </div>
            {/* [TERRAIN-HEAL 2026-07-16 · WEB-CART-DEADFIELDS] La note cuisine + le créneau saisis dans le
                panier étaient jetés (onCheckout ne passait QUE le promo) → allergie/instruction perdue en
                silence (« mensonge visuel »). On les propage à ctx : le checkout les pré-remplit (même
                binding ctx.notes/ctx.slot) et placeOrder transmet la note. */}
            {cart.some(isSoldOut) && (
              <div role="alert" style={{ marginBottom: 10, fontSize: 12, color: 'var(--red-text, #C2410C)', fontWeight: 700, textAlign: 'center' }}>Un article de ton panier est épuisé — retire-le pour continuer.</div>
            )}
            <button className="lc-btn lc-btn--orange" style={{ width: '100%', opacity: cart.some(isSoldOut) ? 0.5 : 1 }} disabled={cart.some(isSoldOut)} onClick={()=>{ if (cart.some(isSoldOut)) return; onCheckout(promo.trim() ? promo.trim().toUpperCase() : null, notes.trim() || null, slot); }}>
              Passer commande <WC_I.arrow s={16}/>
            </button>
            <div style={{ marginTop: 10, textAlign: 'center', fontSize: 11, color: 'var(--gray-3)' }}>Retrait sur place · Hénin-Beaumont 62110</div>
          </div>
        )}
      </div>
    </>
  );
}

// [GOAL LONG-TERM 2026-05-16] Dead AccountFlow + WizardFlow + W_WIZ removed (superseded by account-v2.jsx + wizard-v2.jsx)
window.CartDrawer = CartDrawer;
