// web/upsell.jsx — [UPSELL 2026-06-27] Funnel d'upsell avant règlement.
//   Déclenché quand le client clique « Passer commande » (panier) : on propose, en 3 pages
//   skippables, d'AJOUTER avant de payer :
//     1. une BOISSON (catégorie 10)        — sautée si le panier en a déjà une
//     2. un DESSERT (catégorie 9)          — sautée si le panier en a déjà un
//     3. des SUGGESTIONS (frites / produits populaires) — « et avec ça ? »
//   Chaque ajout = item simple ajouté direct au panier (qty 1). « Non merci » passe à l'étape
//   suivante ; après la dernière → onProceed() (checkout). Si rien à proposer → onProceed direct.
const { useState: upS, useEffect: upE } = React;

function UpsellFlow({ open, cart, onAdd, onProceed, onClose }) {
  const M = (typeof window !== 'undefined' && window.LC && window.LC.menu) || null;
  const fmt = n => (Number(n) || 0).toFixed(2).replace('.', ',') + ' €';

  // Build the steps relevant to THIS cart (skip a category already present).
  const buildSteps = () => {
    if (!M) return [];
    const cats = new Set((cart || []).map(c => c.category_id));
    const steps = [];
    if (!cats.has(10)) steps.push({ id: 'drinks', title: 'Une boisson ?', sub: 'Ajoute une boisson fraîche à ta commande', items: M.itemsForCategory(10) });
    if (!cats.has(9))  steps.push({ id: 'desserts', title: 'Un petit dessert ?', sub: 'Termine sur une note sucrée', items: M.itemsForCategory(9) });
    // Suggestions : seulement des add-ons SIMPLES (frites + featured non-composables).
    // [UPSELL P2 HEAL 2026-06-27] Un produit COMPOSABLE (sandwich/burger/tacos/bol — exige
    // viande/sauce/pain) ajouté ici serait direct-add avec des DÉFAUTS silencieux (1ʳᵉ viande,
    // 1ʳᵉ sauce) que le client n'a jamais choisis (compo imposée + risque allergène). L'upsell
    // sert des add-ons rapides, pas des repas complets qui passent par le wizard. On exclut donc
    // tout item composable, détecté par le wizard_template de sa catégorie (même logique que
    // l'app pour router wizard-vs-direct).
    const COMPOSABLE_TPL = ['sandwich', 'burger', 'tacos', 'bol'];
    const catTemplate = (it) => it.wizard_template
      || ((M.categories || []).find(c => c.id === it.category_id) || {}).wizard_template
      || null;
    const isComposable = (it) => COMPOSABLE_TPL.includes(catTemplate(it));
    const inCart = new Set((cart || []).map(c => c.id));
    const sugg = []
      .concat(M.itemsForCategory(7))                                  // frites — side rapide, direct-add OK
      .concat(M.items.filter(i => i.is_featured && !isComposable(i))) // featured SIMPLES seulement
      .filter(i => !inCart.has(i.id) && !isComposable(i))             // garde dure : jamais un composable
      .slice(0, 6);
    if (sugg.length) steps.push({ id: 'extras', title: 'Et avec ça ?', sub: 'Les incontournables Le Cayenne', items: sugg });
    return steps;
  };

  const [steps, setSteps] = upS([]);
  const [idx, setIdx] = upS(0);
  const [added, setAdded] = upS({}); // visual "ajouté" ticks by item id

  // [UPSELL 2026-06-27] Compute the steps ONCE when the funnel opens (snapshot of the cart at
  // open). Adding items during the upsell must NOT rebuild/reset the flow — so we depend on
  // [open] only, not cart.length (which would reset idx to 0 on every add).
  upE(() => {
    if (!open) return;
    const s = buildSteps();
    setSteps(s); setIdx(0); setAdded({});
    if (s.length === 0) { onProceed(); } // nothing to upsell → straight to checkout
  }, [open]);

  if (!open || steps.length === 0) return null;
  const safeIdx = Math.min(idx, steps.length - 1);
  const step = steps[safeIdx];
  const last = safeIdx === steps.length - 1;

  const addItem = (it) => {
    // [HEAL 2026-07-19] Garde anti-doublon : une fois ajouté (added[it.id] → « ✓ Ajouté »), un re-tap
    // NE doit PAS rappeler onAdd — sinon chaque clic empile une 2ᵉ ligne panier = payé ×2 au double-tap.
    if (added[it.id]) return;
    // Simple items (drinks/desserts/frites base) → add unit directly. The App's onAdd multiplies
    // qty; we pass the unit price so the cart line is correct (mirrors DirectAddView contract).
    onAdd({ ...it, price: it.price, qty: 1 });
    setAdded(a => ({ ...a, [it.id]: true }));
  };
  const next = () => { if (last) onProceed(); else setIdx(i => i + 1); };

  return (
    <WebModal open={open} onClose={onClose} full label="Compléter ta commande">
      <div className="lc-wiz">
        <div className="lc-wiz-main">
          <div className="lc-wiz-header">
            <div role="status" aria-live="polite">
              <div className="lc-wiz-eyebrow"><b>{safeIdx + 1}</b> / {steps.length} · AVANT DE PAYER</div>
              <h2 className="lc-wiz-title">{step.title}</h2>
            </div>
            <div className="lc-wiz-sub">{step.sub}</div>
            <div className="lc-wiz-progress">
              {steps.map((_, i) => <span key={i} className={i < safeIdx ? 'done' : i === safeIdx ? 'current' : ''}/>)}
            </div>
          </div>
          <div className="lc-wiz-body">
            <div className="lc-wiz-options" style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(150px, 1fr))', gap: 12 }}>
              {step.items.map(it => (
                <button key={it.id} className={'lc-wiz-choice' + (added[it.id] ? ' is-on' : '')} onClick={() => addItem(it)} style={{ position: 'relative', flexDirection: 'column', alignItems: 'stretch', textAlign: 'left' }}>
                  <div className="lc-wiz-choice-thumb" style={{ width: '100%', height: 88, marginBottom: 8 }}>
                    {it.image
                      ? <img src={it.image} alt="" loading="lazy" style={{ width: '100%', height: '100%', objectFit: 'contain', borderRadius: 'inherit' }} onError={(e) => { e.currentTarget.style.display = 'none'; const s = e.currentTarget.nextElementSibling; if (s) s.style.display = 'flex'; }}/>
                      : null}
                    <span style={{ display: it.image ? 'none' : 'flex', alignItems: 'center', justifyContent: 'center', width: '100%', height: '100%', fontSize: 36 }}>{it.emoji || '🍽'}</span>
                  </div>
                  <div className="lc-wiz-choice-body">
                    <div className="lc-wiz-choice-name">{it.name}</div>
                  </div>
                  <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: 6 }}>
                    <span className="lc-wiz-choice-price" style={{ position: 'static' }}>{fmt(it.price)}</span>
                    <span style={{ fontSize: 12, fontWeight: 700, color: added[it.id] ? 'var(--green-text)' : 'var(--orange-text)' }}>{added[it.id] ? '✓ Ajouté' : '+ Ajouter'}</span>
                  </div>
                </button>
              ))}
            </div>
          </div>
          <div className="lc-wiz-footer">
            <div className="lc-wiz-footer-left">
              <button className="lc-wiz-foot-back" aria-label="Étape précédente" onClick={() => safeIdx > 0 ? setIdx(i => i - 1) : onProceed()}><WC_I.back s={14}/></button>
              <button onClick={next} style={{ background: 'transparent', border: 0, color: 'var(--gray-3)', fontSize: 13, fontWeight: 700, cursor: 'pointer' }}>Non merci</button>
            </div>
            <button className="lc-wiz-foot-next" style={{ background: 'var(--orange)' }} onClick={next}>
              {last ? 'Régler ma commande' : 'Continuer'} <WC_I.arrow s={16}/>
            </button>
          </div>
        </div>
      </div>
    </WebModal>
  );
}

window.UpsellFlow = UpsellFlow;
