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

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

  var DAY_KEYS = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];

  // ── State ────────────────────────────────────────────────────────────────
  const [open, setOpen]       = useState("rest");
  const [client, setClient]   = useState(null);
  const debounceRef           = useRef(null);
  const pendingPatch          = useRef({});
  const fileRef               = useRef(null);
  const heroRef               = useRef(null);
  const aboutRef              = useRef(null);

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

  async function loadClient() {
    var c = await window.SVX.getCurrentClient();
    if (c) setClient(c);
  }

  // ── Debounced save ───────────────────────────────────────────────────────
  function debounceSave(patch) {
    Object.assign(pendingPatch.current, patch);
    clearTimeout(debounceRef.current);
    debounceRef.current = setTimeout(async function () {
      var final = Object.assign({}, pendingPatch.current);
      pendingPatch.current = {};
      if (!client) return;
      var res = await window.SB.from("clients").update(final).eq("id", client.id);
      if (res.error) {
        console.error("[Settings] save:", res.error);
        window.SVX.toast(tr("Error desant", "Error al guardar"), "error");
      } else {
        window.SVX.toast(tr("Desat", "Guardado"), "success");
      }
    }, 800);
  }

  // ── Contact ──────────────────────────────────────────────────────────────
  function updateContact(key, value) {
    setClient(function (c) {
      var newContact = Object.assign({}, c.contact || {}, { [key]: value });
      debounceSave({ contact: newContact });
      return Object.assign({}, c, { contact: newContact });
    });
  }

  // ── Hours ────────────────────────────────────────────────────────────────
  function updateDay(dayKey, services) {
    setClient(function (c) {
      var newHours = Object.assign({}, c.hours || {});
      newHours[dayKey] = services;
      debounceSave({ hours: newHours });
      return Object.assign({}, c, { hours: newHours });
    });
  }

  function updateService(dayKey, si, field, value) {
    var services = ((client.hours || {})[dayKey] || []).map(function (s) { return Object.assign({}, s); });
    if (!services[si]) return;
    services[si][field] = value;
    updateDay(dayKey, services);
  }

  function addService(dayKey) {
    var services = ((client.hours || {})[dayKey] || []).map(function (s) { return Object.assign({}, s); });
    services.push({ open: "20:00", close: "23:00" });
    updateDay(dayKey, services);
  }

  function removeService(dayKey, si) {
    var services = ((client.hours || {})[dayKey] || []).filter(function (_, i) { return i !== si; });
    updateDay(dayKey, services.length === 0 ? null : services);
  }

  // ── Brand ────────────────────────────────────────────────────────────────
  function updateBrand(key, value) {
    setClient(function (c) {
      var newBrand = Object.assign({}, c.brand || {}, { [key]: value });
      debounceSave({ brand: newBrand });
      return Object.assign({}, c, { brand: newBrand });
    });
  }

  async function uploadLogo(e) {
    var file = e.target.files && e.target.files[0];
    if (!file || !client) return;
    if (file.size > 2 * 1024 * 1024) {
      window.SVX.toast(tr("Màxim 2 MB", "Máximo 2 MB"), "warn");
      return;
    }
    var ext  = (file.name.split(".").pop() || "png").toLowerCase();
    var path = client.slug + "/logo." + ext;

    window.SVX.toast(tr("Pujant…", "Subiendo…"), "info");

    var res = await window.SB.storage
      .from("client-assets")
      .upload(path, file, { upsert: true });

    if (res.error) {
      console.error("[Settings] upload:", res.error);
      window.SVX.toast(tr("Error pujant el logotip", "Error subiendo el logo"), "error");
      return;
    }

    var urlRes = window.SB.storage.from("client-assets").getPublicUrl(path);
    var logoUrl = urlRes.data.publicUrl;
    updateBrand("logo_url", logoUrl);
  }

  async function uploadHero(e) {
    var file = e.target.files && e.target.files[0];
    if (!file || !client) return;
    if (file.size > 2 * 1024 * 1024) { window.SVX.toast(tr("Màxim 2 MB", "Máximo 2 MB"), "warn"); return; }
    var ext  = (file.name.split(".").pop() || "jpg").toLowerCase();
    var path = client.slug + "/hero." + ext;
    window.SVX.toast(tr("Pujant…", "Subiendo…"), "info");
    var res = await window.SB.storage.from("client-assets").upload(path, file, { upsert: true });
    if (res.error) { console.error("[Settings] uploadHero:", res.error); window.SVX.toast(tr("Error pujant la foto", "Error subiendo la foto"), "error"); return; }
    var url = window.SB.storage.from("client-assets").getPublicUrl(path).data.publicUrl;
    updateBrand("hero_url", url);
  }

  async function uploadAbout(e) {
    var file = e.target.files && e.target.files[0];
    if (!file || !client) return;
    if (file.size > 2 * 1024 * 1024) { window.SVX.toast(tr("Màxim 2 MB", "Máximo 2 MB"), "warn"); return; }
    var ext  = (file.name.split(".").pop() || "jpg").toLowerCase();
    var path = client.slug + "/about." + ext;
    window.SVX.toast(tr("Pujant…", "Subiendo…"), "info");
    var res = await window.SB.storage.from("client-assets").upload(path, file, { upsert: true });
    if (res.error) { console.error("[Settings] uploadAbout:", res.error); window.SVX.toast(tr("Error pujant la foto", "Error subiendo la foto"), "error"); return; }
    var url = window.SB.storage.from("client-assets").getPublicUrl(path).data.publicUrl;
    updateBrand("about_url", url);
  }

  // ── Subscription helpers ─────────────────────────────────────────────────
  function planLabel(plan) {
    var plans = (window.SRV_CONFIG || {}).PLANS || {};
    var p = plans[plan];
    if (p) return lang === "es" ? p.label_es : p.label_ca;
    return plan;
  }

  function fmtDate(iso) {
    if (!iso) return "—";
    return new Date(iso).toLocaleDateString(lang === "es" ? "es-ES" : "ca-ES", { day: "numeric", month: "long", year: "numeric" });
  }

  var waNumber = ((window.SRV_CONFIG || {}).WA_SUPPORT_NUMBER || "").replace(/\D/g, "");
  var waSubUrl = waNumber
    ? "https://wa.me/" + waNumber + "?text=" + encodeURIComponent(
        lang === "es"
          ? "Hola, quiero hablar de mi suscripción ServiaOS."
          : "Hola, vull parlar de la meva subscripció ServiaOS."
      )
    : "#";

  var devMode = (window.SRV_CONFIG || {}).DEV_MODE === true;

  // ── Section config ───────────────────────────────────────────────────────
  var secs = [
    { id: "rest",  label: t.secs.rest },
    { id: "hours", label: t.secs.hours },
    { id: "brand", label: t.secs.brand },
    { id: "whats", label: t.secs.whats },
    { id: "sub",   label: t.secs.sub },
  ];

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

  var contact = client.contact || {};
  var hours   = client.hours   || {};
  var brand   = client.brand   || {};

  var timeInputStyle = {
    border: "1px solid var(--line)", borderRadius: 4, padding: "3px 6px",
    fontSize: 13, fontFamily: "inherit", width: 90,
  };
  var tinyBtnStyle = {
    background: "none", border: "none", cursor: "pointer", fontSize: 12,
    color: "var(--ink-3)", padding: "2px 6px",
  };

  return (
    <div>
      <header className="srv-page-head">
        <h1 className="t-h1">{t.title}</h1>
      </header>
      <div className="set-list">
        {secs.map(function (s) {
          return (
            <div key={s.id} className={"set-sec " + (open === s.id ? "open" : "")}>
              <button className="set-sec-head" onClick={function () { setOpen(open === s.id ? null : s.id); }}>
                <h2 className="t-h2">{s.label}</h2>
                <i className="ph ph-caret-down"></i>
              </button>
              {open === s.id && (
                <div className="set-sec-body">

                  {/* ── Restaurant ── */}
                  {s.id === "rest" && <>
                    <div className="set-row">
                      <span className="eyebrow">{t.rest.name}</span>
                      <input className="set-input" value={client.name || ""} onChange={function (e) {
                        var v = e.target.value;
                        setClient(function (c) { return Object.assign({}, c, { name: v }); });
                        debounceSave({ name: v });
                      }} />
                    </div>
                    <div className="set-row">
                      <span className="eyebrow">{t.rest.phone}</span>
                      <input className="set-input" value={contact.phone || ""} onChange={function (e) { updateContact("phone", e.target.value); }} />
                    </div>
                    <div className="set-row">
                      <span className="eyebrow">{t.rest.addr}</span>
                      <input className="set-input" value={contact.address || ""} onChange={function (e) { updateContact("address", e.target.value); }} />
                    </div>
                    <div className="set-row">
                      <span className="eyebrow">{t.rest.city}</span>
                      <input className="set-input" value={contact.city || ""} onChange={function (e) { updateContact("city", e.target.value); }} />
                    </div>
                  </>}

                  {/* ── Horaris ── */}
                  {s.id === "hours" && <>
                    <div className="eyebrow" style={{marginBottom: 6}}>{t.hoursLabel}</div>
                    <ul className="hours">
                      {DAY_KEYS.map(function (dk, i) {
                        var services = hours[dk];
                        var isClosed = services === null || services === undefined;
                        return (
                          <li key={dk} style={{display: "flex", alignItems: "flex-start", gap: 10}}>
                            <span style={{minWidth: 80}}>{t.days[i]}</span>
                            {isClosed ? (
                              <em className="closed" style={{flex: 1}}>{t.closed}</em>
                            ) : (
                              <div style={{display: "flex", flexDirection: "column", gap: 4, flex: 1}}>
                                {services.map(function (srv, si) {
                                  return (
                                    <div key={si} style={{display: "flex", gap: 6, alignItems: "center"}}>
                                      <input type="time" value={srv.open || ""} onChange={function (e) { updateService(dk, si, "open", e.target.value); }} style={timeInputStyle} />
                                      <span style={{color: "var(--ink-3)"}}>–</span>
                                      <input type="time" value={srv.close || ""} onChange={function (e) { updateService(dk, si, "close", e.target.value); }} style={timeInputStyle} />
                                      {si > 0 && (
                                        <button style={tinyBtnStyle} onClick={function () { removeService(dk, si); }}>✕</button>
                                      )}
                                    </div>
                                  );
                                })}
                                {services.length < 2 && (
                                  <button style={Object.assign({}, tinyBtnStyle, {fontSize: 11, marginTop: 2})} onClick={function () { addService(dk); }}>+ {tr("Servei", "Servicio")}</button>
                                )}
                              </div>
                            )}
                            <button
                              style={tinyBtnStyle}
                              onClick={function () { updateDay(dk, isClosed ? [{ open: "13:00", close: "16:00" }] : null); }}
                              title={isClosed ? tr("Obrir", "Abrir") : tr("Tancar", "Cerrar")}
                            >{isClosed ? "↩" : "✕"}</button>
                          </li>
                        );
                      })}
                    </ul>
                  </>}

                  {/* ── Marca ── */}
                  {s.id === "brand" && <>
                    <div className="brand-preview" style={{background: brand.primary_color || "var(--ink)"}}>
                      {brand.logo_url
                        ? <img src={brand.logo_url} alt="Logo" style={{maxHeight: 48, maxWidth: "80%"}} />
                        : <div className="brand-mark-big">{client.name || "—"}</div>
                      }
                    </div>
                    <p style={{margin: 0, fontSize: 13, color: "var(--ink-2)", fontStyle: "italic", fontFamily: "var(--font-serif)"}}>{t.brandNote}</p>
                    <div className="set-row">
                      <span className="eyebrow">{t.brandPrimary}</span>
                      <div style={{display: "flex", alignItems: "center", gap: 10}}>
                        <input
                          type="color"
                          value={brand.primary_color || "#7D2A2E"}
                          onChange={function (e) { updateBrand("primary_color", e.target.value); }}
                          style={{width: 28, height: 28, border: "1px solid var(--line)", borderRadius: 6, padding: 0, cursor: "pointer"}}
                        />
                        <code style={{fontFamily: "var(--font-mono)", fontSize: 13, color: "var(--ink-2)"}}>{brand.primary_color || "#7D2A2E"}</code>
                      </div>
                    </div>
                    <div className="set-row">
                      <span className="eyebrow">{t.brandTagline}</span>
                      <p style={{margin: "2px 0 8px", fontSize: 12, color: "var(--ink-3)", lineHeight: 1.4, fontStyle: "italic"}}>{t.brandTaglineHelp}</p>
                      <div style={{display: "flex", flexDirection: "column", gap: 6}}>
                        <label style={{display: "block"}}>
                          <span style={{display: "block", fontSize: 11, color: "var(--ink-3)", marginBottom: 2, textTransform: "uppercase", letterSpacing: "0.05em"}}>{t.brandTaglineCa}</span>
                          <input className="set-input" value={brand.tagline_ca || ""} onChange={function (e) { updateBrand("tagline_ca", e.target.value); }} placeholder="Ex: PENEDÈS · BRASA · TERRITORI" maxLength={60} />
                        </label>
                        <label style={{display: "block"}}>
                          <span style={{display: "block", fontSize: 11, color: "var(--ink-3)", marginBottom: 2, textTransform: "uppercase", letterSpacing: "0.05em"}}>{t.brandTaglineEs}</span>
                          <input className="set-input" value={brand.tagline_es || ""} onChange={function (e) { updateBrand("tagline_es", e.target.value); }} placeholder="Ej: PENEDÈS · BRASA · TERRITORIO" maxLength={60} />
                        </label>
                      </div>
                    </div>
                    <div className="set-row">
                      <span className="eyebrow">{t.brandLogo}</span>
                      <input type="file" accept="image/*" ref={fileRef} style={{display: "none"}} onChange={uploadLogo} />
                      <button className="btn ghost small" onClick={function () { fileRef.current && fileRef.current.click(); }}>
                        <i className="ph ph-upload-simple"></i>{tr("Canviar logotip", "Cambiar logo")}
                      </button>
                    </div>
                    <div className="set-row">
                      <span className="eyebrow">{t.brandHero}</span>
                      <p style={{margin: "2px 0 8px", fontSize: 12, color: "var(--ink-3)", lineHeight: 1.4, fontStyle: "italic"}}>{t.brandHeroHelp}</p>
                      {brand.hero_url && <img src={brand.hero_url} alt="Hero" style={{maxHeight: 80, maxWidth: "100%", objectFit: "cover", borderRadius: 4, marginBottom: 8}} />}
                      <input type="file" accept="image/*" ref={heroRef} style={{display: "none"}} onChange={uploadHero} />
                      <button className="btn ghost small" onClick={function () { heroRef.current && heroRef.current.click(); }}>
                        <i className="ph ph-upload-simple"></i>{brand.hero_url ? t.brandHeroChange : t.brandHeroUpload}
                      </button>
                    </div>
                    <div className="set-row">
                      <span className="eyebrow">{t.brandAbout}</span>
                      <p style={{margin: "2px 0 8px", fontSize: 12, color: "var(--ink-3)", lineHeight: 1.4, fontStyle: "italic"}}>{t.brandAboutHelp}</p>
                      {brand.about_url && <img src={brand.about_url} alt="About" style={{maxHeight: 80, maxWidth: "100%", objectFit: "cover", borderRadius: 4, marginBottom: 8}} />}
                      <input type="file" accept="image/*" ref={aboutRef} style={{display: "none"}} onChange={uploadAbout} />
                      <button className="btn ghost small" onClick={function () { aboutRef.current && aboutRef.current.click(); }}>
                        <i className="ph ph-upload-simple"></i>{brand.about_url ? t.brandAboutChange : t.brandAboutUpload}
                      </button>
                    </div>
                  </>}

                  {/* ── WhatsApp ── */}
                  {s.id === "whats" && <>
                    <div className="set-row">
                      <span className="eyebrow">{t.whatsNum}</span>
                      <span className="set-val">
                        {contact.wa_number || contact.phone || "—"}
                        {(contact.wa_number || contact.phone) && <span className="src-badge src-bot" style={{marginLeft: 8}}>{tr("Connectat", "Conectado")}</span>}
                      </span>
                    </div>
                    <div className="set-row">
                      <span className="eyebrow">{t.whatsBot}</span>
                      <div style={{display: "flex", alignItems: "center", gap: 10}}>
                        <button className="toggle on" aria-label="bot" style={{pointerEvents: "none", opacity: 0.7}}><span className="thumb"></span></button>
                        <span style={{fontSize: 13, color: "var(--ink-2)"}}>{t.botOn} <span style={{fontSize: 11, color: "var(--ink-3)"}}>(read-only v1)</span></span>
                      </div>
                    </div>
                  </>}

                  {/* ── Subscripció ── */}
                  {s.id === "sub" && <>
                    <div className="sub-card">
                      <div className="eyebrow">{t.subPlan}</div>
                      <div className="t-h2">{client.name} · {planLabel(client.subscription_plan)}</div>
                      <div className="set-row" style={{marginTop: 14}}>
                        <span className="eyebrow">{t.subRenew}</span>
                        <span className="set-val">{fmtDate(client.subscription_expires_at)}</span>
                      </div>
                      <div className="set-row">
                        <span className="eyebrow">{t.subPay}</span>
                        <span className="set-val">{client.stripe_customer_id ? tr("Stripe configurat", "Stripe configurado") : "—"}</span>
                      </div>
                    </div>
                    <div style={{display: "flex", gap: 10, flexWrap: "wrap", marginTop: 6}}>
                      <a
                        className="btn ghost small"
                        href={waSubUrl}
                        target="_blank"
                        rel="noopener noreferrer"
                        style={{textDecoration: "none"}}
                      >{t.subManage}</a>
                      {devMode && (
                        <button className="btn ghost small" onClick={onExpire} style={{color: "var(--terra-700)"}}>Simular caducitat →</button>
                      )}
                    </div>
                  </>}

                </div>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}

window.Settings = Settings;
