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

  const [events, setEvents]   = useState(null);
  const [tab, setTab]         = useState("upcoming");
  const [editModal, setEditModal] = useState(null); // null | { ev, isNew }
  const [form, setForm]       = useState({});
  const [confirmId, setConfirmId] = useState(null);

  const clientIdRef = useRef(null);
  const clientSlugRef = useRef("demo");

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

  // ── Load ─────────────────────────────────────────────────────────────
  useEffect(function () { loadEvents(); }, []);

  async function loadEvents() {
    var client = await window.SVX.getCurrentClient();
    if (!client) return;
    clientIdRef.current = client.id;
    clientSlugRef.current = client.slug || "demo";

    var res = await window.SB
      .from("agenda_events")
      .select("*")
      .eq("client_id", client.id)
      .order("starts_at", { ascending: true });

    if (res.error) {
      console.error("[Agenda] load:", res.error);
      window.SVX.toast(tr("Error carregant l'agenda", "Error cargando la agenda"), "error");
      setEvents([]);
      return;
    }
    setEvents(res.data || []);
  }

  // ── Split upcoming / past ───────────────────────────────────────────
  var now = new Date().toISOString();
  var upcoming = events ? events.filter(function (e) { return e.starts_at >= now; }) : [];
  var past     = events ? events.filter(function (e) { return e.starts_at < now; }).reverse() : [];
  var shown    = tab === "upcoming" ? upcoming : past;

  // ── Toggle active ───────────────────────────────────────────────────
  async function doToggle(ev) {
    var newActive = !ev.active;
    setEvents(function (prev) { return prev.map(function (e) { return e.id === ev.id ? Object.assign({}, e, { active: newActive }) : e; }); });
    var res = await window.SB.from("agenda_events").update({ active: newActive }).eq("id", ev.id);
    if (res.error) {
      setEvents(function (prev) { return prev.map(function (e) { return e.id === ev.id ? Object.assign({}, e, { active: ev.active }) : e; }); });
      window.SVX.toast(tr("Error desant", "Error al guardar"), "error");
    } else {
      window.SVX.toast(tr("Desat", "Guardado"), "success");
    }
  }

  // ── Delete ──────────────────────────────────────────────────────────
  async function doDelete(id) {
    setEvents(function (prev) { return prev.filter(function (e) { return e.id !== id; }); });
    setConfirmId(null);
    var res = await window.SB.from("agenda_events").delete().eq("id", id);
    if (res.error) {
      window.SVX.toast(tr("Error eliminant", "Error eliminando"), "error");
      loadEvents();
    } else {
      window.SVX.toast(tr("Eliminat", "Eliminado"), "success");
    }
  }

  // ── Date helpers ────────────────────────────────────────────────────
  function toLocalDateStr(d) {
    return d.getFullYear() + "-" + String(d.getMonth() + 1).padStart(2, "0") + "-" + String(d.getDate()).padStart(2, "0");
  }
  function toLocalTimeStr(d) {
    return String(d.getHours()).padStart(2, "0") + ":" + String(d.getMinutes()).padStart(2, "0");
  }
  function todayISO() { return toLocalDateStr(new Date()); }

  function combineDateTimeLocal(dateStr, timeStr) {
    if (!dateStr) return null;
    var t2 = timeStr || "20:00";
    var p = dateStr.split("-").map(Number);
    var tp = t2.split(":").map(Number);
    return new Date(p[0], p[1] - 1, p[2], tp[0], tp[1], 0);
  }

  // ── Edit modal ──────────────────────────────────────────────────────
  function openEdit(ev, isNew) {
    var sd, st, ed, et;
    if (ev.starts_at) {
      var ds = new Date(ev.starts_at);
      sd = toLocalDateStr(ds);
      st = toLocalTimeStr(ds);
    } else {
      sd = todayISO();
      st = "20:00";
    }
    if (ev.ends_at) {
      var de = new Date(ev.ends_at);
      ed = toLocalDateStr(de);
      et = toLocalTimeStr(de);
    } else {
      ed = "";
      et = "";
    }
    setForm({
      name_ca:        ev.name_ca || "",
      name_es:        ev.name_es || "",
      description_ca: ev.description_ca || "",
      description_es: ev.description_es || "",
      location_ca:    ev.location_ca || "",
      location_es:    ev.location_es || "",
      start_date:     sd,
      start_time:     st,
      end_date:       ed,
      end_time:       et,
      all_day:        !!ev.all_day,
      price:          ev.price_cents != null ? (ev.price_cents / 100).toFixed(2).replace(".", ",") : "",
      capacity:       ev.capacity != null ? String(ev.capacity) : "",
      booking_url:    ev.booking_url || "",
      tags:           (ev.tags || []).join(", "),
      active:         ev.active !== false,
    });
    setEditModal({ ev: ev, isNew: !!isNew });
  }

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

  function parseCents(str) {
    if (!str) return null;
    var raw = str.replace(",", ".").trim();
    if (raw === "" || isNaN(parseFloat(raw))) return null;
    return Math.round(parseFloat(raw) * 100);
  }

  function parseTags(str) {
    if (!str) return [];
    return str.split(",").map(function (t) { return t.trim(); }).filter(Boolean);
  }

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

    if (!form.name_ca.trim() && !form.name_es.trim()) {
      window.SVX.toast(tr("El nom és obligatori", "El nombre es obligatorio"), "warn");
      return;
    }
    if (!form.start_date) {
      window.SVX.toast(tr("La data d'inici és obligatòria", "La fecha de inicio es obligatoria"), "warn");
      return;
    }
    if (!form.start_time && !form.all_day) {
      window.SVX.toast(tr("L'hora d'inici és obligatòria", "La hora de inicio es obligatoria"), "warn");
      return;
    }

    var startsDate = combineDateTimeLocal(form.start_date, form.all_day ? "00:00" : form.start_time);
    var endsDate = (form.end_date && (form.end_time || form.all_day))
      ? combineDateTimeLocal(form.end_date, form.all_day ? "23:59" : form.end_time)
      : null;

    // Warn if event is in the past
    if (startsDate && startsDate < new Date()) {
      if (!confirm(t.pastWarning)) return;
    }

    var patch = {
      name_ca:        form.name_ca.trim(),
      name_es:        form.name_es.trim(),
      description_ca: form.description_ca.trim(),
      description_es: form.description_es.trim(),
      location_ca:    form.location_ca.trim(),
      location_es:    form.location_es.trim(),
      starts_at:      startsDate.toISOString(),
      ends_at:        endsDate ? endsDate.toISOString() : null,
      all_day:        form.all_day,
      price_cents:    parseCents(form.price),
      capacity:       form.capacity ? parseInt(form.capacity, 10) || null : null,
      booking_url:    form.booking_url.trim() || null,
      tags:           parseTags(form.tags),
      active:         form.active,
    };

    if (editModal.isNew) {
      patch.client_id = clientIdRef.current;
      var res = await window.SB.from("agenda_events").insert(patch).select().single();
      if (res.error) {
        console.error("[Agenda] insert:", res.error);
        window.SVX.toast(tr("Error creant", "Error creando"), "error");
        return;
      }
      setEvents(function (prev) { return prev.concat(res.data).sort(function (a, b) { return a.starts_at < b.starts_at ? -1 : 1; }); });
    } else {
      var id = editModal.ev.id;
      setEvents(function (prev) { return prev.map(function (e) { return e.id === id ? Object.assign({}, e, patch) : e; }); });
      var res2 = await window.SB.from("agenda_events").update(patch).eq("id", id);
      if (res2.error) {
        console.error("[Agenda] update:", res2.error);
        window.SVX.toast(tr("Error desant", "Error al guardar"), "error");
        loadEvents();
        setEditModal(null);
        return;
      }
    }
    window.SVX.toast(tr("Desat", "Guardado"), "success");
    setEditModal(null);
  }

  function cancelModal() {
    setEditModal(null);
  }

  // ── Helpers ─────────────────────────────────────────────────────────
  function fmtDate(iso, allDay) {
    if (!iso) return "—";
    var d = new Date(iso);
    var locale = lang === "es" ? "es-ES" : "ca-ES";
    var datePart = d.toLocaleDateString(locale, { weekday: "long", day: "numeric", month: "long" });
    datePart = datePart.charAt(0).toUpperCase() + datePart.slice(1);
    if (allDay) return datePart;
    var timePart = d.toLocaleTimeString(locale, { hour: "2-digit", minute: "2-digit", hour12: false });
    return datePart + " \u00b7 " + timePart;
  }

  function fmtTimeRange(startsIso, endsIso) {
    if (!endsIso) return "";
    var d = new Date(endsIso);
    var locale = lang === "es" ? "es-ES" : "ca-ES";
    return "\u2013" + d.toLocaleTimeString(locale, { hour: "2-digit", minute: "2-digit", hour12: false });
  }

  function fmtPrice(cents) {
    if (cents == null) return null;
    return (cents / 100).toFixed(2).replace(".", ",") + " \u20ac";
  }

  function webUrl() {
    return "https://" + clientSlugRef.current + ".serviaos.com/#agenda";
  }

  // ── Render ──────────────────────────────────────────────────────────
  if (events === 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>
        <button className="btn primary" onClick={function () { openEdit({}, true); }}>
          <i className="ph ph-plus"></i>{t.add}
        </button>
      </header>

      {/* ── Tabs ── */}
      <div style={{display: "flex", gap: 4, marginBottom: 20}}>
        <button
          className={"btn " + (tab === "upcoming" ? "primary" : "ghost")}
          style={{fontSize: 13}}
          onClick={function () { setTab("upcoming"); }}
        >{t.tabUpcoming} ({upcoming.length})</button>
        <button
          className={"btn " + (tab === "past" ? "primary" : "ghost")}
          style={{fontSize: 13}}
          onClick={function () { setTab("past"); }}
        >{t.tabPast} ({past.length})</button>
      </div>

      {/* ── Event list ── */}
      {shown.length === 0 && (
        <p style={{color: "var(--ink-3)", fontSize: 15, marginTop: 12, fontStyle: "italic"}}>
          {tab === "upcoming" ? t.noUpcoming : t.noPast}
        </p>
      )}

      <div style={{display: "flex", flexDirection: "column", gap: 12}}>
        {shown.map(function (ev) {
          var title = lang === "es" ? (ev.name_es || ev.name_ca) : (ev.name_ca || ev.name_es);
          var desc  = lang === "es" ? ev.description_es : ev.description_ca;
          var loc   = lang === "es" ? ev.location_es : ev.location_ca;
          var dateStr = fmtDate(ev.starts_at, ev.all_day) + fmtTimeRange(ev.starts_at, ev.ends_at);
          var tags  = (ev.tags || []).join(" \u00b7 ");
          var price = fmtPrice(ev.price_cents);
          var meta  = [loc, tags, price, ev.capacity ? ev.capacity + " " + tr("places", "plazas") : null].filter(Boolean).join(" \u00b7 ");

          return (
            <div key={ev.id} style={{
              border: "1px solid var(--line)", borderRadius: 10, padding: "16px 20px",
              background: ev.active ? "var(--paper)" : "var(--paper-2)",
              opacity: ev.active ? 1 : 0.6,
              transition: "opacity 200ms",
            }}>
              <div style={{display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 6}}>
                <span style={{fontSize: 12, color: "var(--ink-3)", fontFamily: "var(--font-sans)"}}>{dateStr}</span>
                <div style={{display: "flex", alignItems: "center", gap: 6}}>
                  <button className={"toggle " + (ev.active ? "on" : "")} onClick={function () { doToggle(ev); }} 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 () { setConfirmId(ev.id); }} title={tr("Eliminar", "Eliminar")}><i className="ph ph-trash"></i></button>
                </div>
              </div>
              <div style={{fontSize: 16, fontWeight: 600, fontFamily: "var(--font-sans)", color: "var(--ink)", marginBottom: 4}}>{title || "—"}</div>
              {meta && <div style={{fontSize: 12, color: "var(--ink-3)", marginBottom: 4}}>{meta}</div>}
              {desc && <div style={{fontSize: 13, color: "var(--ink-2)", lineHeight: 1.4, display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical", overflow: "hidden"}}>{desc}</div>}
              <div style={{display: "flex", gap: 8, marginTop: 10}}>
                <button className="btn ghost" style={{fontSize: 12, padding: "6px 12px"}} onClick={function () { openEdit(ev, false); }}>
                  <i className="ph ph-pencil-simple"></i>{t.edit}
                </button>
                <a className="btn ghost" style={{fontSize: 12, padding: "6px 12px", textDecoration: "none"}} href={webUrl()} target="_blank" rel="noopener noreferrer">
                  <i className="ph ph-arrow-square-out"></i>{t.viewWeb}
                </a>
              </div>
            </div>
          );
        })}
      </div>

      {/* ── Edit / Create 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" style={{maxHeight: "90vh", overflowY: "auto"}} onClick={function (e) { e.stopPropagation(); }}>
            <h2 className="t-h2" style={{marginBottom: 8}}>
              {editModal.isNew ? t.add : t.edit}
            </h2>
            <form onSubmit={saveModal}>
              <div style={{display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12}}>
                <label style={labelStyle}>
                  {t.fieldNameCa}
                  <input autoFocus value={form.name_ca} onChange={function (e) { updateForm("name_ca", e.target.value); }} style={inputStyle} />
                </label>
                <label style={labelStyle}>
                  {t.fieldNameEs}
                  <input value={form.name_es} onChange={function (e) { updateForm("name_es", e.target.value); }} style={inputStyle} />
                </label>
              </div>
              <label style={labelStyle}>
                {t.fieldDescCa}
                <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}>
                {t.fieldDescEs}
                <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", gap: 12}}>
                <label style={labelStyle}>
                  {t.fieldLocationCa}
                  <input value={form.location_ca} onChange={function (e) { updateForm("location_ca", e.target.value); }} style={inputStyle} />
                </label>
                <label style={labelStyle}>
                  {t.fieldLocationEs}
                  <input value={form.location_es} onChange={function (e) { updateForm("location_es", e.target.value); }} style={inputStyle} />
                </label>
              </div>
              <div style={{display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12}}>
                <label style={labelStyle}>
                  {t.startDate}
                  <input type="date" value={form.start_date} onChange={function (e) { updateForm("start_date", e.target.value); }} style={inputStyle} />
                </label>
                {!form.all_day && (
                  <label style={labelStyle}>
                    {t.startTime}
                    <input type="time" value={form.start_time} step="900" onChange={function (e) { updateForm("start_time", e.target.value); }} style={inputStyle} />
                  </label>
                )}
              </div>
              <div style={{display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12}}>
                <label style={labelStyle}>
                  {t.endDate}
                  <input type="date" value={form.end_date} onChange={function (e) { updateForm("end_date", e.target.value); }} style={inputStyle} />
                </label>
                {!form.all_day && (
                  <label style={labelStyle}>
                    {t.endTime}
                    <input type="time" value={form.end_time} step="900" onChange={function (e) { updateForm("end_time", e.target.value); }} style={inputStyle} />
                  </label>
                )}
              </div>
              <label style={{display: "flex", alignItems: "center", gap: 8, fontSize: 13, color: "var(--ink-2)", marginBottom: 12, cursor: "pointer"}}>
                <input type="checkbox" checked={form.all_day} onChange={function (e) { updateForm("all_day", e.target.checked); }} />
                {t.fieldAllDay}
              </label>
              <div style={{display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 12}}>
                <label style={labelStyle}>
                  {t.fieldPrice}
                  <input value={form.price} onChange={function (e) { updateForm("price", e.target.value); }} onFocus={function (e) { e.target.select(); }} placeholder="0,00" style={inputStyle} />
                </label>
                <label style={labelStyle}>
                  {t.fieldCapacity}
                  <input type="number" min="0" value={form.capacity} onChange={function (e) { updateForm("capacity", e.target.value); }} placeholder="—" style={inputStyle} />
                </label>
                <label style={labelStyle}>
                  {t.fieldTags}
                  <input value={form.tags} onChange={function (e) { updateForm("tags", e.target.value); }} placeholder={tr("cata, vins", "cata, vinos")} style={inputStyle} />
                </label>
              </div>
              <label style={labelStyle}>
                {t.fieldBooking}
                <input type="url" value={form.booking_url} onChange={function (e) { updateForm("booking_url", e.target.value); }} placeholder="https://..." style={inputStyle} />
              </label>
              <label style={{display: "flex", alignItems: "center", gap: 8, fontSize: 13, color: "var(--ink-2)", marginBottom: 16, cursor: "pointer"}}>
                <input type="checkbox" checked={form.active} onChange={function (e) { updateForm("active", e.target.checked); }} />
                {t.fieldActive}
              </label>
              <div style={{display: "flex", gap: 8}}>
                <button type="submit" className="btn primary">{t.save}</button>
                <button type="button" className="btn ghost" onClick={cancelModal}>{t.cancel}</button>
              </div>
            </form>
          </div>
        </div>
      )}

      {/* ── Confirm delete ── */}
      {confirmId && (
        <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) setConfirmId(null); }}
        >
          <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}}>{tr("Eliminar esdeveniment?", "\u00bfEliminar evento?")}</h2>
            <p style={{margin: "0 0 16px", fontSize: 14, color: "var(--ink-2)"}}>{t.confirmDelete}</p>
            <div style={{display: "flex", gap: 8}}>
              <button className="btn primary" style={{background: "var(--danger)"}} onClick={function () { doDelete(confirmId); }}>{tr("Eliminar", "Eliminar")}</button>
              <button className="btn ghost" onClick={function () { setConfirmId(null); }}>{t.cancel}</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

window.Agenda = Agenda;
