var ALLERGENS = [
  { key: "gluten",      ca: "Gluten",      es: "Gluten" },
  { key: "crustacis",   ca: "Crustacis",   es: "Crustáceos" },
  { key: "ous",         ca: "Ous",         es: "Huevos" },
  { key: "peix",        ca: "Peix",        es: "Pescado" },
  { key: "cacauets",    ca: "Cacauets",    es: "Cacahuetes" },
  { key: "soja",        ca: "Soja",        es: "Soja" },
  { key: "lactis",      ca: "Lactis",      es: "Lácteos" },
  { key: "fruits_secs", ca: "Fruits secs", es: "Frutos secos" },
  { key: "api",         ca: "Api",         es: "Apio" },
  { key: "mostassa",    ca: "Mostassa",    es: "Mostaza" },
  { key: "sesam",       ca: "Sèsam",      es: "Sésamo" },
  { key: "sulfits",     ca: "Sulfits",     es: "Sulfitos" },
  { key: "tramussos",   ca: "Tramussos",   es: "Altramuces" },
  { key: "molluscos",   ca: "Mol·luscos",  es: "Moluscos" },
];

function Carta({ lang }) {
  const { useState, useEffect, useRef } = React;
  const T = window.T;
  const t = T[lang].carta;

  const [sections, setSections]       = useState(null);
  const [cellState, setCellState]     = useState({});
  const [saved, setSaved]             = useState(false);
  const [confirmTarget, setConfirmTarget] = useState(null);
  const [deleteCheck, setDeleteCheck]     = useState(false);

  // Edit modal state: null or { item, isNew }
  const [editModal, setEditModal] = useState(null);
  const [form, setForm]           = useState({});

  // Section modal: null or { mode: 'rename'|'create', sec?, name_ca, name_es }
  const [secModal, setSecModal]   = useState(null);

  function tr(ca, es) { return lang === "es" ? es : ca; }

  const clientIdRef          = useRef(null);
  const sectionsRef          = useRef([]);
  const sectionEls           = useRef({});
  const sortablesRef         = useRef({});
  const sectionsContainerRef = useRef(null);
  const secSortableRef       = useRef(null);

  // ── Load ─────────────────────────────────────────────────────────────────
  useEffect(() => { loadItems(); }, []);

  async function loadItems() {
    const client = await window.SVX.getCurrentClient();
    if (!client) return;
    clientIdRef.current = client.id;

    const { data, error } = await window.SB
      .from("menu_items")
      .select("*")
      .eq("client_id", client.id)
      .order("section_sort", { ascending: true })
      .order("sort_order",   { ascending: true });

    if (error) {
      console.error("[Carta] load:", error);
      window.SVX.toast(tr("Error carregant la carta", "Error cargando la carta"), "error");
      setSections([]);
      return;
    }
    const grouped = groupBySections(data || []);
    setSections(grouped);
    sectionsRef.current = grouped;
  }

  function groupBySections(items) {
    const map = new Map();
    for (const item of items) {
      if (!map.has(item.section_tab)) {
        map.set(item.section_tab, {
          section_tab:     item.section_tab,
          section_name_ca: item.section_name_ca,
          section_name_es: item.section_name_es,
          section_sort:    item.section_sort,
          items: [],
          _empty: false,
        });
      }
      map.get(item.section_tab).items.push(item);
    }
    return Array.from(map.values()).sort((a, b) => a.section_sort - b.section_sort);
  }

  // ── SortableJS for dishes (within + across sections) ─────────────────────
  useEffect(function () {
    if (!sections || typeof Sortable === "undefined") return;

    Object.values(sortablesRef.current).forEach(function (s) { try { s.destroy(); } catch (_) {} });
    sortablesRef.current = {};

    sections.forEach(function (sec) {
      var el = sectionEls.current[sec.section_tab];
      if (!el) return;
      sortablesRef.current[sec.section_tab] = Sortable.create(el, {
        group:     "dishes",
        handle:    ".col-grip",
        animation: 150,
        ghostClass: "dish-ghost",
        dragClass:  "dish-dragging",
        onEnd: function (evt) {
          var fromTab = evt.from.getAttribute("data-section-tab");
          var toTab   = evt.to.getAttribute("data-section-tab");
          var itemId  = evt.item.getAttribute("data-id");
          if (fromTab === toTab && evt.oldIndex === evt.newIndex) return;
          handleDishDragEnd(itemId, fromTab, toTab, evt.to);
        },
      });
    });

    return function () {
      Object.values(sortablesRef.current).forEach(function (s) { try { s.destroy(); } catch (_) {} });
      sortablesRef.current = {};
    };
  }, [sections]);

  // ── SortableJS for section ordering ──────────────────────────────────────
  useEffect(function () {
    if (!sections || !sectionsContainerRef.current || typeof Sortable === "undefined") return;
    if (secSortableRef.current) { try { secSortableRef.current.destroy(); } catch (_) {} }

    secSortableRef.current = Sortable.create(sectionsContainerRef.current, {
      handle: ".section-drag-handle",
      animation: 200,
      ghostClass: "section-ghost",
      onEnd: function (evt) {
        if (evt.oldIndex === evt.newIndex) return;
        var reordered = arrayMove(sectionsRef.current, evt.oldIndex, evt.newIndex);
        // Assign new section_sort = index
        reordered = reordered.map(function (s, i) {
          return Object.assign({}, s, {
            section_sort: i,
            items: s.items.map(function (it) { return Object.assign({}, it, { section_sort: i }); }),
          });
        });
        setSections(reordered);
        sectionsRef.current = reordered;
        // Persist to DB
        persistSectionOrder(reordered);
      },
    });

    return function () {
      if (secSortableRef.current) { try { secSortableRef.current.destroy(); } catch (_) {} secSortableRef.current = null; }
    };
  }, [sections ? sections.length : 0]);

  async function persistSectionOrder(reordered) {
    var updates = [];
    for (var i = 0; i < reordered.length; i++) {
      var sec = reordered[i];
      if (sec.items.length > 0) {
        updates.push(
          window.SB.from("menu_items")
            .update({ section_sort: i })
            .eq("client_id", clientIdRef.current)
            .eq("section_tab", sec.section_tab)
        );
      }
    }
    if (updates.length > 0) {
      var results = await Promise.all(updates);
      if (results.some(function (r) { return r.error; })) { loadItems(); }
      else { globalSaved(); }
    }
  }

  function arrayMove(arr, from, to) {
    var copy = arr.slice();
    var item = copy.splice(from, 1)[0];
    copy.splice(to, 0, item);
    return copy;
  }

  // ── State helpers ─────────────────────────────────────────────────────────
  function patchState(itemId, patch) {
    setSections(prev => {
      const next = prev.map(sec => ({
        ...sec,
        items: sec.items.map(item => item.id === itemId ? { ...item, ...patch } : item),
      }));
      sectionsRef.current = next;
      return next;
    });
  }

  function flashCell(itemId, status) {
    setCellState(prev => ({ ...prev, [itemId]: status }));
    if (status !== "saving") {
      const delay = status === "saved" ? 700 : 1500;
      setTimeout(() => setCellState(prev => {
        const next = { ...prev };
        if (next[itemId] === status) delete next[itemId];
        return next;
      }), delay);
    }
  }

  function globalSaved() {
    setSaved(true);
    setTimeout(() => setSaved(false), 1800);
  }

  // ── Toggle active ─────────────────────────────────────────────────────────
  function handleToggle(item) {
    if (item.active) {
      setConfirmTarget({ type: "deactivate", item: item });
      setDeleteCheck(false);
    } else {
      doToggle(item);
    }
  }

  async function doToggle(item) {
    const newActive = !item.active;
    patchState(item.id, { active: newActive });
    const { error } = await window.SB.from("menu_items").update({ active: newActive }).eq("id", item.id);
    if (error) {
      patchState(item.id, { active: item.active });
      window.SVX.toast(tr("Error desant el canvi", "Error al guardar"), "error");
    } else { globalSaved(); }
  }

  // ── Delete dish ─────────────────────────────────────────────────────────
  function handleDelete(item) {
    setConfirmTarget({ type: "delete", item: item });
    setDeleteCheck(false);
  }

  async function doDelete(item) {
    setSections(function (prev) {
      var next = prev.map(function (sec) {
        var filtered = sec.items.filter(function (i) { return i.id !== item.id; });
        // Keep section visible even if last item removed (mark _empty)
        return Object.assign({}, sec, { items: filtered, _empty: sec._empty || filtered.length === 0 });
      });
      sectionsRef.current = next;
      return next;
    });
    var res = await window.SB.from("menu_items").delete().eq("id", item.id);
    if (res.error) { window.SVX.toast(tr("Error eliminant el plat", "Error eliminando el plato"), "error"); loadItems(); }
    else { globalSaved(); }
  }

  // ── Delete section ──────────────────────────────────────────────────────
  async function doDeleteSection(sec) {
    setSections(function (prev) {
      var next = prev.filter(function (s) { return s.section_tab !== sec.section_tab; });
      sectionsRef.current = next;
      return next;
    });
    if (sec.items.length > 0) {
      var res = await window.SB.from("menu_items").delete().eq("client_id", clientIdRef.current).eq("section_tab", sec.section_tab);
      if (res.error) { window.SVX.toast(tr("Error eliminant la secció", "Error eliminando la sección"), "error"); loadItems(); }
      else { globalSaved(); }
    }
  }

  // ── Confirm action ──────────────────────────────────────────────────────
  function executeConfirm() {
    if (!confirmTarget) return;
    if (confirmTarget.type === "deactivate") doToggle(confirmTarget.item);
    if (confirmTarget.type === "delete")     doDelete(confirmTarget.item);
    if (confirmTarget.type === "delete_section") doDeleteSection(confirmTarget.sec);
    setConfirmTarget(null);
    setDeleteCheck(false);
  }

  function dismissConfirm() { setConfirmTarget(null); setDeleteCheck(false); }

  // ── Section management ──────────────────────────────────────────────────
  function slugify(str) {
    return str.toLowerCase()
      .normalize("NFD").replace(/[\u0300-\u036f]/g, "")
      .replace(/[·.]/g, "").replace(/[^a-z0-9]+/g, "-")
      .replace(/^-|-$/g, "") || "seccio";
  }

  function uniqueTab(base) {
    var existing = (sectionsRef.current || []).map(function (s) { return s.section_tab; });
    if (!existing.includes(base)) return base;
    for (var n = 2; n < 100; n++) { if (!existing.includes(base + "-" + n)) return base + "-" + n; }
    return base + "-" + Date.now();
  }

  function openSecRename(sec) {
    setSecModal({ mode: "rename", sec: sec, name_ca: sec.section_name_ca, name_es: sec.section_name_es });
  }

  function openSecCreate() {
    setSecModal({ mode: "create", sec: null, name_ca: "", name_es: "" });
  }

  function updateSecModal(key, val) {
    setSecModal(function (prev) { return Object.assign({}, prev, { [key]: val }); });
  }

  async function saveSecModal(e) {
    e.preventDefault();
    if (!secModal) return;
    var nameCa = (secModal.name_ca || "").trim();
    var nameEs = (secModal.name_es || "").trim();
    if (!nameCa && !nameEs) return;

    if (secModal.mode === "rename") {
      var sec = secModal.sec;
      // Optimistic: update local
      setSections(function (prev) {
        var next = prev.map(function (s) {
          if (s.section_tab !== sec.section_tab) return s;
          return Object.assign({}, s, {
            section_name_ca: nameCa || s.section_name_ca,
            section_name_es: nameEs || s.section_name_es,
            items: s.items.map(function (it) {
              return Object.assign({}, it, {
                section_name_ca: nameCa || it.section_name_ca,
                section_name_es: nameEs || it.section_name_es,
              });
            }),
          });
        });
        sectionsRef.current = next;
        return next;
      });
      setSecModal(null);

      // Persist: update all items in section
      if (sec.items.length > 0) {
        var res = await window.SB.from("menu_items")
          .update({ section_name_ca: nameCa || sec.section_name_ca, section_name_es: nameEs || sec.section_name_es })
          .eq("client_id", clientIdRef.current)
          .eq("section_tab", sec.section_tab);
        if (res.error) { window.SVX.toast(tr("Error desant", "Error al guardar"), "error"); loadItems(); }
        else { globalSaved(); }
      }
    } else {
      // Create new empty section (local only, Opción A)
      var tab = uniqueTab(slugify(nameCa || nameEs));
      var maxSort = (sectionsRef.current || []).reduce(function (m, s) { return Math.max(m, s.section_sort); }, -1);
      var newSec = {
        section_tab: tab,
        section_name_ca: nameCa || nameEs,
        section_name_es: nameEs || nameCa,
        section_sort: maxSort + 1,
        items: [],
        _empty: true,
      };
      setSections(function (prev) {
        var next = prev.concat(newSec);
        sectionsRef.current = next;
        return next;
      });
      setSecModal(null);
    }
  }

  function cancelSecModal() { setSecModal(null); }

  function handleDeleteSection(sec) {
    setConfirmTarget({ type: "delete_section", sec: sec });
    setDeleteCheck(false);
  }

  // ── Edit modal ──────────────────────────────────────────────────────────
  function openEditModal(item, isNew) {
    setForm({
      name_ca:        item.name_ca || "",
      name_es:        item.name_es || "",
      description_ca: item.description_ca || "",
      description_es: item.description_es || "",
      price:          item.price_cents != null ? (item.price_cents / 100).toFixed(2).replace(".", ",") : "",
      allergens:      (item.allergens || []).slice(),
      tag_ca:         item.tag_ca || "",
      tag_es:         item.tag_es || "",
      section_tab:    item.section_tab,
    });
    setEditModal({ item: item, isNew: !!isNew });
  }

  function updateForm(key, val) {
    setForm(function (prev) { return Object.assign({}, prev, { [key]: val }); });
  }

  function toggleFormAllergen(key) {
    setForm(function (prev) {
      var arr = prev.allergens || [];
      var next = arr.includes(key) ? arr.filter(function (a) { return a !== key; }) : arr.concat(key);
      return Object.assign({}, prev, { allergens: next });
    });
  }

  async function saveModal(e) {
    e.preventDefault();
    if (!editModal) return;
    var item = editModal.item;

    var rawPrice = (form.price || "").replace(",", ".").trim();
    var priceCents = null;
    if (rawPrice !== "" && !isNaN(parseFloat(rawPrice))) {
      priceCents = Math.round(parseFloat(rawPrice) * 100);
    }

    // Resolve section info from form.section_tab
    var targetSec = (sectionsRef.current || []).find(function (s) { return s.section_tab === form.section_tab; });
    var secPatch = targetSec ? {
      section_tab:     targetSec.section_tab,
      section_name_ca: targetSec.section_name_ca,
      section_name_es: targetSec.section_name_es,
      section_sort:    targetSec.section_sort,
    } : {};

    var patch = Object.assign({
      name_ca:        form.name_ca,
      name_es:        form.name_es,
      description_ca: form.description_ca,
      description_es: form.description_es,
      price_cents:    priceCents,
      allergens:      form.allergens,
      tag_ca:         form.tag_ca.trim() || null,
      tag_es:         form.tag_es.trim() || null,
    }, secPatch);

    // If section changed, move item between sections in local state
    var oldTab = item.section_tab;
    var newTab = form.section_tab;

    if (oldTab !== newTab) {
      setSections(function (prev) {
        var updatedItem = Object.assign({}, item, patch);
        var next = prev.map(function (s) {
          if (s.section_tab === oldTab) {
            var remaining = s.items.filter(function (i) { return i.id !== item.id; });
            return Object.assign({}, s, { items: remaining, _empty: s._empty || remaining.length === 0 });
          }
          if (s.section_tab === newTab) return Object.assign({}, s, { items: s.items.concat(updatedItem), _empty: false });
          return s;
        });
        sectionsRef.current = next;
        return next;
      });
    } else {
      patchState(item.id, patch);
    }

    setEditModal(null);
    flashCell(item.id, "saving");

    var res = await window.SB.from("menu_items").update(patch).eq("id", item.id);
    if (res.error) {
      flashCell(item.id, "error");
      window.SVX.toast(tr("Error desant el plat", "Error guardando el plato"), "error");
      loadItems();
    } else {
      flashCell(item.id, "saved");
      globalSaved();
    }
  }

  async function cancelModal() {
    if (!editModal) return;
    if (editModal.isNew) {
      var itemId = editModal.item.id;
      setEditModal(null);
      setSections(function (prev) {
        var next = prev.map(function (sec) {
          var filtered = sec.items.filter(function (i) { return i.id !== itemId; });
          return Object.assign({}, sec, { items: filtered, _empty: sec._empty || filtered.length === 0 });
        });
        sectionsRef.current = next;
        return next;
      });
      await window.SB.from("menu_items").delete().eq("id", itemId);
    } else {
      setEditModal(null);
    }
  }

  // ── Add dish ──────────────────────────────────────────────────────────────
  async function addDish(sec) {
    if (!clientIdRef.current) return;
    const maxSort = sec.items.reduce((m, i) => Math.max(m, i.sort_order), -1);
    const newItem = {
      client_id:       clientIdRef.current,
      section_tab:     sec.section_tab,
      section_name_ca: sec.section_name_ca,
      section_name_es: sec.section_name_es,
      section_sort:    sec.section_sort,
      name_ca:         "",
      name_es:         "",
      description_ca:  "",
      description_es:  "",
      price_cents:     null,
      allergens:       [],
      sort_order:      maxSort + 1,
      active:          true,
    };

    const { data, error } = await window.SB
      .from("menu_items")
      .insert(newItem)
      .select()
      .single();

    if (error) {
      window.SVX.toast(tr("Error afegint el plat", "Error al añadir el plato"), "error");
      return;
    }

    setSections(prev => {
      const next = prev.map(s =>
        s.section_tab === sec.section_tab ? { ...s, items: [...s.items, data], _empty: false } : s
      );
      sectionsRef.current = next;
      return next;
    });
    openEditModal(data, true);
  }

  // ── Dish drag end: reorder within section or move across sections ──────
  async function handleDishDragEnd(itemId, fromTab, toTab, toContainer) {
    // Build new order from DOM of destination container
    var newIds = Array.from(toContainer.querySelectorAll("[data-id]")).map(function (n) { return n.dataset.id; });

    // Build item map across ALL sections
    var allItems = {};
    sectionsRef.current.forEach(function (s) {
      s.items.forEach(function (it) { allItems[it.id] = it; });
    });

    var movedItem = allItems[itemId];
    if (!movedItem) { loadItems(); return; }

    var crossSection = fromTab !== toTab;
    var toSec = sectionsRef.current.find(function (s) { return s.section_tab === toTab; });

    // Optimistic: update local state
    setSections(function (prev) {
      var next = prev.map(function (s) {
        if (crossSection && s.section_tab === fromTab) {
          // Remove from source
          var remaining = s.items.filter(function (i) { return i.id !== itemId; });
          remaining = remaining.map(function (i, idx) { return Object.assign({}, i, { sort_order: idx }); });
          return Object.assign({}, s, { items: remaining, _empty: s._empty || remaining.length === 0 });
        }
        if (s.section_tab === toTab) {
          // Rebuild destination from DOM order
          var destItems = newIds.map(function (id, idx) {
            var it = id === itemId && crossSection
              ? Object.assign({}, movedItem, {
                  section_tab:     toSec.section_tab,
                  section_name_ca: toSec.section_name_ca,
                  section_name_es: toSec.section_name_es,
                  section_sort:    toSec.section_sort,
                })
              : allItems[id];
            return it ? Object.assign({}, it, { sort_order: idx }) : null;
          }).filter(Boolean);
          return Object.assign({}, s, { items: destItems, _empty: false });
        }
        return s;
      });
      sectionsRef.current = next;
      return next;
    });

    // Persist to DB
    var updates = [];

    // If cross-section, update the moved item's section fields
    if (crossSection && toSec) {
      updates.push(
        window.SB.from("menu_items").update({
          section_tab:     toSec.section_tab,
          section_name_ca: toSec.section_name_ca,
          section_name_es: toSec.section_name_es,
          section_sort:    toSec.section_sort,
        }).eq("id", itemId)
      );
    }

    // Update sort_order for all items in destination
    newIds.forEach(function (id, idx) {
      updates.push(
        window.SB.from("menu_items").update({ sort_order: idx }).eq("id", id)
      );
    });

    // If cross-section, also reorder source
    if (crossSection) {
      var fromEl = sectionEls.current[fromTab];
      if (fromEl) {
        var fromIds = Array.from(fromEl.querySelectorAll("[data-id]")).map(function (n) { return n.dataset.id; });
        fromIds.forEach(function (id, idx) {
          updates.push(
            window.SB.from("menu_items").update({ sort_order: idx }).eq("id", id)
          );
        });
      }
    }

    var results = await Promise.all(updates);
    if (results.some(function (r) { return r.error; })) {
      window.SVX.toast(tr("Error desant l'ordre", "Error guardando el orden"), "error");
      loadItems();
    } else {
      globalSaved();
    }
  }

  // ── Helpers ───────────────────────────────────────────────────────────────
  function fmtPrice(cents) {
    if (cents == null) return "—";
    return (cents / 100).toFixed(2).replace(".", ",");
  }
  function allergenAbbr(key) {
    var map = { gluten: "GL", crustacis: "CR", ous: "OU", peix: "PX", cacauets: "CC", soja: "SO", lactis: "LA", fruits_secs: "FS", api: "AP", mostassa: "MO", sesam: "SE", sulfits: "SU", tramussos: "TR", molluscos: "ML" };
    return map[key] || key.slice(0, 2).toUpperCase();
  }

  // ── Render ────────────────────────────────────────────────────────────────
  if (sections === null) return (
    <div style={{padding: 32, color: "var(--ink-3)", fontSize: 14}}>—</div>
  );

  var inputStyle = {
    display: "block", width: "100%", padding: "8px 10px", border: "1px solid var(--line)",
    borderRadius: 6, fontSize: 14, fontFamily: "inherit", marginTop: 4, boxSizing: "border-box",
  };
  var labelStyle = { display: "block", fontSize: 13, color: "var(--ink-2)", marginBottom: 12 };

  return (
    <div>
      <header className="srv-page-head">
        <div>
          <h1 className="t-h1">{t.title}</h1>
          <p style={{margin: "8px 0 0", color: "var(--ink-2)", fontSize: 15}}>{t.sub}</p>
        </div>
        {saved && (
          <div style={{display: "inline-flex", alignItems: "center", gap: 8, color: "var(--oliva-700)", background: "var(--oliva-50)", padding: "8px 14px", borderRadius: 999, fontSize: 13, fontWeight: 500}}>
            <i className="ph ph-check-circle"></i>{t.saved}
          </div>
        )}
      </header>

      {sections.length === 0 && (
        <p style={{color: "var(--ink-3)", fontSize: 15, marginTop: 24}}>
          {tr("La carta és buida. Crea la primera secció.", "La carta está vacía. Crea la primera sección.")}
        </p>
      )}

      <div ref={sectionsContainerRef}>
      {sections.map(function (sec) {
        var secName = lang === "es" ? sec.section_name_es : sec.section_name_ca;
        return (
          <div key={sec.section_tab} className="section-block" data-section-tab={sec.section_tab} style={{marginBottom: 28}}>
            <div className="section-head">
              <span className="section-drag-handle"><i className="ph ph-dots-six-vertical"></i></span>
              <h2 className="t-h2" style={{margin: 0}}>{secName}</h2>
              <div className="section-head-actions">
                <button className="section-action-btn" onClick={function () { openSecRename(sec); }} title={tr("Reanomenar", "Renombrar")}>
                  <i className="ph ph-pencil-simple"></i>
                </button>
                <button className="section-action-btn" onClick={function () { handleDeleteSection(sec); }} title={tr("Eliminar secció", "Eliminar sección")} style={{color: "var(--danger)"}}>
                  <i className="ph ph-trash"></i>
                </button>
              </div>
            </div>

            {sec.items.length === 0 ? (
              <p style={{color: "var(--ink-3)", fontSize: 14, fontStyle: "italic", padding: "12px 0"}}>
                {tr("Cap plat en aquesta secció.", "Ningún plato en esta sección.")}
              </p>
            ) : (
              <div className="srv-table">
                <div className="srv-table-head">
                  <span></span>
                  <span>{tr("Plat", "Plato")}</span>
                  <span style={{textAlign: "right"}}>{tr("Preu", "Precio")}</span>
                  <span>{t.allergens}</span>
                  <span style={{textAlign: "right"}}>{t.active}</span>
                </div>
                <div ref={function (el) { if (el) sectionEls.current[sec.section_tab] = el; }} data-section-tab={sec.section_tab}>
                  {sec.items.map(function (item) {
                    var cs      = cellState[item.id];
                    var rowCls  = ["srv-table-row", item.active ? "" : "off",
                      cs === "saving" ? "cell-saving" : cs === "saved" ? "cell-saved" : cs === "error" ? "cell-error" : "",
                    ].filter(Boolean).join(" ");
                    var displayName = lang === "es" ? (item.name_es || item.name_ca) : (item.name_ca || item.name_es);
                    var displayDesc = lang === "es" ? item.description_es : item.description_ca;
                    var displayTag  = lang === "es" ? item.tag_es : item.tag_ca;

                    return (
                      <div key={item.id} data-id={item.id} className={rowCls}>
                        <span className="col-grip"><i className="ph ph-dots-six-vertical"></i></span>
                        <div className="col-name" style={{cursor: "pointer"}} onClick={function () { openEditModal(item, false); }}>
                          <div className="dish-name">
                            {displayName || <span style={{color: "var(--ink-4)", fontStyle: "italic", fontSize: 13}}>+ {tr("nom", "nombre")}</span>}
                            {displayTag && <span className="tag-badge">{displayTag}</span>}
                          </div>
                          <div className="dish-sub">
                            {displayDesc || <span style={{color: "var(--ink-4)", fontStyle: "italic", fontSize: 12}}>+ {tr("descripció", "descripción")}</span>}
                          </div>
                        </div>
                        <div className="col-price" style={{cursor: "pointer"}} onClick={function () { openEditModal(item, false); }}>
                          {item.price_cents != null
                            ? <>{fmtPrice(item.price_cents)} <span className="price-suffix">€</span></>
                            : <span style={{color: "var(--ink-4)"}}>—</span>}
                        </div>
                        <div className="col-alg" style={{cursor: "pointer"}} onClick={function () { openEditModal(item, false); }}>
                          {!item.allergens || item.allergens.length === 0
                            ? <span style={{color: "var(--ink-4)", fontSize: 12}}>—</span>
                            : (function () {
                                var badges = item.allergens.slice(0, 3).map(function (a) {
                                  return <span key={a} className="allergen-badge" title={(ALLERGENS.find(function (x) { return x.key === a; }) || {})[lang === "es" ? "es" : "ca"] || a}>{allergenAbbr(a)}</span>;
                                });
                                if (item.allergens.length > 3) badges.push(<span key="_more" className="allergen-badge">+{item.allergens.length - 3}</span>);
                                return badges;
                              })()}
                        </div>
                        <div className="col-on" style={{display: "flex", alignItems: "center", gap: 6, justifyContent: "flex-end"}}>
                          <button className={"toggle " + (item.active ? "on" : "")} onClick={function () { handleToggle(item); }} aria-label="toggle"><span className="thumb"></span></button>
                          <button style={{background: "none", border: "none", cursor: "pointer", padding: 2, color: "var(--ink-4)", fontSize: 14}} onClick={function () { handleDelete(item); }} title={tr("Eliminar", "Eliminar")}><i className="ph ph-trash"></i></button>
                        </div>
                      </div>
                    );
                  })}
                </div>
              </div>
            )}
            <button className="btn ghost" style={{marginTop: 8, fontSize: 13}} onClick={function () { addDish(sec); }}>
              <i className="ph ph-plus"></i>{t.add}
            </button>
          </div>
        );
      })}
      </div>

      {/* ── + Nova secció ────────────────────────────────────────────────── */}
      <button className="new-section-btn" onClick={openSecCreate}>
        <i className="ph ph-plus"></i> {tr("Nova secció", "Nueva sección")}
      </button>

      {/* ── Section rename / create modal ────────────────────────────────── */}
      {secModal && (
        <div
          style={{position: "fixed", inset: 0, background: "rgba(0,0,0,0.4)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 200}}
          onClick={function (e) { if (e.target === e.currentTarget) cancelSecModal(); }}
        >
          <div style={{background: "var(--paper)", borderRadius: 12, padding: 24, width: "90%", maxWidth: 400, boxShadow: "0 8px 30px rgba(0,0,0,0.12)"}}>
            <h2 className="t-h2" style={{marginBottom: 16}}>
              {secModal.mode === "rename" ? tr("Reanomenar secció", "Renombrar sección") : tr("Nova secció", "Nueva sección")}
            </h2>
            <form onSubmit={saveSecModal}>
              <label style={labelStyle}>
                {tr("Nom (CA)", "Nombre (CA)")}
                <input autoFocus value={secModal.name_ca} onChange={function (e) { updateSecModal("name_ca", e.target.value); }} style={inputStyle} />
              </label>
              <label style={labelStyle}>
                {tr("Nom (ES)", "Nombre (ES)")}
                <input value={secModal.name_es} onChange={function (e) { updateSecModal("name_es", e.target.value); }} style={inputStyle} />
              </label>
              <div style={{display: "flex", gap: 8, marginTop: 8}}>
                <button type="submit" className="btn primary">
                  {secModal.mode === "rename" ? tr("Desar", "Guardar") : tr("Crear", "Crear")}
                </button>
                <button type="button" className="btn ghost" onClick={cancelSecModal}>{tr("Cancel·lar", "Cancelar")}</button>
              </div>
            </form>
          </div>
        </div>
      )}

      {/* ── Edit dish modal ──────────────────────────────────────────────── */}
      {editModal && (
        <div
          style={{position: "fixed", inset: 0, background: "rgba(0,0,0,0.4)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 200}}
          onClick={function (e) { if (e.target === e.currentTarget) cancelModal(); }}
        >
          <div className="dish-edit-modal" onClick={function (e) { e.stopPropagation(); }}>
            <h2 className="t-h2" style={{marginBottom: 4}}>
              {editModal.isNew ? tr("Nou plat", "Nuevo plato") : tr("Editar plat", "Editar plato")}
            </h2>
            <form onSubmit={saveModal}>
              <label style={labelStyle}>
                {tr("Secció", "Sección")}
                <select value={form.section_tab} onChange={function (e) { updateForm("section_tab", e.target.value); }} style={Object.assign({}, inputStyle, {padding: "8px 6px"})}>
                  {(sectionsRef.current || []).map(function (s) {
                    return <option key={s.section_tab} value={s.section_tab}>{lang === "es" ? s.section_name_es : s.section_name_ca}</option>;
                  })}
                </select>
              </label>
              <div style={{display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12}}>
                <label style={labelStyle}>
                  {tr("Nom (CA)", "Nombre (CA)")}
                  <input autoFocus value={form.name_ca} onChange={function (e) { updateForm("name_ca", e.target.value); }} style={inputStyle} />
                </label>
                <label style={labelStyle}>
                  {tr("Nom (ES)", "Nombre (ES)")}
                  <input value={form.name_es} onChange={function (e) { updateForm("name_es", e.target.value); }} style={inputStyle} />
                </label>
              </div>
              <label style={labelStyle}>
                {tr("Descripció (CA)", "Descripción (CA)")}
                <textarea rows="2" value={form.description_ca} onChange={function (e) { updateForm("description_ca", e.target.value); }} style={Object.assign({}, inputStyle, {resize: "vertical"})} />
              </label>
              <label style={labelStyle}>
                {tr("Descripció (ES)", "Descripción (ES)")}
                <textarea rows="2" value={form.description_es} onChange={function (e) { updateForm("description_es", e.target.value); }} style={Object.assign({}, inputStyle, {resize: "vertical"})} />
              </label>
              <div style={{display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 12}}>
                <label style={labelStyle}>
                  {tr("Preu (€)", "Precio (€)")}
                  <input value={form.price} onChange={function (e) { updateForm("price", e.target.value); }} onFocus={function (e) { e.target.select(); }} placeholder="16,50" style={inputStyle} />
                </label>
                <label style={labelStyle}>
                  {tr("Etiqueta (CA)", "Etiqueta (CA)")}
                  <input value={form.tag_ca} onChange={function (e) { updateForm("tag_ca", e.target.value); }} placeholder={tr("Nou…", "Nuevo…")} style={inputStyle} />
                </label>
                <label style={labelStyle}>
                  {tr("Etiqueta (ES)", "Etiqueta (ES)")}
                  <input value={form.tag_es} onChange={function (e) { updateForm("tag_es", e.target.value); }} style={inputStyle} />
                </label>
              </div>
              <div style={{marginBottom: 16}}>
                <div style={Object.assign({}, labelStyle, {marginBottom: 8})}>{t.allergens}</div>
                <div className="allergen-grid">
                  {ALLERGENS.map(function (al) {
                    var checked = (form.allergens || []).includes(al.key);
                    return (
                      <label key={al.key} className="allergen-grid-item">
                        <input type="checkbox" checked={checked} onChange={function () { toggleFormAllergen(al.key); }} />
                        {lang === "es" ? al.es : al.ca}
                      </label>
                    );
                  })}
                </div>
              </div>
              <div style={{display: "flex", gap: 8}}>
                <button type="submit" className="btn primary">{tr("Desar", "Guardar")}</button>
                <button type="button" className="btn ghost" onClick={cancelModal}>{tr("Cancel·lar", "Cancelar")}</button>
              </div>
            </form>
          </div>
        </div>
      )}

      {/* ── Confirm modal (deactivate / delete dish / delete section) ───── */}
      {confirmTarget && (function () {
        var isDelete    = confirmTarget.type === "delete";
        var isDeleteSec = confirmTarget.type === "delete_section";
        var isDeact     = confirmTarget.type === "deactivate";

        var title, body, btnLabel;
        if (isDeleteSec) {
          var sec = confirmTarget.sec;
          var sName = lang === "es" ? sec.section_name_es : sec.section_name_ca;
          var count = sec.items.length;
          title = tr("Eliminar secció?", "¿Eliminar sección?");
          body = count > 0
            ? tr('Això eliminarà la secció «' + sName + '» i els seus ' + count + ' plats permanentment.', 'Esto eliminará la sección «' + sName + '» y sus ' + count + ' platos permanentemente.')
            : tr('Això eliminarà la secció «' + sName + '».', 'Esto eliminará la sección «' + sName + '».');
          btnLabel = tr("Eliminar secció", "Eliminar sección");
        } else if (isDelete) {
          var iName = lang === "es" ? (confirmTarget.item.name_es || confirmTarget.item.name_ca || "—") : (confirmTarget.item.name_ca || confirmTarget.item.name_es || "—");
          title = tr("Eliminar plat?", "¿Eliminar plato?");
          body = tr("Això eliminarà " + iName + " permanentment. L'acció no es pot desfer.", "Esto eliminará " + iName + " permanentemente. La acción no se puede deshacer.");
          btnLabel = tr("Eliminar definitivament", "Eliminar definitivamente");
        } else {
          var iName2 = lang === "es" ? (confirmTarget.item.name_es || confirmTarget.item.name_ca || "—") : (confirmTarget.item.name_ca || confirmTarget.item.name_es || "—");
          title = tr("Desactivar plat?", "¿Desactivar plato?");
          body = tr(iName2 + " deixarà de mostrar-se a la carta. Pots reactivar-lo en qualsevol moment.", iName2 + " dejará de mostrarse en la carta. Puedes reactivarlo cuando quieras.");
          btnLabel = tr("Desactivar", "Desactivar");
        }

        var needsCheck = isDelete || (isDeleteSec && confirmTarget.sec.items.length > 0);

        return (
          <div
            style={{position: "fixed", inset: 0, background: "rgba(0,0,0,0.4)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 200}}
            onClick={function (e) { if (e.target === e.currentTarget) dismissConfirm(); }}
          >
            <div style={{background: "var(--paper)", borderRadius: 12, padding: 24, width: "90%", maxWidth: 400, boxShadow: "0 8px 30px rgba(0,0,0,0.12)"}}>
              <h2 className="t-h2" style={{marginBottom: 8}}>{title}</h2>
              <p style={{margin: "0 0 16px", fontSize: 14, color: "var(--ink-2)"}}>{body}</p>
              {needsCheck && (
                <label className="confirm-check" style={{display: "flex", alignItems: "center", gap: 8, fontSize: 13, color: "var(--ink-2)", marginBottom: 16, cursor: "pointer"}}>
                  <input type="checkbox" checked={deleteCheck} onChange={function (e) { setDeleteCheck(e.target.checked); }} />
                  {tr("Entenc que això no es pot desfer", "Entiendo que esto no se puede deshacer")}
                </label>
              )}
              <div style={{display: "flex", gap: 8}}>
                <button
                  className="btn primary"
                  style={isDeact ? {background: "var(--terra-700)"} : {background: "var(--danger)"}}
                  disabled={needsCheck && !deleteCheck}
                  onClick={executeConfirm}
                >{btnLabel}</button>
                <button className="btn ghost" onClick={dismissConfirm}>{tr("Cancel·lar", "Cancelar")}</button>
              </div>
            </div>
          </div>
        );
      })()}
    </div>
  );
}

window.Carta = Carta;
