// ── Gericht-Karte ────────────────────────────────────────────────────────────
function DishCard({ dish, onOpen }) {
  return (
    <button
      onClick={() => onOpen(dish)}
      className="group text-left bg-card border border-line rounded-xl2 overflow-hidden flex flex-col hover:-translate-y-1 hover:shadow-xl hover:shadow-black/[0.07] transition-all duration-300 reveal"
    >
      <div className="relative">
        <FoodPlaceholder tone={dish.tone} label={dish.name} rounded="rounded-none" className="aspect-[5/4] w-full" />
        <span className="absolute top-3 right-3 z-10 inline-flex items-center justify-center w-10 h-10 rounded-full bg-paper/90 text-ink shadow-md group-hover:bg-terra group-hover:text-white transition-colors">
          <Ico.plus className="w-5 h-5" />
        </span>
      </div>
      <div className="p-5 flex flex-col flex-1">
        <div className="flex items-baseline justify-between gap-3">
          <h3 className="font-serif text-[21px] leading-snug text-ink group-hover:text-terra transition-colors">{dish.name}</h3>
          <span className="font-mono text-[14px] text-ink whitespace-nowrap tabular-nums">{dish.price.toFixed(2)}</span>
        </div>
        <p className="mt-2 text-[14.5px] leading-relaxed text-muted flex-1">{dish.desc}</p>
        <div className="mt-4 flex items-center gap-2 flex-wrap">
          {dish.tags.map((t) => <DietBadge key={t} tag={t} />)}
          <span className="ml-auto"><AllergenList codes={dish.allergens} /></span>
        </div>
      </div>
    </button>
  );
}

