/* ============================================================
   RIVA — Écran de composition d'un plat

   S'ouvre quand un plat demande des choix (viande, accompagnement,
   boisson, composition d'une pizza ou d'un panuozzo…) ou quand c'est une signature.
   Les groupes de choix viennent directement de  carte.js  :

     options: [
       { id:'viande', titre:'Votre choix', min:1, max:1, choix:[...] },
       { id:'boisson', titre:'Boisson 33 cl', min:0, max:1, prix:1, choix:[...] },
     ]

   min : nombre de choix obligatoires   max : nombre de choix autorisés
   prix : supplément par choix coché (absent = compris dans le prix)
   ============================================================ */

const { useState: useCo, useEffect: useCoE, useMemo: useCoM, useRef: useCoR } = React;

/* Ce qu'on propose en « Et avec ça ? » sous le plat choisi. Chez Riva, les
   bouchées à partager et les boissons — pas les entrées d'un autre restaurant. */
const SUGGESTIONS_CATS = ['bouchees', 'fraicheurs'];

/* Le plat ouvre-t-il l'écran de composition ? */
function shouldUpsell(item) {
  if (item?.options && item.options.length) return true;        // des choix à faire
  return !!(item?.badges && item.badges.includes('signature')); // ou une signature
}

function ComposerModal({ open, item, onClose, onConfirm }) {
  const [choix, setChoix] = useCo({});      // { idGroupe: [choix retenus] }
  const [qte, setQte] = useCo(1);
  const [extras, setExtras] = useCo({});    // { idPlat: quantité }

  useCoE(() => {
    if (!open || !item) return;
    const depart = {};
    (item.options || []).forEach(g => { depart[g.id] = []; });
    setChoix(depart);
    setQte(1);
    setExtras({});
  }, [open, item?.id]);

  useCoE(() => {
    document.body.style.overflow = open ? 'hidden' : '';
    return () => { document.body.style.overflow = ''; };
  }, [open]);

  const { menu: menuEffectif } = getEffectiveMenu();
  const tousLesPlats = useCoM(
    () => Object.values(menuEffectif).flatMap(c => c.items),
    [menuEffectif]
  );
  const trouverPlat = (id) => tousLesPlats.find(i => i.id === id);

  const suggestions = useCoM(() => {
    const liste = [];
    SUGGESTIONS_CATS.forEach(catId => {
      (menuEffectif[catId]?.items || []).forEach(i => { if (i.id !== item?.id && !i.rupture) liste.push(i); });
    });
    return liste.slice(0, 6);
  }, [menuEffectif, item?.id]);

  if (!open || !item) return null;

  const groupes = item.options || [];

  // Supplément dû aux choix payants (ex : boisson +1 €, protéine en plus +2 €)
  const supplements = groupes.reduce((somme, g) => {
    if (!g.prix) return somme;
    return somme + g.prix * (choix[g.id]?.length || 0);
  }, 0);

  const prixUnitaire = item.price + supplements;

  /* L'aperçu ne s'affiche que là où il a un sens : un plat qu'on garnit
     vraiment, pas une canette qui demande juste son parfum. */
  const composable = groupes.length >= 4;
  const forme = /pizza/i.test(item.catId || '') ? 'pizza' : 'panuozzo';

  /* Pas de useMemo ici : on est APRÈS le `return null` du modal fermé, et un
     hook posé après un retour conditionnel change le nombre de hooks d'un
     rendu à l'autre — React refuse et la page devient blanche. Le calcul est
     de toute façon négligeable : quelques dizaines d'entrées. */
  const ingredientsChoisis = [];
  groupes.forEach(g => {
    // La sauce colore le fond (texteBase) et la taille ne se dessine pas :
    // ni l'une ni l'autre ne se pose en morceaux sur la pizza.
    if (g.id === 'sauce' || g.id === 'taille') return;
    (choix[g.id] || []).forEach(v => {
      if (!ingredientsChoisis.some(o => o.nom === v)) {
        ingredientsChoisis.push({
          nom: v,
          couleur: typeof couleurIngredient === 'function' ? couleurIngredient(v) : '#C9A54E',
        });
      }
    });
  });


  const totalExtras = Object.entries(extras).reduce((somme, [id, q]) => {
    const plat = trouverPlat(id);
    return somme + (plat ? plat.price * q : 0);
  }, 0);

  const total = prixUnitaire * qte + totalExtras;

  const choixComplets = groupes.every(g => (choix[g.id]?.length || 0) >= (g.min || 0));

  const basculer = (groupe, valeur) => {
    setChoix(prev => {
      const actuels = prev[groupe.id] || [];
      const index = actuels.indexOf(valeur);
      let suivants;
      if (index >= 0) suivants = actuels.filter(v => v !== valeur);
      else if (actuels.length < groupe.max) suivants = [...actuels, valeur];
      else if (groupe.max === 1) suivants = [valeur];          // choix unique : on remplace
      else suivants = actuels;                                  // plein : on ignore
      return { ...prev, [groupe.id]: suivants };
    });
  };

  const ajusterExtra = (id, delta) => {
    setExtras(prev => {
      const suivant = { ...prev };
      const q = (suivant[id] || 0) + delta;
      if (q <= 0) delete suivant[id]; else suivant[id] = q;
      return suivant;
    });
  };

  const valider = () => {
    // On met les choix à plat pour le panier, l'écran de caisse et le ticket
    const detail = {};
    groupes.forEach(g => {
      const retenus = choix[g.id] || [];
      if (retenus.length) detail[g.titre.split('—')[0].trim()] = retenus.join(', ');
    });

    const lignes = [{
      id: item.id + (Object.keys(detail).length ? '-' + Date.now() : ''),
      name: item.name,
      price: prixUnitaire,
      img: item.img,
      teinte: item.teinte,
      catLabel: item.catLabel,
      qty: qte,
      options: Object.keys(detail).length ? detail : undefined,
    }];

    Object.entries(extras).forEach(([id, q]) => {
      const plat = trouverPlat(id);
      if (plat) lignes.push({ id: plat.id, name: plat.name, price: plat.price, img: plat.img, teinte: plat.teinte, catLabel: plat.catLabel, qty: q });
    });

    onConfirm(lignes);
  };

  const passer = () => {
    onConfirm([{ id: item.id, name: item.name, price: item.price, img: item.img, teinte: item.teinte, catLabel: item.catLabel, qty: 1 }]);
  };

  return (
    <div className="fixed inset-0 z-[195] voile-fonce backdrop-blur-sm flex items-end md:items-center justify-center md:p-4" onClick={onClose}>
      <div onClick={(e) => e.stopPropagation()}
           className="w-full max-w-[560px] bg-[var(--bg-2)] rounded-t-3xl md:rounded-3xl border border-[var(--line)] flex flex-col overflow-hidden"
           style={{ maxHeight: '92vh' }}>

        {/* Le plat */}
        <div className="relative shrink-0">
          <PlatVisuel item={item} className="aspect-[16/8] relative">
            <div className="absolute inset-0 bg-gradient-to-t from-[var(--bg-2)] via-[var(--bg-2)]/40 to-transparent"/>
            <button onClick={onClose} aria-label="Fermer"
                    className="absolute top-3 right-3 w-10 h-10 rounded-full bg-black/60 backdrop-blur text-white flex items-center justify-center">
              <Icon.Close className="w-5 h-5"/>
            </button>
          </PlatVisuel>
          <div className="absolute -bottom-2 left-5 right-5">
            <div className="font-hand text-[var(--vert)] text-xl leading-none">{item.tagline || item.catLabel}</div>
            <h3 className="font-display text-4xl text-[var(--cream)]">{item.name}</h3>
          </div>
        </div>

        {/* Les choix */}
        <div className="flex-1 overflow-y-auto px-5 pt-8 pb-4 space-y-5">
          {item.desc && (
            <p className="text-sm text-[var(--cream-2)]/80 leading-relaxed">{item.desc}</p>
          )}

          {composable && (
            <Composition
              forme={forme}
              /* Ce que le plat porte DÉJÀ : la Margherita arrive avec sa
                 tomate, sa mozzarella et son basilic. Sans ça, on ouvrirait
                 l'écran sur une pizza nue, ce qui est faux. */
              base={(item.desc || '').split('•').map(s => s.trim()).filter(Boolean)}
              ingredients={ingredientsChoisis}
              texteBase={(item.desc || '') + ' ' + (choix.sauce || []).join(' ')}/>
          )}

          {groupes.map(groupe => {
            const retenus = choix[groupe.id] || [];
            const plein = retenus.length >= groupe.max;
            const manque = (groupe.min || 0) - retenus.length;
            return (
              <div key={groupe.id}>
                <div className="flex items-baseline justify-between gap-3 mb-3">
                  <div className="kicker !mb-0">{groupe.titre}</div>
                  <div className={`text-[11px] font-bold uppercase tracking-wider ${manque > 0 ? 'text-[var(--rouge-2)]' : 'text-[var(--muted)]'}`}>
                    {manque > 0
                      ? `${retenus.length}/${groupe.min} requis`
                      : groupe.prix
                        ? `+${groupe.prix.toFixed(2)}€ l'unité`
                        : groupe.max > 1 ? `${retenus.length}/${groupe.max}` : 'facultatif'}
                  </div>
                </div>
                <div className="flex flex-wrap gap-1.5">
                  {groupe.choix.map(valeur => {
                    const picto = typeof illustrationIngredient === 'function' ? illustrationIngredient(valeur) : null;
                    const actif = retenus.includes(valeur);
                    const bloque = !actif && plein && groupe.max > 1;
                    return (
                      <button key={valeur} onClick={() => basculer(groupe, valeur)}
                              disabled={bloque}
                              aria-pressed={actif}
                              className={`inline-flex items-center gap-1.5 text-sm px-3.5 py-2 rounded-full border transition-all
                                ${actif
                                  ? 'border-[var(--vert)] bg-[var(--vert)]/15 text-[var(--cream)] font-semibold'
                                  : bloque
                                    ? 'border-[var(--line)] text-[var(--muted)]/40 cursor-not-allowed'
                                    : 'border-[var(--line)] text-[var(--cream-2)] hover:border-[var(--cream)]/30'}`}>
                        {actif && <span className="text-[var(--vert)]">✓</span>}
                        {picto && <img src={picto} alt="" aria-hidden="true" className="w-6 h-6 shrink-0"/>}
                        {valeur}
                        {groupe.prix ? <span className="text-[var(--vert)] text-xs ml-1.5">+{groupe.prix.toFixed(2)}€</span> : null}
                      </button>
                    );
                  })}
                </div>
              </div>
            );
          })}

          {/* Quantité */}
          <div>
            <div className="kicker mb-3">Quantité</div>
            <div className="flex items-center gap-4">
              <div className="qty">
                <button onClick={() => setQte(q => Math.max(1, q - 1))} aria-label="Retirer">−</button>
                <span className="v">{qte}</span>
                <button onClick={() => setQte(q => Math.min(30, q + 1))} aria-label="Ajouter">+</button>
              </div>
              <span className="text-sm text-[var(--muted)]">{prixUnitaire.toFixed(2)}€ l'unité</span>
            </div>
          </div>

          {/* Et avec ça ? */}
          {suggestions.length > 0 && (
            <div>
              <div className="kicker mb-3">Et avec ça ?</div>
              <div className="space-y-2">
                {suggestions.map(plat => (
                  <ExtraLigne
                    key={plat.id}
                    item={plat}
                    qty={extras[plat.id] || 0}
                    onAdd={() => ajusterExtra(plat.id, 1)}
                    onRemove={() => ajusterExtra(plat.id, -1)}
                  />
                ))}
              </div>
            </div>
          )}
        </div>

        {/* Total et validation */}
        <div className="shrink-0 border-t border-[var(--line)] bg-[var(--bg)] p-4">
          <div className="flex items-center justify-between mb-3">
            <div className="text-xs text-[var(--muted)] uppercase tracking-wider font-bold">Total</div>
            <div className="font-display text-3xl text-[var(--vert)]">{total.toFixed(2)}€</div>
          </div>
          <div className="flex gap-2">
            {groupes.length === 0 && (
              <button onClick={passer} className="btn btn-ghost !py-3 !px-4 !text-xs flex-1">
                Juste le plat
              </button>
            )}
            <button onClick={valider} disabled={!choixComplets}
                    className="btn btn-primary !py-3 !px-5 flex-[2] disabled:opacity-40 disabled:cursor-not-allowed">
              {choixComplets ? `Ajouter · ${total.toFixed(2)}€` : 'Faites vos choix'}
              <Icon.ArrowRight className="w-4 h-4"/>
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

function ExtraLigne({ item, qty, onAdd, onRemove }) {
  return (
    <div className="flex items-center gap-3 bg-[var(--bg)] rounded-xl p-2.5 border border-[var(--line)]">
      <PlatVisuel item={item} className="w-14 h-14 rounded-lg shrink-0 overflow-hidden"/>
      <div className="flex-1 min-w-0">
        <div className="font-semibold text-sm leading-tight">{item.name}</div>
        <div className="text-xs text-[var(--vert)] mt-0.5 font-bold">{item.price.toFixed(2)}€</div>
      </div>
      {qty > 0 ? (
        <div className="qty shrink-0">
          <button onClick={onRemove} aria-label="Retirer">−</button>
          <span className="v">{qty}</span>
          <button onClick={onAdd} aria-label="Ajouter">+</button>
        </div>
      ) : (
        <button onClick={onAdd} aria-label={`Ajouter ${item.name}`} className="btn btn-primary !py-2 !px-3 !text-xs shrink-0">
          <Icon.Plus className="w-4 h-4"/>
        </button>
      )}
    </div>
  );
}

Object.assign(window, { ComposerModal, ExtraLigne, shouldUpsell });