// ── Speisekarte ──────────────────────────────────────────────────────────────
function Menu({ onOpen }) {
  const [active, setActive] = React.useState(CATEGORIES[0].id);
  const navRef = React.useRef(null);

  // Spy: welche Kategorie ist im Blick
  React.useEffect(() => {
    const secs = CATEGORIES.map((c) => document.getElementById("cat-" + c.id)).filter(Boolean);
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((en) => {
          if (en.isIntersecting) setActive(en.target.id.replace("cat-", ""));
        });
      },
      { rootMargin: "-45% 0px -50% 0px", threshold: 0 }
    );
    secs.forEach((s) => io.observe(s));
    return () => io.disconnect();
  }, []);

  const go = (id) => {
    const el = document.getElementById("cat-" + id);
    if (el) {
      const y = el.getBoundingClientRect().top + window.scrollY - 132;
      window.scrollTo({ top: y, behavior: "smooth" });
    }
  };

  return (
    <section id="menu" className="py-20 sm:py-28">
      <div className="mx-auto max-w-[1240px] px-5 sm:px-8">
        <div className="reveal max-w-3xl">
          <SectionHead kicker="La Carta" title="Unsere Speisekarte"
            sub="Alles frisch zubereitet — auch zum Mitnehmen. Tippe ein Gericht an, um es in den Warenkorb zu legen." />
        </div>
      </div>

      {/* Sticky Kategorie-Nav */}
      <div className="sticky top-[68px] z-30 bg-paper/85 backdrop-blur-md border-y border-line mt-10">
        <div ref={navRef} className="mx-auto max-w-[1240px] px-5 sm:px-8 flex gap-2 overflow-x-auto no-sb py-3">
          {CATEGORIES.map((c) => (
            <button key={c.id} onClick={() => go(c.id)}
              className={cx("shrink-0 px-4 h-10 rounded-full text-[14px] font-medium transition-colors whitespace-nowrap",
                active === c.id ? "bg-ink text-paper" : "text-ink/70 hover:bg-ink/5")}>
              {c.label}
            </button>
          ))}
        </div>
      </div>

      <div className="mx-auto max-w-[1240px] px-5 sm:px-8 mt-14 space-y-20">
        {CATEGORIES.map((c) => {
          const items = MENU.filter((m) => m.cat === c.id);
          return (
            <div key={c.id} id={"cat-" + c.id} className="scroll-mt-32">
              <div className="flex items-end gap-4 mb-3">
                <div>
                  <div className="font-mono text-xs uppercase tracking-[0.2em] text-terra mb-2">{c.kicker}</div>
                  <h3 className="font-serif text-[clamp(1.8rem,4vw,2.6rem)] leading-none text-ink">{c.label}</h3>
                </div>
                <div className="flex-1 border-b border-line mb-2" />
                <span className="font-mono text-xs text-muted mb-2">{items.length} Gerichte</span>
              </div>
              {c.note && <p className="text-[15px] leading-relaxed text-muted max-w-2xl mb-7">{c.note}</p>}
              {!c.note && <div className="mb-5" />}
              <div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
                {items.map((d) => <DishCard key={d.id} dish={d} onOpen={onOpen} />)}
              </div>
            </div>
          );
        })}
      </div>

      {/* Allergen-Legende */}
      <div className="mx-auto max-w-[1240px] px-5 sm:px-8 mt-16">
        <div className="bg-card border border-line rounded-xl2 p-6">
          <div className="font-mono text-[11px] uppercase tracking-widest text-muted mb-3">Allergene</div>
          <div className="flex flex-wrap gap-x-5 gap-y-1.5 text-[13px] text-muted">
            {Object.entries(ALLERGENS).map(([k, v]) => (
              <span key={k}><strong className="font-mono text-ink">{k}</strong> {v}</span>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

// ── Gericht-Modal (Menge + Varianten) ────────────────────────────────────────
function DishModal({ dish, onClose, onAdd }) {
  const opts = dish.options || [];
  const [sel, setSel] = React.useState(() => {
    const init = {};
    opts.forEach((o) => { init[o.id] = o.choices[0].id; });
    return init;
  });
  const [qty, setQty] = React.useState(1);
  const [note, setNote] = React.useState("");

  const deltaSum = opts.reduce((s, o) => {
    const ch = o.choices.find((c) => c.id === sel[o.id]);
    return s + (ch ? ch.delta : 0);
  }, 0);
  const unit = dish.price + deltaSum;
  const total = unit * qty;

  // Esc schliesst
  React.useEffect(() => {
    const on = (e) => e.key === "Escape" && onClose();
    document.addEventListener("keydown", on);
    document.body.style.overflow = "hidden";
    return () => { document.removeEventListener("keydown", on); document.body.style.overflow = ""; };
  }, []);

  const add = () => {
    const chosen = opts.map((o) => ({ label: o.label, value: o.choices.find((c) => c.id === sel[o.id]).label }));
    onAdd({
      key: dish.id + "|" + Object.values(sel).join("-") + "|" + note.trim(),
      id: dish.id, name: dish.name, tone: dish.tone,
      unit, qty, options: chosen, note: note.trim(),
    });
    onClose();
  };

  return (
    <div className="fixed inset-0 z-[60] flex sm:items-center justify-center anim-fade" role="dialog" aria-modal="true" aria-label={dish.name}>
      <div className="absolute inset-0 bg-ink/55 backdrop-blur-sm" onClick={onClose} />
      <div className="relative w-full sm:max-w-lg bg-paper sm:rounded-xl2 overflow-hidden mt-auto sm:mt-0 max-h-[94vh] flex flex-col anim-sheet shadow-2xl">
        <div className="relative shrink-0">
          <FoodPlaceholder tone={dish.tone} label={dish.name} rounded="rounded-none" className="h-44 sm:h-52 w-full" />
          <button onClick={onClose} className="absolute top-3 right-3 w-11 h-11 grid place-items-center rounded-full bg-paper/90 text-ink hover:bg-paper shadow-md" aria-label="Schliessen">
            <Ico.close className="w-6 h-6" />
          </button>
        </div>

        <div className="p-6 overflow-y-auto">
          <div className="flex items-start justify-between gap-4">
            <h3 className="font-serif text-[28px] leading-tight text-ink">{dish.name}</h3>
            <span className="font-mono text-[15px] text-muted whitespace-nowrap mt-1.5">{CHF(dish.price)}</span>
          </div>
          <p className="mt-3 text-[15.5px] leading-relaxed text-muted">{dish.desc}</p>
          <div className="mt-4 flex items-center gap-2 flex-wrap">
            {dish.tags.map((t) => <DietBadge key={t} tag={t} />)}
            {dish.allergens.length > 0 && <span className="text-[13px] text-muted">Allergene: <AllergenList codes={dish.allergens} /></span>}
          </div>

          {/* Optionen */}
          {opts.map((o) => (
            <div key={o.id} className="mt-6">
              <div className="font-medium text-[15px] text-ink mb-2.5">{o.label}{o.required && <span className="text-muted font-normal"> · Pflicht</span>}</div>
              <div className="grid gap-2">
                {o.choices.map((c) => {
                  const on = sel[o.id] === c.id;
                  return (
                    <button key={c.id} onClick={() => setSel((s) => ({ ...s, [o.id]: c.id }))}
                      className={cx("flex items-center justify-between gap-3 h-12 px-4 rounded-xl border text-[15px] transition-colors",
                        on ? "border-terra bg-terra/8 text-ink" : "border-line bg-card text-ink/80 hover:border-ink/25")}>
                      <span className="flex items-center gap-3">
                        <span className={cx("w-4 h-4 rounded-full border-2 grid place-items-center", on ? "border-terra" : "border-ink/30")}>
                          {on && <span className="w-2 h-2 rounded-full bg-terra" />}
                        </span>
                        {c.label}
                      </span>
                      {c.delta > 0 && <span className="font-mono text-[13px] text-muted">+{c.delta.toFixed(2)}</span>}
                    </button>
                  );
                })}
              </div>
            </div>
          ))}

          {/* Notiz */}
          <div className="mt-6">
            <label className="font-medium text-[15px] text-ink mb-2.5 block" htmlFor="note">Anmerkung <span className="text-muted font-normal">· optional</span></label>
            <input id="note" value={note} onChange={(e) => setNote(e.target.value)} maxLength={120}
              placeholder="z.B. ohne Zwiebeln, extra scharf …"
              className="w-full h-12 px-4 rounded-xl border border-line bg-card text-[15px] text-ink placeholder:text-muted/60 focus:border-terra outline-none" />
          </div>
        </div>

        {/* Footer: Menge + Add */}
        <div className="shrink-0 border-t border-line p-4 sm:p-5 flex items-center gap-4 bg-paper" style={{ paddingBottom: "max(1rem, env(safe-area-inset-bottom))" }}>
          <div className="flex items-center gap-1 border border-line rounded-full p-1">
            <button onClick={() => setQty((q) => Math.max(1, q - 1))} className="w-11 h-11 grid place-items-center rounded-full hover:bg-ink/5 disabled:opacity-30" disabled={qty <= 1} aria-label="Weniger"><Ico.minus className="w-5 h-5" /></button>
            <span className="w-8 text-center font-medium tabular-nums text-[17px]">{qty}</span>
            <button onClick={() => setQty((q) => Math.min(20, q + 1))} className="w-11 h-11 grid place-items-center rounded-full hover:bg-ink/5" aria-label="Mehr"><Ico.plus className="w-5 h-5" /></button>
          </div>
          <button onClick={add} className="flex-1 h-13 py-3.5 rounded-full bg-terra text-white font-medium text-[16px] hover:bg-terra-d transition-colors flex items-center justify-center gap-2">
            In den Warenkorb · {CHF(total)}
          </button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { DishCard, Menu, DishModal });
