// =====================================================================
// SOMOS SETAS — Admin Panel
// =====================================================================

const { useState: useStateA, useEffect: useEffectA, useMemo: useMemoA } = React;

// Redimensiona una imagen con canvas.
// Si es PNG (puede tener transparencia) → exporta como PNG.
// Si es JPG/WEBP/etc → exporta como JPEG comprimido.
function resizeToBlob(file, maxSize = 900, quality = 0.82) {
  const isPng = file.type === "image/png";
  const mimeOut = isPng ? "image/png" : "image/jpeg";
  return new Promise((resolve) => {
    const reader = new FileReader();
    reader.onload = (e) => {
      const img = new Image();
      img.onload = () => {
        const canvas = document.createElement("canvas");
        let { width, height } = img;
        if (width > height) {
          if (width > maxSize) { height = Math.round(height * maxSize / width); width = maxSize; }
        } else {
          if (height > maxSize) { width = Math.round(width * maxSize / height); height = maxSize; }
        }
        canvas.width = width;
        canvas.height = height;
        const ctx = canvas.getContext("2d");
        // Para PNG: fondo transparente (no rellenar)
        // Para JPEG: fondo blanco para evitar negro en áreas alfa residuales
        if (!isPng) {
          ctx.fillStyle = "#ffffff";
          ctx.fillRect(0, 0, width, height);
        }
        ctx.drawImage(img, 0, 0, width, height);
        canvas.toBlob((blob) => resolve({ blob, mimeOut, ext: isPng ? "png" : "jpg" }), mimeOut, isPng ? undefined : quality);
      };
      img.src = e.target.result;
    };
    reader.readAsDataURL(file);
  });
}

// Sube una imagen a Supabase Storage y devuelve la URL pública
async function uploadImage(file, folder = "productos", maxSize = 900, quality = 0.82) {
  const { blob, mimeOut, ext } = await resizeToBlob(file, maxSize, quality);
  const path = `${folder}/${Date.now()}-${Math.random().toString(36).slice(2)}.${ext}`;
  const { error } = await window.sb.storage.from("somos-setas").upload(path, blob, {
    contentType: mimeOut,
    cacheControl: "31536000",
  });
  if (error) throw error;
  const { data } = window.sb.storage.from("somos-setas").getPublicUrl(path);
  return data.publicUrl;
}

// =====================================================================
// LOGIN
// =====================================================================
function AdminLogin() {
  const [user, setUser] = useStateA("");
  const [pass, setPass] = useStateA("");
  const [err, setErr] = useStateA("");
  const [loading, setLoading] = useStateA(false);

  const submit = async (e) => {
    e?.preventDefault();
    setLoading(true);
    setErr("");
    const { error } = await window.sb.auth.signInWithPassword({ email: user, password: pass });
    if (error) setErr("Credenciales incorrectas. Verificá tu email y contraseña.");
    setLoading(false);
  };

  return (
    <div className="login-shell">
      <aside className="login-side">
        <div>
          <a href="#" aria-label="Somos Setas — Inicio">
            <img src="assets/logo-blanco.png" alt="Somos Setas" className="logo-img small"/>
          </a>
        </div>
        <div>
          <span className="eyebrow">Panel de gestión</span>
          <div className="display">Administrá tu <em>catálogo de hongos</em>, banners y pedidos en un solo lugar.</div>
        </div>
        <div className="login-foot">Acceso restringido a personal autorizado.</div>
      </aside>
      <div className="login-form-wrap">
        <form className="login-form" onSubmit={submit}>
          <h2>Ingresar al panel</h2>
          <p>Ingresá tus credenciales de administrador.</p>
          {err && <div className="err">{err}</div>}
          <div className="field">
            <label>Email</label>
            <input type="email" value={user} onChange={(e) => setUser(e.target.value)} autoFocus autoComplete="email"/>
          </div>
          <div className="field">
            <label>Contraseña</label>
            <input type="password" value={pass} onChange={(e) => setPass(e.target.value)} autoComplete="current-password"/>
          </div>
          <button type="submit" className="btn-primary" disabled={loading}>{loading ? "Ingresando…" : "Iniciar sesión"}</button>
          <a href="#" className="back-home">← Volver al sitio</a>
        </form>
      </div>
    </div>
  );
}

// =====================================================================
// DASHBOARD HOME
// =====================================================================
function AdminDashboard({ store }) {
  const totalProducts = store.products.length;
  const activeBanners = store.banners.filter((b) => b.active).length;
  const recentOrders = store.orders.slice(0, 5);
  const totalRevenue = store.orders.reduce((s, o) => s + o.total, 0);

  return (
    <div>
      <div className="admin-head">
        <div>
          <h1>Resumen</h1>
          <div className="sub">Vista general del estado del sitio.</div>
        </div>
        <div style={{display: "flex", gap: 8}}>
          <a href="#" className="btn-ghost">↗ Ver sitio</a>
          <button className="btn-primary" onClick={() => navigate("admin/productos/nuevo")}><Icon.plus width="12" height="12"/> Nuevo producto</button>
        </div>
      </div>

      <div className="stat-grid">
        <div className="stat-card">
          <div className="stat-label">Productos</div>
          <div className="stat-val">{totalProducts}</div>
          <div className="stat-meta">En el catálogo activo</div>
        </div>
        <div className="stat-card">
          <div className="stat-label">Banners activos</div>
          <div className="stat-val">{activeBanners}<span style={{fontSize: 18, opacity: 0.4}}>/{store.banners.length}</span></div>
          <div className="stat-meta">Visibles en home</div>
        </div>
        <div className="stat-card">
          <div className="stat-label">Pedidos</div>
          <div className="stat-val">{store.orders.length}</div>
          <div className="stat-meta">Histórico total</div>
        </div>
        <div className="stat-card">
          <div className="stat-label">Facturación est.</div>
          <div className="stat-val mono" style={{fontSize: 28, fontFamily: "var(--mono)"}}>{fmtPrice(totalRevenue)}</div>
          <div className="stat-meta">Suma de pedidos recibidos</div>
        </div>
      </div>

      <div style={{display: "grid", gridTemplateColumns: "1.4fr 1fr", gap: 24}}>
        <div className="panel">
          <div className="panel-head">
            <h3>Últimos pedidos</h3>
            <button className="btn-ghost" onClick={() => navigate("admin/pedidos")}>Ver todos</button>
          </div>
          {recentOrders.length === 0 ? (
            <div style={{padding: 40, textAlign: "center", color: "var(--ink-3)", fontSize: 14}}>
              Aún no hay pedidos recibidos.
            </div>
          ) : (
            <table className="tbl">
              <thead><tr><th>ID</th><th>Cliente</th><th>Items</th><th>Total</th><th>Estado</th></tr></thead>
              <tbody>
                {recentOrders.map((o) => (
                  <tr key={o.id}>
                    <td className="mono" style={{fontSize: 11}}>{o.id}</td>
                    <td>{o.name || "—"}<div style={{fontSize: 11, color: "var(--ink-3)"}}>{o.city}</div></td>
                    <td>{o.items.reduce((s, i) => s + i.qty, 0)} prod.</td>
                    <td className="mono">{fmtPrice(o.total)}</td>
                    <td><span className="tag amber">{o.status}</span></td>
                  </tr>
                ))}
              </tbody>
            </table>
          )}
        </div>

        <div className="panel">
          <div className="panel-head"><h3>Accesos rápidos</h3></div>
          <div className="panel-body" style={{display: "grid", gap: 10}}>
            <button className="btn-ghost" onClick={() => navigate("admin/productos")} style={{justifyContent: "flex-start"}}>Gestionar productos →</button>
            <button className="btn-ghost" onClick={() => navigate("admin/banners")} style={{justifyContent: "flex-start"}}>Editar banners promocionales →</button>
            <button className="btn-ghost" onClick={() => navigate("admin/pedidos")} style={{justifyContent: "flex-start"}}>Ver pedidos recibidos →</button>
            <button className="btn-ghost" onClick={() => navigate("admin/config")} style={{justifyContent: "flex-start"}}>Configuración general →</button>
          </div>
        </div>
      </div>
    </div>
  );
}

// =====================================================================
// PRODUCT LIST
// =====================================================================
function AdminProducts({ store }) {
  const [filter, setFilter] = useStateA("all");
  const [search, setSearch] = useStateA("");
  const [editingId, setEditingId] = useStateA(null);

  const filtered = store.products.filter((p) => {
    if (filter !== "all" && p.category !== filter) return false;
    if (search && !p.name.toLowerCase().includes(search.toLowerCase())) return false;
    return true;
  });

  const handleDelete = (id) => {
    if (confirm("¿Eliminar este producto del catálogo?")) {
      store.setProducts(store.products.filter((p) => p.id !== id));
    }
  };

  const handleToggleFeatured = (id) => {
    store.setProducts(store.products.map((p) => p.id === id ? { ...p, featured: !p.featured } : p));
  };

  const handleToggleVisible = (id) => {
    store.setProducts(store.products.map((p) => p.id === id ? { ...p, visible: p.visible === false ? true : false } : p));
  };

  const handleDuplicate = (id) => {
    const original = store.products.find((p) => p.id === id);
    if (!original) return;
    const newId = id + "-copia-" + Date.now().toString(36);
    const copy = {
      ...original,
      id: newId,
      name: original.name + " (copia)",
      featured: false,
      visible: false,
    };
    const idx = store.products.findIndex((p) => p.id === id);
    const updated = [...store.products];
    updated.splice(idx + 1, 0, copy);
    store.setProducts(updated);
    setEditingId(newId); // abre el editor para renombrar de inmediato
  };

  return (
    <div>
      <div className="admin-head">
        <div>
          <h1>Productos</h1>
          <div className="sub">{store.products.length} productos en el catálogo.</div>
        </div>
        <button className="btn-primary" onClick={() => setEditingId("__new")}><Icon.plus width="12" height="12"/> Nuevo producto</button>
      </div>

      <div className="panel">
        <div className="panel-head">
          <div className="chip-row">
            <button className={"chip" + (filter === "all" ? " is-active" : "")} onClick={() => setFilter("all")}>Todos</button>
            {window.SS_CATEGORIES.map((c) => (
              <button key={c.id} className={"chip" + (filter === c.id ? " is-active" : "")} onClick={() => setFilter(c.id)}>{c.name}</button>
            ))}
          </div>
          <input
            type="text"
            placeholder="Buscar por nombre…"
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            style={{border: "1px solid var(--line-2)", borderRadius: 6, padding: "8px 12px", fontSize: 13, width: 220}}
          />
        </div>

        <div className="tbl-wrap">
        <table className="tbl">
          <thead>
            <tr>
              <th></th>
              <th>Producto</th>
              <th>Categoría</th>
              <th>Presentaciones</th>
              <th>Precio desde</th>
              <th>Visible</th>
              <th>Destacado</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            {filtered.map((p) => {
              const cat = window.SS_CATEGORIES.find((c) => c.id === p.category)?.name;
              const min = Math.min(...p.presentations.map((pr) => pr.price));
              return (
                <tr key={p.id}>
                  <td>
                    <div className="thumb" style={{overflow: "hidden", background: p.image ? "transparent" : undefined}}>
                      {p.image && <img src={p.image} alt={p.name} style={{width: "100%", height: "100%", objectFit: "cover", display: "block"}}/>}
                    </div>
                  </td>
                  <td>
                    <div style={{fontFamily: "var(--display)", fontSize: 18, fontWeight: 500, color: "var(--moss-3)"}}>{p.name}</div>
                    {p.scientific && <div style={{fontSize: 11, color: "var(--ink-3)", fontStyle: "italic"}}>{p.scientific}</div>}
                  </td>
                  <td><span className="tag">{cat}</span></td>
                  <td><span className="mono" style={{fontSize: 12}}>{p.presentations.length}</span></td>
                  <td className="mono">{fmtPrice(min)}</td>
                  <td>
                    <div className={"switch" + (p.visible !== false ? " is-on" : "")} onClick={() => handleToggleVisible(p.id)} title={p.visible !== false ? "Visible en tienda" : "Oculto en tienda"}></div>
                  </td>
                  <td>
                    <div className={"switch" + (p.featured ? " is-on" : "")} onClick={() => handleToggleFeatured(p.id)}></div>
                  </td>
                  <td>
                    <div className="tbl-actions">
                      <button onClick={() => setEditingId(p.id)}>Editar</button>
                      <button onClick={() => handleDuplicate(p.id)} title="Duplicar producto">Duplicar</button>
                      <button className="danger" onClick={() => handleDelete(p.id)}>Eliminar</button>
                    </div>
                  </td>
                </tr>
              );
            })}
            {filtered.length === 0 && (
              <tr><td colSpan="7" style={{textAlign: "center", padding: 60, color: "var(--ink-3)"}}>No se encontraron productos.</td></tr>
            )}
          </tbody>
        </table>
        </div>
      </div>

      {editingId && (
        <ProductEditor
          store={store}
          productId={editingId === "__new" ? null : editingId}
          onClose={() => setEditingId(null)}
        />
      )}
    </div>
  );
}

// =====================================================================
// PRODUCT EDITOR MODAL
// =====================================================================
function ProductEditor({ store, productId, onClose }) {
  const existing = productId ? store.products.find((p) => p.id === productId) : null;
  const [form, setForm] = useStateA(() => {
    if (existing) {
      // Backward compat: si no tiene gallery, construirla desde image
      const gallery = existing.gallery?.length ? existing.gallery : (existing.image ? [existing.image] : []);
      return { ...existing, gallery, video: existing.video || "" };
    }
    return {
      id: "", name: "", scientific: "", category: "hongos",
      tagline: "", description: "",
      benefits: ["", "", "", ""],
      presentations: [{ id: "gotas", label: "Extracto en gotas — 60 ml", price: 0 }],
      image: "", gallery: [], video: "", featured: false, visible: true,
    };
  });

  const update = (k, v) => setForm((f) => ({ ...f, [k]: v }));
  const updateBenefit = (i, v) => setForm((f) => {
    const benefits = [...f.benefits]; benefits[i] = v; return { ...f, benefits };
  });
  const updatePres = (i, k, v) => setForm((f) => {
    const presentations = [...f.presentations];
    presentations[i] = { ...presentations[i], [k]: k === "price" ? Number(v) : v };
    return { ...f, presentations };
  });
  const addPres = () => setForm((f) => ({ ...f, presentations: [...f.presentations, { id: "p" + (f.presentations.length + 1), label: "", price: 0 }] }));
  const removePres = (i) => setForm((f) => ({ ...f, presentations: f.presentations.filter((_, idx) => idx !== i) }));
  const addBenefit = () => setForm((f) => ({ ...f, benefits: [...f.benefits, ""] }));
  const removeBenefit = (i) => setForm((f) => ({ ...f, benefits: f.benefits.filter((_, idx) => idx !== i) }));

  const [imgUploading, setImgUploading] = useStateA(false);

  // Sube una o varias imágenes y las agrega a la galería
  const handleImageUpload = async (e) => {
    const files = Array.from(e.target.files);
    if (!files.length) return;
    setImgUploading(true);
    try {
      for (const file of files) {
        const url = await uploadImage(file, "productos", 900, 0.82);
        setForm((f) => {
          const gallery = [...(f.gallery || []), url];
          return { ...f, gallery, image: gallery[0] };
        });
      }
    } catch (err) {
      alert("Error al subir imagen: " + err.message);
    } finally {
      setImgUploading(false);
      e.target.value = "";
    }
  };

  const removeFromGallery = (i) => setForm((f) => {
    const gallery = f.gallery.filter((_, idx) => idx !== i);
    return { ...f, gallery, image: gallery[0] || "" };
  });

  const save = () => {
    const cleaned = { ...form, benefits: form.benefits.filter((b) => b.trim()) };
    if (!cleaned.gallery) cleaned.gallery = cleaned.image ? [cleaned.image] : [];
    cleaned.image = cleaned.gallery[0] || "";
    if (!cleaned.id) cleaned.id = window.slug(cleaned.name) || "producto-" + Date.now().toString(36);
    if (existing) {
      store.setProducts(store.products.map((p) => p.id === productId ? cleaned : p));
    } else {
      store.setProducts([cleaned, ...store.products]);
    }
    onClose();
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" style={{maxWidth: 820}} onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <h3>{existing ? "Editar producto" : "Nuevo producto"}</h3>
          <button className="icon-btn" onClick={onClose}><Icon.close width="18" height="18"/></button>
        </div>
        <div className="modal-body">
          <div className="field-row">
            <div className="field">
              <label>Nombre</label>
              <input type="text" value={form.name} onChange={(e) => update("name", e.target.value)}/>
            </div>
            <div className="field">
              <label>Nombre científico</label>
              <input type="text" value={form.scientific} onChange={(e) => update("scientific", e.target.value)}/>
            </div>
          </div>

          <div className="field">
            <label>Categoría</label>
            <select value={form.category} onChange={(e) => update("category", e.target.value)}>
              {window.SS_CATEGORIES.map((c) => <option key={c.id} value={c.id}>{c.name}</option>)}
            </select>
          </div>

          <div className="field">
            <label>Fotos del producto</label>
            <div className="gallery-manager">
              {(form.gallery || []).map((url, i) => (
                <div key={url + i} className="gallery-thumb">
                  <img src={url} alt={`Foto ${i + 1}`}/>
                  {i === 0 && <span className="gallery-main-badge">Principal</span>}
                  <button className="gallery-remove" onClick={() => removeFromGallery(i)} title="Quitar">×</button>
                </div>
              ))}
              <label className={"gallery-add" + (imgUploading ? " is-uploading" : "")}>
                {imgUploading
                  ? <><span className="gallery-spinner"></span><span>Subiendo…</span></>
                  : <><Icon.plus width="18" height="18"/><span>Agregar fotos</span></>}
                <input type="file" accept="image/*" multiple onChange={handleImageUpload} disabled={imgUploading} style={{display: "none"}}/>
              </label>
            </div>
            <p style={{fontSize: 12, color: "var(--ink-3)", margin: "6px 0 0"}}>La primera foto es la imagen principal. Podés subir varias a la vez. Recomendado: 800 × 1000 px.</p>
          </div>

          <div className="field">
            <label>Video del producto (opcional)</label>
            <input type="url" value={form.video || ""} onChange={(e) => update("video", e.target.value)}
              placeholder="Pegá un link de YouTube, Vimeo o .mp4 directo"/>
            {form.video && window.parseVideoUrl && !window.parseVideoUrl(form.video) && (
              <p style={{fontSize: 12, color: "#c0392b", margin: "4px 0 0"}}>⚠ URL no reconocida — verificá que sea un link válido de YouTube, Vimeo o .mp4</p>
            )}
          </div>

          <div className="field">
            <label>Tagline (frase corta)</label>
            <input type="text" value={form.tagline} onChange={(e) => update("tagline", e.target.value)}/>
          </div>

          <div className="field">
            <label>Descripción</label>
            <textarea rows="3" value={form.description} onChange={(e) => update("description", e.target.value)}></textarea>
          </div>

          <div className="field">
            <label>Beneficios</label>
            <div style={{display: "grid", gap: 8}}>
              {form.benefits.map((b, i) => (
                <div key={i} style={{display: "flex", gap: 8}}>
                  <input type="text" value={b} onChange={(e) => updateBenefit(i, e.target.value)} placeholder={`Beneficio ${i + 1}`}/>
                  <button className="btn-ghost btn-danger" onClick={() => removeBenefit(i)} style={{padding: "8px 10px"}}>−</button>
                </div>
              ))}
              <button className="btn-ghost" onClick={addBenefit} style={{justifyContent: "flex-start"}}>+ Agregar beneficio</button>
            </div>
          </div>

          <div className="field">
            <label>Presentaciones y precios</label>
            <div style={{display: "grid", gap: 8}}>
              {form.presentations.map((p, i) => (
                <div key={i} style={{display: "grid", gridTemplateColumns: "100px 1fr 130px 40px", gap: 8}}>
                  <input type="text" value={p.id} onChange={(e) => updatePres(i, "id", e.target.value)} placeholder="id"/>
                  <input type="text" value={p.label} onChange={(e) => updatePres(i, "label", e.target.value)} placeholder="Descripción"/>
                  <input type="number" value={p.price} onChange={(e) => updatePres(i, "price", e.target.value)} placeholder="Precio ARS"/>
                  <button className="btn-ghost btn-danger" onClick={() => removePres(i)} style={{padding: "8px 10px"}}>−</button>
                </div>
              ))}
              <button className="btn-ghost" onClick={addPres} style={{justifyContent: "flex-start"}}>+ Agregar presentación</button>
            </div>
          </div>

          <div className="field" style={{display: "flex", alignItems: "center", gap: 12}}>
            <div className={"switch" + (form.visible !== false ? " is-on" : "")} onClick={() => update("visible", form.visible === false ? true : false)}></div>
            <label style={{margin: 0}}>Visible en la tienda</label>
          </div>
          <div className="field" style={{display: "flex", alignItems: "center", gap: 12}}>
            <div className={"switch" + (form.featured ? " is-on" : "")} onClick={() => update("featured", !form.featured)}></div>
            <label style={{margin: 0}}>Marcar como destacado en la home</label>
          </div>
          <div className="field" style={{display: "flex", alignItems: "center", gap: 12}}>
            <div className={"switch" + (form.promoted ? " is-on" : "")} onClick={() => update("promoted", !form.promoted)}></div>
            <label style={{margin: 0}}>Marcar en promoción (muestra badge "Promo" en la card)</label>
          </div>
        </div>
        <div className="modal-foot">
          <button className="btn-ghost" onClick={onClose}>Cancelar</button>
          <button className="btn-primary" onClick={save}>Guardar producto</button>
        </div>
      </div>
    </div>
  );
}

// =====================================================================
// BANNERS
// =====================================================================
function AdminBanners({ store }) {
  const [editing, setEditing] = useStateA(null);

  const toggleBanner = (id) => {
    store.setBanners(store.banners.map((b) => b.id === id ? { ...b, active: !b.active } : b));
  };
  const removeBanner = (id) => {
    if (confirm("¿Eliminar este banner?")) {
      store.setBanners(store.banners.filter((b) => b.id !== id));
    }
  };

  return (
    <div>
      <div className="admin-head">
        <div>
          <h1>Banners promocionales</h1>
          <div className="sub">Carrusel principal de la home — {store.banners.filter((b) => b.active).length} activos.</div>
        </div>
        <button className="btn-primary" onClick={() => setEditing("__new")}><Icon.plus width="12" height="12"/> Nuevo banner</button>
      </div>

      <div>
        {store.banners.map((b) => (
          <div key={b.id} className="banner-row">
            <div className="banner-swatch" style={{background: `linear-gradient(135deg, ${b.bg}, ${b.accent})`}}></div>
            <div className="banner-row-info">
              <h5>{b.title}</h5>
              <p>{b.eyebrow} · CTA: {b.ctaLabel} → {b.ctaHref}</p>
            </div>
            <div style={{display: "flex", gap: 12, alignItems: "center"}}>
              <div className={"switch" + (b.active ? " is-on" : "")} onClick={() => toggleBanner(b.id)}></div>
              <button className="btn-ghost" onClick={() => setEditing(b.id)}>Editar</button>
              <button className="btn-ghost btn-danger" onClick={() => removeBanner(b.id)}>Eliminar</button>
            </div>
          </div>
        ))}
      </div>

      {editing && (
        <BannerEditor
          store={store}
          bannerId={editing === "__new" ? null : editing}
          onClose={() => setEditing(null)}
        />
      )}
    </div>
  );
}

function BannerEditor({ store, bannerId, onClose }) {
  const existing = bannerId ? store.banners.find((b) => b.id === bannerId) : null;
  const [form, setForm] = useStateA(() => {
    if (existing) {
      const gallery = existing.gallery?.length ? existing.gallery : (existing.image ? [existing.image] : []);
      return { ...existing, gallery, video: existing.video || "" };
    }
    return {
      id: "b" + Date.now().toString(36),
      eyebrow: "Promo", title: "", subtitle: "",
      ctaLabel: "Ver productos", ctaHref: "#catalogo",
      bg: "#2D3B2C", fg: "#F5F0E6", accent: "#D9CCB3",
      image: "", gallery: [], video: "", active: true,
    };
  });
  const update = (k, v) => setForm((f) => ({ ...f, [k]: v }));

  const [bannerImgUploading, setBannerImgUploading] = useStateA(false);
  const [mediaTab, setMediaTab] = useStateA(form.video ? "video" : "images");

  const handleImageUpload = async (e) => {
    const files = Array.from(e.target.files);
    if (!files.length) return;
    setBannerImgUploading(true);
    try {
      for (const file of files) {
        const url = await uploadImage(file, "banners", 1600, 0.80);
        setForm((f) => {
          const gallery = [...(f.gallery || []), url];
          return { ...f, gallery, image: gallery[0] };
        });
      }
    } catch (err) {
      alert("Error al subir imagen: " + err.message);
    } finally {
      setBannerImgUploading(false);
      e.target.value = "";
    }
  };

  const removeBannerImg = (i) => setForm((f) => {
    const gallery = f.gallery.filter((_, idx) => idx !== i);
    return { ...f, gallery, image: gallery[0] || "" };
  });

  const save = () => {
    const saved = { ...form };
    if (!saved.gallery) saved.gallery = saved.image ? [saved.image] : [];
    saved.image = saved.gallery[0] || "";
    if (existing) {
      store.setBanners(store.banners.map((b) => b.id === bannerId ? saved : b));
    } else {
      store.setBanners([...store.banners, saved]);
    }
    onClose();
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <h3>{existing ? "Editar banner" : "Nuevo banner"}</h3>
          <button className="icon-btn" onClick={onClose}><Icon.close width="18" height="18"/></button>
        </div>
        <div className="modal-body">
          {/* Preview */}
          <div style={{
            background: form.bg,
            color: form.fg,
            padding: "32px 28px",
            borderRadius: 8,
            marginBottom: 22,
            position: "relative",
            overflow: "hidden",
            minHeight: form.image ? 160 : "auto",
          }}>
            {form.image && (
              <img src={form.image} alt="" style={{
                position: "absolute", inset: 0, width: "100%", height: "100%",
                objectFit: "cover", opacity: 0.35, pointerEvents: "none",
              }}/>
            )}
            <div style={{position: "relative"}}>
              <div style={{fontSize: 10, letterSpacing: "0.16em", textTransform: "uppercase", opacity: 0.7, marginBottom: 10}}>{form.eyebrow}</div>
              <div style={{fontFamily: "var(--display)", fontSize: 36, lineHeight: 1.05, marginBottom: 8}}>{form.title || "Título del banner"}</div>
              <div style={{fontSize: 14, opacity: 0.85, marginBottom: 16}}>{form.subtitle}</div>
              <span style={{display: "inline-block", padding: "8px 14px", borderRadius: 999, background: form.accent, color: form.bg, fontSize: 11, fontWeight: 600, letterSpacing: "0.06em", textTransform: "uppercase"}}>
                {form.ctaLabel}
              </span>
            </div>
          </div>

          <div className="field">
            <label>Eyebrow (etiqueta superior)</label>
            <input type="text" value={form.eyebrow} onChange={(e) => update("eyebrow", e.target.value)}/>
          </div>
          <div className="field">
            <label>Título</label>
            <input type="text" value={form.title} onChange={(e) => update("title", e.target.value)}/>
          </div>
          <div className="field">
            <label>Subtítulo</label>
            <textarea rows="2" value={form.subtitle} onChange={(e) => update("subtitle", e.target.value)}></textarea>
          </div>
          <div className="field-row">
            <div className="field">
              <label>Texto del botón</label>
              <input type="text" value={form.ctaLabel} onChange={(e) => update("ctaLabel", e.target.value)}/>
            </div>
            <div className="field">
              <label>Link del botón</label>
              <input type="text" value={form.ctaHref} onChange={(e) => update("ctaHref", e.target.value)}/>
            </div>
          </div>
          <div className="field">
            <label>Media de fondo (opcional)</label>
            <div className="chip-row" style={{marginBottom: 10}}>
              <button className={"chip" + (mediaTab === "images" ? " is-active" : "")} onClick={() => setMediaTab("images")}>Imágenes</button>
              <button className={"chip" + (mediaTab === "video" ? " is-active" : "")} onClick={() => setMediaTab("video")}>Video</button>
            </div>
            {mediaTab === "images" ? (
              <>
                <div className="gallery-manager">
                  {(form.gallery || []).map((url, i) => (
                    <div key={url + i} className="gallery-thumb">
                      <img src={url} alt=""/>
                      {i === 0 && <span className="gallery-main-badge">Principal</span>}
                      <button className="gallery-remove" onClick={() => removeBannerImg(i)}>×</button>
                    </div>
                  ))}
                  <label className={"gallery-add" + (bannerImgUploading ? " is-uploading" : "")}>
                    {bannerImgUploading
                      ? <><span className="gallery-spinner"></span><span>Subiendo…</span></>
                      : <><Icon.plus width="18" height="18"/><span>Agregar imágenes</span></>}
                    <input type="file" accept="image/*" multiple onChange={handleImageUpload} disabled={bannerImgUploading} style={{display: "none"}}/>
                  </label>
                </div>
                <p style={{fontSize: 12, color: "var(--ink-3)", margin: "6px 0 0"}}>Recomendado: 1600 × 600 px. La primera imagen se usa como fondo principal.</p>
              </>
            ) : (
              <>
                <input type="url" value={form.video || ""} onChange={(e) => update("video", e.target.value)}
                  placeholder="Pegá un link de YouTube, Vimeo o .mp4 directo"/>
                <p style={{fontSize: 12, color: "var(--ink-3)", margin: "6px 0 0"}}>El video se reproducirá en loop sin sonido como fondo del banner.</p>
              </>
            )}
          </div>
          <div className="field-row-3">
            <div className="field">
              <label>Fondo</label>
              <input type="color" value={form.bg} onChange={(e) => update("bg", e.target.value)} style={{height: 42, padding: 2}}/>
            </div>
            <div className="field">
              <label>Texto</label>
              <input type="color" value={form.fg} onChange={(e) => update("fg", e.target.value)} style={{height: 42, padding: 2}}/>
            </div>
            <div className="field">
              <label>Acento (botón)</label>
              <input type="color" value={form.accent} onChange={(e) => update("accent", e.target.value)} style={{height: 42, padding: 2}}/>
            </div>
          </div>
        </div>
        <div className="modal-foot">
          <button className="btn-ghost" onClick={onClose}>Cancelar</button>
          <button className="btn-primary" onClick={save}>Guardar banner</button>
        </div>
      </div>
    </div>
  );
}

// =====================================================================
// ORDERS
// =====================================================================
// =====================================================================
// REMITO — generador de HTML reutilizable
// =====================================================================
function buildRemitoTableHtml({ numero, fecha, cliente, items, descuentoMode, descuentoPct, descuentoFijo, subtotal, discAmt, total, totalCant, logoUrl }) {
  const rowsHtml = items.map((item, idx) => `
    <tr style="background:${idx % 2 === 0 ? "#f0f4f8" : "#fff"}">
      <td style="text-align:center;border:1px solid #bbb;padding:7px 4px;font-size:12px">${idx + 1}</td>
      <td style="border:1px solid #bbb;padding:7px 10px;font-size:12px">${item.desc || "—"}</td>
      <td style="text-align:center;border:1px solid #bbb;padding:7px 4px;font-size:12px">${item.cant}</td>
      <td style="text-align:right;border:1px solid #bbb;padding:7px 10px;font-size:12px">$${Number(item.unitario).toLocaleString("es-AR")},00</td>
      <td style="text-align:right;border:1px solid #bbb;padding:7px 10px;font-size:12px;font-weight:600">$${(Number(item.cant) * Number(item.unitario)).toLocaleString("es-AR")},00</td>
      <td style="border:1px solid #bbb;padding:7px 6px;font-size:11px;color:#888">${item.lote || ""}</td>
    </tr>`).join("");

  const discountLabel = descuentoMode === "fijo"
    ? `DESCUENTO`
    : `DESCUENTO (${descuentoPct}%)`;
  const discountRows = Number(discAmt) > 0 ? `
    <tr>
      <td colspan="3" style="border:1px solid #bbb;padding:5px 10px;font-size:11px;text-align:right;color:#555">SUBTOTAL</td>
      <td colspan="2" style="border:1px solid #bbb;padding:5px 10px;text-align:right;font-size:12px">$${subtotal.toLocaleString("es-AR")},00</td>
      <td style="border:1px solid #bbb"></td>
    </tr>
    <tr>
      <td colspan="3" style="border:1px solid #bbb;padding:5px 10px;font-size:11px;text-align:right;color:#c0392b">${discountLabel}</td>
      <td colspan="2" style="border:1px solid #bbb;padding:5px 10px;text-align:right;font-size:12px;color:#c0392b">− $${discAmt.toLocaleString("es-AR")},00</td>
      <td style="border:1px solid #bbb"></td>
    </tr>` : "";

  return `<table style="width:100%;border-collapse:collapse;border:2px solid #333;table-layout:fixed">
  <colgroup>
    <col style="width:5%"/><col style="width:38%"/><col style="width:9%"/>
    <col style="width:16%"/><col style="width:16%"/><col style="width:16%"/>
  </colgroup>
  <tr>
    <td colspan="2" rowspan="2" style="border:1px solid #bbb;padding:10px 14px;vertical-align:top">
      <div style="font-weight:700;font-size:15px;text-transform:uppercase">${cliente || "CLIENTE"}</div>
      <div style="font-size:11px;color:#555;margin-top:6px">${fecha}</div>
    </td>
    <td colspan="2" style="border:1px solid #bbb;padding:10px;font-family:monospace;font-size:11px;text-align:center">${numero}</td>
    <td style="border:1px solid #bbb;padding:10px;text-align:center;font-weight:700;font-size:11px;letter-spacing:2px">DESPACHO</td>
    <td rowspan="2" style="border:1px solid #bbb;padding:8px;text-align:center;vertical-align:middle">
      <img src="${logoUrl}" alt="Somos Setas" style="max-height:60px;max-width:100%;display:block;margin:0 auto" onerror="this.style.display='none'"/>
    </td>
  </tr>
  <tr>
    <td colspan="2" style="border:1px solid #bbb;padding:6px"></td>
    <td style="border:1px solid #bbb;padding:6px;text-align:center;font-weight:700;font-size:11px;letter-spacing:2px">CONTROL</td>
  </tr>
  <tr style="background:#e0e0e0">
    <td style="border:1px solid #bbb;padding:8px 10px;font-weight:700;font-size:11px;letter-spacing:1px;text-align:center">N°</td>
    <td style="border:1px solid #bbb;padding:8px 10px;font-weight:700;font-size:11px;letter-spacing:1px">ITEM</td>
    <td style="border:1px solid #bbb;padding:8px 4px;font-weight:700;font-size:11px;letter-spacing:1px;text-align:center">CANT</td>
    <td style="border:1px solid #bbb;padding:8px 10px;font-weight:700;font-size:11px;letter-spacing:1px;text-align:center">UNITARIO</td>
    <td style="border:1px solid #bbb;padding:8px 10px;font-weight:700;font-size:11px;letter-spacing:1px;text-align:center">TOTAL</td>
    <td style="border:1px solid #bbb;padding:8px 6px;font-weight:700;font-size:11px;letter-spacing:1px;text-align:center">LOTE</td>
  </tr>
  ${rowsHtml}${discountRows}
  <tr style="background:#f5c842">
    <td colspan="2" style="border:1px solid #bbb;padding:10px 14px"></td>
    <td style="border:1px solid #bbb;padding:10px 4px;text-align:center;font-weight:700;font-size:18px">${totalCant}</td>
    <td colspan="2" style="border:1px solid #bbb;padding:10px;text-align:right;font-weight:700;font-size:16px">$${total.toLocaleString("es-AR")},00</td>
    <td style="border:1px solid #bbb;padding:8px 6px">
      <div style="font-size:9px;font-weight:700;margin-bottom:3px">TRANSFERENCIAS:</div>
      <div style="font-size:9px">ALIAS: SOMOS.SETAS</div>
      <div style="font-size:9px">BANCO: GALICIA</div>
      <div style="font-size:9px">CUIT-20-32122426-2 JUAN SANTI</div>
    </td>
  </tr>
</table>`;
}

// Genera datos de remito a partir de un pedido (usa el remito guardado si existe,
// sino lo deriva del pedido con descuento del tier)
function buildRemitoFromOrder(order) {
  if (order.remito) return order.remito;
  const items = (order.items || []).map((i, idx) => ({
    id: String(idx + 1),
    desc: `${i.productName} — ${i.presLabel}`,
    cant: i.qty,
    unitario: i.price,
    lote: "",
  }));
  const today = new Date(order.ts);
  const fecha = today.toLocaleDateString("es-AR", { day: "2-digit", month: "2-digit", year: "numeric" });
  const numero = `${today.getFullYear()}${String(today.getMonth()+1).padStart(2,"0")}${String(today.getDate()).padStart(2,"0")}-${order.id.slice(-3).toUpperCase()}`;
  const descuentoPct = (order.tierDiscAmt && order.subtotal) ? Math.round((order.tierDiscAmt / order.subtotal) * 100) : 0;
  const subtotal = items.reduce((s, i) => s + i.cant * i.unitario, 0);
  const discAmt  = Math.round(subtotal * descuentoPct / 100);
  const total    = subtotal - discAmt;
  return { numero, fecha, cliente: order.name || "", items, descuentoMode: "pct", descuentoPct, descuentoFijo: 0, subtotal, discAmt, total };
}

function printRemitos(remitos) {
  const logoUrl = window.location.origin + "/assets/logo-vertical.png";
  const blocks = remitos.map((r, idx) => {
    const totalCant = r.items.reduce((s, i) => s + Number(i.cant), 0);
    const breakStyle = idx < remitos.length - 1 ? "page-break-after:always;margin-bottom:24px" : "";
    return `<div style="${breakStyle}">${buildRemitoTableHtml({ ...r, totalCant, logoUrl })}</div>`;
  }).join("");

  const html = `<!DOCTYPE html><html lang="es"><head><meta charset="UTF-8">
<title>Remitos (${remitos.length})</title>
<style>
  * { margin:0; padding:0; box-sizing:border-box; }
  body { font-family: Arial, Helvetica, sans-serif; font-size:12px; color:#111; padding:24px; }
  @media print { body { padding:8px; } }
</style></head><body>${blocks}
<script>window.onload=function(){window.print();}<\/script>
</body></html>`;

  const win = window.open("", "_blank", "width=900,height=720");
  if (win) { win.document.write(html); win.document.close(); }
}

// =====================================================================
// REMITO MODAL
// =====================================================================
function RemitoModal({ store, onClose, order }) {
  const today = new Date();
  const dateStr = today.toLocaleDateString("es-AR", { day: "2-digit", month: "2-digit", year: "numeric" });

  const genNumero = () => {
    const y = today.getFullYear();
    const m = String(today.getMonth() + 1).padStart(2, "0");
    const d = String(today.getDate()).padStart(2, "0");
    const rnd = String(Math.floor(Math.random() * 900 + 100));
    return `${y}${m}${d}-${rnd}`;
  };

  const calcDiscountPct = () => {
    if (!order) return 0;
    if (order.tierDiscAmt && order.subtotal) return Math.round((order.tierDiscAmt / order.subtotal) * 100);
    return 0;
  };

  const initItems = () => {
    if (order?.remito?.items) return order.remito.items.map((i) => ({ ...i, id: i.id || Math.random().toString(36).slice(2) }));
    if (order?.items) {
      return order.items.map((i, idx) => ({
        id: String(idx + 1),
        desc: `${i.productName} — ${i.presLabel}`,
        cant: i.qty,
        unitario: i.price,
        lote: "",
      }));
    }
    return [{ id: "1", desc: "", cant: 1, unitario: 0, lote: "" }];
  };

  const [cliente, setCliente] = useStateA(order?.remito?.cliente || order?.name || "");
  const [numero, setNumero] = useStateA(order?.remito?.numero || genNumero());
  const [fecha, setFecha] = useStateA(order?.remito?.fecha || dateStr);
  // Descuento puede ser por porcentaje o por monto fijo
  const [descuentoMode, setDescuentoMode]   = useStateA(order?.remito?.descuentoMode || "pct"); // "pct" | "fijo"
  const [descuentoPct,  setDescuentoPct]    = useStateA(order?.remito?.descuentoPct ?? calcDiscountPct());
  const [descuentoFijo, setDescuentoFijo]   = useStateA(order?.remito?.descuentoFijo ?? 0);
  const [items, setItems] = useStateA(initItems);
  const [saved, setSaved] = useStateA(false);

  const subtotal = items.reduce((s, i) => s + Number(i.cant) * Number(i.unitario), 0);
  const discAmt  = descuentoMode === "fijo"
    ? Math.min(Number(descuentoFijo) || 0, subtotal)
    : Math.round(subtotal * Number(descuentoPct) / 100);
  const total    = subtotal - discAmt;
  const totalCant = items.reduce((s, i) => s + Number(i.cant), 0);

  const addItem    = () => setItems((prev) => [...prev, { id: Date.now().toString(), desc: "", cant: 1, unitario: 0, lote: "" }]);
  const removeItem = (id) => setItems((prev) => prev.length > 1 ? prev.filter((i) => i.id !== id) : prev);
  const updateItem = (id, field, val) => setItems((prev) => prev.map((i) => i.id === id ? { ...i, [field]: val } : i));

  const quickFill = (itemId, productId, presId) => {
    const prod = store.products.find((p) => p.id === productId);
    if (!prod) return;
    const pres = prod.presentations.find((p) => p.id === presId) || prod.presentations[0];
    setItems((prev) => prev.map((i) => i.id === itemId
      ? { ...i, desc: `${prod.name} — ${pres?.label || ""}`, unitario: pres?.price || 0 }
      : i));
  };

  const handleSave = () => {
    const remitoData = {
      numero, fecha, cliente, items,
      descuentoMode, descuentoPct: Number(descuentoPct), descuentoFijo: Number(descuentoFijo) || 0,
      subtotal, discAmt, total,
    };
    if (order?.id) store.updateOrderRemito(order.id, remitoData);
    setSaved(true);
    setTimeout(() => setSaved(false), 2000);
  };

  const handlePrint = () => {
    handleSave();
    printRemitos([{
      numero, fecha, cliente, items,
      descuentoMode, descuentoPct: Number(descuentoPct), descuentoFijo: Number(descuentoFijo) || 0,
      subtotal, discAmt, total,
    }]);
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal modal-remito" onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <h3>{order ? `Remito — Pedido ${order.id}` : "Remito Manual"}</h3>
          <button className="icon-btn" onClick={onClose}><Icon.close width="18" height="18"/></button>
        </div>

        <div className="modal-body" style={{ maxHeight: "70vh", overflowY: "auto" }}>
          {/* Encabezado del remito */}
          <div className="field-row" style={{ gap: 10, marginBottom: 12 }}>
            <div className="field" style={{ flex: 2 }}>
              <label>Cliente</label>
              <input type="text" value={cliente} onChange={(e) => setCliente(e.target.value)} placeholder="Nombre del cliente"/>
            </div>
            <div className="field">
              <label>N° Remito</label>
              <input type="text" value={numero} onChange={(e) => setNumero(e.target.value)}/>
            </div>
            <div className="field">
              <label>Fecha</label>
              <input type="text" value={fecha} onChange={(e) => setFecha(e.target.value)}/>
            </div>
          </div>
          <div className="field-row" style={{ gap: 10, marginBottom: 16, alignItems: "flex-end" }}>
            <div className="field" style={{ maxWidth: 200 }}>
              <label>Tipo de descuento</label>
              <div style={{ display: "flex", gap: 6 }}>
                <button
                  type="button"
                  onClick={() => setDescuentoMode("pct")}
                  style={{
                    flex: 1, padding: "8px 10px", fontSize: 12, fontWeight: 600,
                    border: "1.5px solid " + (descuentoMode === "pct" ? "var(--primary)" : "var(--line-2)"),
                    background: descuentoMode === "pct" ? "var(--primary-soft)" : "white",
                    color: descuentoMode === "pct" ? "var(--primary)" : "var(--ink-3)",
                    borderRadius: 6, cursor: "pointer",
                  }}
                >Porcentaje</button>
                <button
                  type="button"
                  onClick={() => setDescuentoMode("fijo")}
                  style={{
                    flex: 1, padding: "8px 10px", fontSize: 12, fontWeight: 600,
                    border: "1.5px solid " + (descuentoMode === "fijo" ? "var(--primary)" : "var(--line-2)"),
                    background: descuentoMode === "fijo" ? "var(--primary-soft)" : "white",
                    color: descuentoMode === "fijo" ? "var(--primary)" : "var(--ink-3)",
                    borderRadius: 6, cursor: "pointer",
                  }}
                >Monto fijo</button>
              </div>
            </div>
            {descuentoMode === "pct" ? (
              <div className="field" style={{ maxWidth: 140 }}>
                <label>Descuento %</label>
                <input type="number" value={descuentoPct} min="0" max="100" step="1" onChange={(e) => setDescuentoPct(e.target.value)}/>
              </div>
            ) : (
              <div className="field" style={{ maxWidth: 180 }}>
                <label>Descuento ($)</label>
                <input type="number" value={descuentoFijo} min="0" step="100" onChange={(e) => setDescuentoFijo(e.target.value)} placeholder="Ej. 5000"/>
              </div>
            )}
          </div>

          {/* Ítems */}
          <div className="remito-items-wrap">
            <div className="remito-items-head">
              <span style={{ flex: 3 }}>Producto / descripción</span>
              <span style={{ width: 64, textAlign: "center" }}>Cant.</span>
              <span style={{ width: 120, textAlign: "right" }}>Precio unit.</span>
              <span style={{ width: 120, textAlign: "right" }}>Total</span>
              <span style={{ width: 72 }}>Lote</span>
              <span style={{ width: 30 }}></span>
            </div>
            {items.map((item) => (
              <div key={item.id} className="remito-item-row">
                <div style={{ flex: 3, display: "flex", flexDirection: "column", gap: 4 }}>
                  <input
                    type="text" value={item.desc}
                    onChange={(e) => updateItem(item.id, "desc", e.target.value)}
                    placeholder="Descripción del producto…" style={{ width: "100%" }}
                  />
                  <select
                    onChange={(e) => { if (!e.target.value) return; const [pid, prid] = e.target.value.split("::"); quickFill(item.id, pid, prid); e.target.value = ""; }}
                    style={{ fontSize: 11, color: "var(--ink-3)" }}
                  >
                    <option value="">— Seleccionar del catálogo —</option>
                    {store.products.filter((p) => p.visible !== false).map((p) =>
                      p.presentations.map((pr) => (
                        <option key={p.id + pr.id} value={`${p.id}::${pr.id}`}>
                          {p.name} — {pr.label} ({fmtPrice(pr.price)})
                        </option>
                      ))
                    )}
                  </select>
                </div>
                <input type="number" value={item.cant} min="1"
                  onChange={(e) => updateItem(item.id, "cant", e.target.value)}
                  style={{ width: 64, textAlign: "center" }}
                />
                <input type="number" value={item.unitario}
                  onChange={(e) => updateItem(item.id, "unitario", e.target.value)}
                  style={{ width: 120, textAlign: "right" }}
                />
                <span style={{ width: 120, textAlign: "right", fontFamily: "var(--mono)", fontSize: 13, fontWeight: 600, display: "flex", alignItems: "center", justifyContent: "flex-end", flexShrink: 0 }}>
                  {fmtPrice(Number(item.cant) * Number(item.unitario))}
                </span>
                <input type="text" value={item.lote}
                  onChange={(e) => updateItem(item.id, "lote", e.target.value)}
                  placeholder="Lote" style={{ width: 72 }}
                />
                <button onClick={() => removeItem(item.id)} style={{ width: 30, background: "none", border: "none", cursor: "pointer", color: "var(--ink-3)", fontSize: 20, lineHeight: 1, flexShrink: 0 }}>×</button>
              </div>
            ))}
            <button className="btn-ghost" onClick={addItem} style={{ marginTop: 8, fontSize: 12 }}>+ Agregar ítem</button>
          </div>

          {/* Preview de totales */}
          <div style={{ display: "flex", justifyContent: "flex-end", marginTop: 16, gap: 20, alignItems: "flex-end" }}>
            {discAmt > 0 && (
              <div style={{ textAlign: "right", fontSize: 13, color: "var(--ink-2)" }}>
                <div>Subtotal: {fmtPrice(subtotal)}</div>
                <div style={{ color: "#c0392b" }}>
                  Descuento {descuentoMode === "pct" ? `(${descuentoPct}%)` : "(monto fijo)"}: − {fmtPrice(discAmt)}
                </div>
              </div>
            )}
            <div style={{ textAlign: "right" }}>
              <div style={{ fontSize: 11, color: "var(--ink-3)", textTransform: "uppercase", letterSpacing: "0.08em" }}>Total</div>
              <div style={{ fontSize: 24, fontWeight: 700, fontFamily: "var(--mono)" }}>{fmtPrice(total)}</div>
            </div>
          </div>
        </div>

        <div className="modal-foot">
          <button className="btn-ghost" onClick={onClose}>Cerrar</button>
          <button className="btn-ghost" onClick={handleSave} style={{ minWidth: 90 }}>{saved ? "✓ Guardado" : "Guardar"}</button>
          <button className="btn-primary" onClick={handlePrint}>Imprimir / PDF</button>
        </div>
      </div>
    </div>
  );
}

// =====================================================================
// ORDERS
// =====================================================================
function AdminOrders({ store }) {
  const [filter, setFilter] = useStateA("todos");
  const [dateFilter, setDateFilter] = useStateA("todos"); // todos | semana | mes | mes-especifico
  const [selectedMonth, setSelectedMonth] = useStateA(""); // "2026-06"
  const [remitoOrderId, setRemitoOrderId] = useStateA(null); // id de pedido con remito abierto
  const [remitoManual, setRemitoManual] = useStateA(false);  // remito manual sin pedido
  const [selectedIds, setSelectedIds] = useStateA(() => new Set()); // ids de pedidos seleccionados

  // Lista de meses únicos en los pedidos (ordenados de más reciente a más antiguo)
  const availableMonths = useMemoA(() => {
    const set = new Set();
    store.orders.forEach((o) => {
      const d = new Date(o.ts);
      set.add(`${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`);
    });
    return Array.from(set).sort().reverse();
  }, [store.orders]);

  const monthLabel = (ym) => {
    const [y, m] = ym.split("-");
    const meses = ["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"];
    return `${meses[parseInt(m,10) - 1]} ${y}`;
  };

  const now = Date.now();
  const WEEK_MS = 7 * 24 * 60 * 60 * 1000;
  const MONTH_MS = 30 * 24 * 60 * 60 * 1000;

  const filtered = store.orders.filter((o) => {
    // Filtro por estado
    if (filter !== "todos" && o.status !== filter) return false;
    // Filtro por fecha
    if (dateFilter === "semana" && (now - o.ts) > WEEK_MS) return false;
    if (dateFilter === "mes" && (now - o.ts) > MONTH_MS) return false;
    if (dateFilter === "mes-especifico" && selectedMonth) {
      const d = new Date(o.ts);
      const ym = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`;
      if (ym !== selectedMonth) return false;
    }
    return true;
  });

  const updateStatus = (id, status) => store.updateOrderStatus(id, status);
  const removeOrder  = (id) => { if (confirm("¿Eliminar este pedido?")) store.deleteOrder(id); };

  const remitoOrder = remitoOrderId ? store.orders.find((o) => o.id === remitoOrderId) : null;

  const toggleSelect = (id) => setSelectedIds((prev) => {
    const next = new Set(prev);
    if (next.has(id)) next.delete(id); else next.add(id);
    return next;
  });

  const allVisibleSelected = filtered.length > 0 && filtered.every((o) => selectedIds.has(o.id));
  const toggleSelectAll = () => setSelectedIds((prev) => {
    if (allVisibleSelected) {
      const next = new Set(prev);
      filtered.forEach((o) => next.delete(o.id));
      return next;
    }
    const next = new Set(prev);
    filtered.forEach((o) => next.add(o.id));
    return next;
  });

  const downloadSelectedRemitos = () => {
    const orders = store.orders.filter((o) => selectedIds.has(o.id));
    if (!orders.length) return;
    // Ordenar por fecha ascendente para que salga en orden cronológico
    orders.sort((a, b) => a.ts - b.ts);
    const remitos = orders.map(buildRemitoFromOrder);
    printRemitos(remitos);
  };

  return (
    <div>
      <div className="admin-head">
        <div>
          <h1>Pedidos</h1>
          <div className="sub">{store.orders.length} pedidos generados.</div>
        </div>
        <div style={{ display: "flex", gap: 8 }}>
          {selectedIds.size > 0 && (
            <button className="btn-primary" onClick={downloadSelectedRemitos} style={{ display: "flex", alignItems: "center", gap: 6 }}>
              Descargar {selectedIds.size} {selectedIds.size === 1 ? "remito" : "remitos"}
            </button>
          )}
          <button className="btn-ghost" onClick={() => setRemitoManual(true)} style={{ display: "flex", alignItems: "center", gap: 6 }}>
            Remito manual
          </button>
        </div>
      </div>

      <div className="panel">
        <div className="panel-head" style={{ flexDirection: "column", alignItems: "stretch", gap: 10 }}>
          <div className="chip-row">
            {["todos", "nuevo", "confirmado", "enviado", "entregado"].map((s) => (
              <button key={s} className={"chip" + (filter === s ? " is-active" : "")} onClick={() => setFilter(s)}>{s}</button>
            ))}
          </div>
          <div className="chip-row" style={{ alignItems: "center" }}>
            <span style={{ fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.08em", color: "var(--ink-3)", marginRight: 4 }}>Fecha:</span>
            <button className={"chip" + (dateFilter === "todos" ? " is-active" : "")} onClick={() => { setDateFilter("todos"); setSelectedMonth(""); }}>Todas</button>
            <button className={"chip" + (dateFilter === "semana" ? " is-active" : "")} onClick={() => { setDateFilter("semana"); setSelectedMonth(""); }}>Última semana</button>
            <button className={"chip" + (dateFilter === "mes" ? " is-active" : "")} onClick={() => { setDateFilter("mes"); setSelectedMonth(""); }}>Último mes</button>
            <select
              value={dateFilter === "mes-especifico" ? selectedMonth : ""}
              onChange={(e) => {
                if (e.target.value) { setDateFilter("mes-especifico"); setSelectedMonth(e.target.value); }
                else { setDateFilter("todos"); setSelectedMonth(""); }
              }}
              style={{ padding: "6px 10px", fontSize: 12, border: "1px solid var(--line-2)", borderRadius: 999, background: dateFilter === "mes-especifico" ? "var(--primary-soft)" : "white", color: dateFilter === "mes-especifico" ? "var(--primary)" : "var(--ink-2)", fontWeight: 600, cursor: "pointer" }}
            >
              <option value="">— Mes específico —</option>
              {availableMonths.map((ym) => <option key={ym} value={ym}>{monthLabel(ym)}</option>)}
            </select>
            <span style={{ marginLeft: "auto", fontSize: 11, color: "var(--ink-3)", fontFamily: "var(--mono)" }}>
              {filtered.length} de {store.orders.length}
            </span>
          </div>
        </div>
        {filtered.length === 0 ? (
          <div style={{ padding: 80, textAlign: "center", color: "var(--ink-3)" }}>
            <h4 className="display" style={{ fontSize: 28, color: "var(--ink)", margin: "0 0 8px" }}>Sin pedidos todavía</h4>
            <p>Los pedidos enviados por WhatsApp aparecerán acá automáticamente.</p>
          </div>
        ) : (
          <div className="tbl-wrap">
          <table className="tbl">
            <thead>
              <tr>
                <th style={{ width: 32 }}>
                  <input
                    type="checkbox"
                    checked={allVisibleSelected}
                    onChange={toggleSelectAll}
                    title={allVisibleSelected ? "Deseleccionar todos" : "Seleccionar todos los visibles"}
                    style={{ cursor: "pointer" }}
                  />
                </th>
                <th>ID</th><th>Fecha</th><th>Cliente</th><th>Items</th><th>Total</th><th>Estado</th><th></th>
              </tr>
            </thead>
            <tbody>
              {filtered.map((o) => (
                <tr key={o.id} style={selectedIds.has(o.id) ? { background: "var(--primary-soft)" } : undefined}>
                  <td>
                    <input
                      type="checkbox"
                      checked={selectedIds.has(o.id)}
                      onChange={() => toggleSelect(o.id)}
                      style={{ cursor: "pointer" }}
                    />
                  </td>
                  <td className="mono" style={{ fontSize: 11 }}>{o.id}</td>
                  <td style={{ fontSize: 12 }}>{new Date(o.ts).toLocaleDateString("es-AR", { day: "2-digit", month: "short", year: "numeric" })}</td>
                  <td>{o.name || "—"}<div style={{ fontSize: 11, color: "var(--ink-3)" }}>{o.city}</div></td>
                  <td>{o.items?.length || 0} líneas / {(o.items || []).reduce((s, i) => s + i.qty, 0)} u.</td>
                  <td className="mono">{fmtPrice(o.total)}</td>
                  <td>
                    <select value={o.status} onChange={(e) => updateStatus(o.id, e.target.value)} style={{ padding: "4px 8px", fontSize: 11, border: "1px solid var(--line-2)", borderRadius: 4 }}>
                      <option value="nuevo">nuevo</option>
                      <option value="confirmado">confirmado</option>
                      <option value="enviado">enviado</option>
                      <option value="entregado">entregado</option>
                    </select>
                  </td>
                  <td>
                    <div className="tbl-actions">
                      <button
                        onClick={() => setRemitoOrderId(o.id)}
                        style={{ background: o.remito ? "var(--primary-soft)" : undefined, color: o.remito ? "var(--primary)" : undefined }}
                        title={o.remito ? "Ver / editar remito" : "Generar remito"}
                      >
                        Remito
                      </button>
                      <button className="danger" onClick={() => removeOrder(o.id)}>Eliminar</button>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
          </div>
        )}
      </div>

      {/* Remito desde pedido */}
      {remitoOrderId && (
        <RemitoModal store={store} order={remitoOrder} onClose={() => setRemitoOrderId(null)}/>
      )}
      {/* Remito manual */}
      {remitoManual && (
        <RemitoModal store={store} order={null} onClose={() => setRemitoManual(false)}/>
      )}
    </div>
  );
}

// =====================================================================
// CONFIG
// =====================================================================
function AdminConfig({ store }) {
  const [form, setForm] = useStateA(store.config);
  const [saved, setSaved] = useStateA(false);
  const save = () => {
    store.setConfig(form);
    setSaved(true);
    setTimeout(() => setSaved(false), 2000);
  };
  const update = (k, v) => setForm((f) => ({ ...f, [k]: v }));
  return (
    <div>
      <div className="admin-head">
        <div>
          <h1>Configuración</h1>
          <div className="sub">Datos generales del sitio.</div>
        </div>
      </div>
      <div className="panel">
        <div className="panel-body">
          <div className="field">
            <label>Número de WhatsApp (formato internacional, sin +)</label>
            <input type="text" value={form.whatsapp} onChange={(e) => update("whatsapp", e.target.value)} placeholder="5492615509004"/>
          </div>
          <div className="field">
            <label>WhatsApp para mostrar al público</label>
            <input type="text" value={form.whatsappDisplay} onChange={(e) => update("whatsappDisplay", e.target.value)}/>
          </div>
          <div className="field">
            <label>Dirección</label>
            <input type="text" value={form.address} onChange={(e) => update("address", e.target.value)}/>
          </div>
          <div className="field-row">
            <div className="field">
              <label>Instagram (usuario, sin @)</label>
              <input type="text" value={form.instagram} onChange={(e) => update("instagram", e.target.value)}/>
            </div>
            <div className="field">
              <label>Sitio web</label>
              <input type="text" value={form.website} onChange={(e) => update("website", e.target.value)}/>
            </div>
          </div>
          <button className="btn-primary" onClick={save}>{saved ? "✓ Guardado" : "Guardar cambios"}</button>
        </div>
      </div>

      <div className="spacer-md"></div>

      <div className="panel">
        <div className="panel-head"><h3>Restablecer datos</h3></div>
        <div className="panel-body">
          <p style={{fontSize: 13, color: "var(--ink-3)", margin: "0 0 14px"}}>Volver a los datos originales del catálogo y banners (no afecta pedidos).</p>
          <button className="btn-ghost btn-danger" onClick={() => {
            if (confirm("¿Restablecer productos y banners a los valores por defecto del catálogo? Tus modificaciones se perderán.")) {
              store.setProducts(window.SS_PRODUCTS);
              store.setBanners(window.SS_DEFAULT_BANNERS);
              store.setConfig(window.SS_DEFAULT_CONFIG);
              alert("Datos restablecidos.");
            }
          }}>Restablecer catálogo y banners</button>
        </div>
      </div>
    </div>
  );
}

// =====================================================================
// DISCOUNT CODES
// =====================================================================
function AdminDiscountCodes({ store }) {
  const [editing, setEditing] = useStateA(null);

  const toggleActive = (id) => {
    store.setDiscountCodes(store.discountCodes.map((c) => c.id === id ? { ...c, active: !c.active } : c));
  };
  const remove = (id) => {
    if (confirm("¿Eliminar este código?")) store.setDiscountCodes(store.discountCodes.filter((c) => c.id !== id));
  };

  const fmtDate = (d) => d ? new Date(d).toLocaleDateString("es-AR", { day: "2-digit", month: "short", year: "numeric" }) : "—";

  return (
    <div>
      <div className="admin-head">
        <div>
          <h1>Códigos de descuento</h1>
          <div className="sub">{store.discountCodes.length} código{store.discountCodes.length !== 1 ? "s" : ""} creado{store.discountCodes.length !== 1 ? "s" : ""}.</div>
        </div>
        <button className="btn-primary" onClick={() => setEditing("__new")}><Icon.plus width="12" height="12"/> Nuevo código</button>
      </div>

      {store.discountCodes.length === 0 ? (
        <div className="panel" style={{padding: "60px 40px", textAlign: "center", color: "var(--ink-3)"}}>
          <p style={{margin: 0}}>Todavía no hay códigos de descuento. Creá el primero.</p>
        </div>
      ) : (
        <div className="tbl-wrap">
          <table className="tbl">
            <thead>
              <tr>
                <th>Código</th>
                <th>Descuento</th>
                <th>Envío</th>
                <th>Mín.</th>
                <th>Usos</th>
                <th>Vigencia</th>
                <th>Estado</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {store.discountCodes.map((c) => {
                const now = new Date();
                const expired = c.expiresAt && new Date(c.expiresAt) < now;
                const notStarted = c.startsAt && new Date(c.startsAt) > now;
                return (
                  <tr key={c.id}>
                    <td>
                      <span className="mono" style={{fontWeight: 700, letterSpacing: "0.08em"}}>{c.code}</span>
                      {c.description && <div style={{fontSize: 11, color: "var(--ink-3)"}}>{c.description}</div>}
                    </td>
                    <td className="mono">
                      {c.type === "fixed" ? fmtPrice(c.value) : `${c.value}%`}
                    </td>
                    <td>{c.appliesToShipping ? <span style={{color:"#2a9d5c", fontWeight:600}}>✓ Sí</span> : "No"}</td>
                    <td className="mono" style={{fontSize:12}}>{c.minSubtotal ? fmtPrice(c.minSubtotal) : "—"}</td>
                    <td style={{fontSize:12}}>{c.usedCount || 0}{c.maxUses ? ` / ${c.maxUses}` : ""}</td>
                    <td style={{fontSize:11}}>
                      {c.startsAt ? <div>Desde: {fmtDate(c.startsAt)}</div> : null}
                      {c.expiresAt ? <div style={{color: expired ? "#c0392b" : "inherit"}}>Hasta: {fmtDate(c.expiresAt)}</div> : <div>Sin vencimiento</div>}
                      {notStarted && <div style={{color:"var(--primary)", fontSize:10, fontWeight:700}}>NO INICIADO</div>}
                      {expired && <div style={{color:"#c0392b", fontSize:10, fontWeight:700}}>VENCIDO</div>}
                    </td>
                    <td>
                      <div className={"switch" + (c.active ? " is-on" : "")} onClick={() => toggleActive(c.id)}></div>
                    </td>
                    <td>
                      <div className="tbl-actions">
                        <button onClick={() => setEditing(c.id)}>Editar</button>
                        <button className="danger" onClick={() => remove(c.id)}>Eliminar</button>
                      </div>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      )}

      {editing && (
        <DiscountCodeEditor
          store={store}
          codeId={editing === "__new" ? null : editing}
          onClose={() => setEditing(null)}
        />
      )}
    </div>
  );
}

function DiscountCodeEditor({ store, codeId, onClose }) {
  const existing = codeId ? store.discountCodes.find((c) => c.id === codeId) : null;
  const [form, setForm] = useStateA(() => existing ? {
    ...existing,
    maxUses: existing.maxUses != null ? String(existing.maxUses) : "",
    minSubtotal: existing.minSubtotal ?? 0,
    startsAt: existing.startsAt || "",
    expiresAt: existing.expiresAt || "",
  } : {
    id: "dc_" + Date.now().toString(36),
    code: "",
    description: "",
    type: "percentage",
    value: 10,
    appliesToShipping: false,
    minSubtotal: 0,
    maxUses: "",
    usedCount: 0,
    active: true,
    startsAt: "",
    expiresAt: "",
  });
  const update = (k, v) => setForm((f) => ({ ...f, [k]: v }));

  const save = () => {
    if (!form.code.trim()) { alert("El código no puede estar vacío"); return; }
    const cleaned = {
      ...form,
      code: form.code.trim().toUpperCase(),
      value: Number(form.value) || 0,
      minSubtotal: Number(form.minSubtotal) || 0,
      maxUses: form.maxUses === "" || form.maxUses == null ? null : Number(form.maxUses),
    };
    if (existing) {
      store.setDiscountCodes(store.discountCodes.map((c) => c.id === codeId ? cleaned : c));
    } else {
      store.setDiscountCodes([...store.discountCodes, cleaned]);
    }
    onClose();
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" style={{maxWidth: 560}} onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <h3>{existing ? "Editar código" : "Nuevo código de descuento"}</h3>
          <button className="icon-btn" onClick={onClose}><Icon.close width="18" height="18"/></button>
        </div>
        <div className="modal-body">
          <div className="field-row">
            <div className="field">
              <label>Código</label>
              <input type="text" value={form.code} onChange={(e) => update("code", e.target.value.toUpperCase())}
                placeholder="Ej. SETAS20" style={{fontFamily: "var(--mono)", fontWeight: 700, letterSpacing: "0.08em"}}/>
            </div>
            <div className="field">
              <label>Descripción interna</label>
              <input type="text" value={form.description} onChange={(e) => update("description", e.target.value)}
                placeholder="Ej. Promo Mayo 2026"/>
            </div>
          </div>

          <div className="field-row">
            <div className="field">
              <label>Tipo de descuento</label>
              <div className="toggle-row">
                <button className={"toggle-opt" + (form.type === "percentage" ? " is-active" : "")} onClick={() => update("type", "percentage")}>Porcentaje (%)</button>
                <button className={"toggle-opt" + (form.type === "fixed" ? " is-active" : "")} onClick={() => update("type", "fixed")}>Monto fijo ($)</button>
              </div>
            </div>
            <div className="field">
              <label>{form.type === "percentage" ? "Porcentaje de descuento" : "Monto de descuento (ARS)"}</label>
              <input type="number" value={form.value} onChange={(e) => update("value", e.target.value)}
                min="0" max={form.type === "percentage" ? "100" : undefined} placeholder={form.type === "percentage" ? "Ej. 20" : "Ej. 5000"}/>
            </div>
          </div>

          <div className="field-row">
            <div className="field">
              <label>Subtotal mínimo para aplicar (ARS)</label>
              <input type="number" value={form.minSubtotal} onChange={(e) => update("minSubtotal", e.target.value)}
                min="0" placeholder="0 = sin mínimo"/>
            </div>
            <div className="field">
              <label>Máximo de usos (vacío = ilimitado)</label>
              <input type="number" value={form.maxUses} onChange={(e) => update("maxUses", e.target.value)}
                min="1" placeholder="Ilimitado"/>
            </div>
          </div>

          <div className="field-row">
            <div className="field">
              <label>Fecha de inicio (opcional)</label>
              <input type="date" value={form.startsAt} onChange={(e) => update("startsAt", e.target.value)}/>
            </div>
            <div className="field">
              <label>Fecha de vencimiento (opcional)</label>
              <input type="date" value={form.expiresAt} onChange={(e) => update("expiresAt", e.target.value)}/>
            </div>
          </div>

          <div className="field" style={{display:"flex", alignItems:"center", gap: 12}}>
            <div className={"switch" + (form.appliesToShipping ? " is-on" : "")} onClick={() => update("appliesToShipping", !form.appliesToShipping)}></div>
            <label style={{margin:0}}>También descuenta / libera el costo de envío</label>
          </div>

          <div className="field" style={{display:"flex", alignItems:"center", gap: 12}}>
            <div className={"switch" + (form.active ? " is-on" : "")} onClick={() => update("active", !form.active)}></div>
            <label style={{margin:0}}>Código activo</label>
          </div>

          {existing && (
            <div style={{padding: "10px 14px", background: "var(--bg-2)", borderRadius: "var(--radius)", fontSize: 12, color: "var(--ink-3)"}}>
              Usos registrados: <strong>{form.usedCount || 0}</strong>
              {form.maxUses ? ` de ${form.maxUses} máximos` : ""}
            </div>
          )}
        </div>
        <div className="modal-foot">
          <button className="btn-ghost" onClick={onClose}>Cancelar</button>
          <button className="btn-primary" onClick={save}>Guardar código</button>
        </div>
      </div>
    </div>
  );
}

// =====================================================================
// ADMIN SHELL / ROUTER
// =====================================================================
function AdminShell({ store, section }) {
  const [sideOpen, setSideOpen] = useStateA(false);

  const items = [
    { id: "dashboard",  label: "Resumen",        href: "#admin" },
    { id: "productos",  label: "Productos",       href: "#admin/productos" },
    { id: "banners",    label: "Banners",         href: "#admin/banners" },
    { id: "pedidos",    label: "Pedidos",         href: "#admin/pedidos" },
    { id: "descuentos", label: "Descuentos",      href: "#admin/descuentos" },
    { id: "config",     label: "Configuración",   href: "#admin/config" },
  ];
  let content;
  if (section === "productos")  content = <AdminProducts store={store}/>;
  else if (section === "banners")    content = <AdminBanners store={store}/>;
  else if (section === "pedidos")    content = <AdminOrders store={store}/>;
  else if (section === "descuentos") content = <AdminDiscountCodes store={store}/>;
  else if (section === "config")     content = <AdminConfig store={store}/>;
  else content = <AdminDashboard store={store}/>;

  return (
    <div className="admin-shell">
      {/* Overlay mobile */}
      {sideOpen && <div className="admin-side-overlay" onClick={() => setSideOpen(false)}/>}

      <aside className={"admin-side" + (sideOpen ? " is-open" : "")}>
        <div className="admin-side-header">
          <a href="#" aria-label="Somos Setas — Inicio">
            <img src="assets/logo-blanco.png" alt="Somos Setas" className="logo-img small"/>
          </a>
          <button className="admin-side-close icon-btn" onClick={() => setSideOpen(false)} aria-label="Cerrar menú">
            <Icon.close width="18" height="18"/>
          </button>
        </div>
        <nav className="admin-nav">
          {items.map((it) => (
            <a key={it.id} href={it.href} style={{textDecoration: "none"}} onClick={() => setSideOpen(false)}>
              <button className={section === it.id || (!section && it.id === "dashboard") ? "is-active" : ""}>
                {it.label}
              </button>
            </a>
          ))}
        </nav>
        <div className="footer-user">
          Panel de administración
          <br/>
          <button onClick={() => { window.sb.auth.signOut(); navigate(""); }}>Cerrar sesión</button>
        </div>
      </aside>

      <main className="admin-main">
        {/* Topbar mobile */}
        <div className="admin-topbar">
          <button className="admin-hamburger icon-btn" onClick={() => setSideOpen(true)} aria-label="Menú">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" width="22" height="22">
              <path d="M3 6h18M3 12h18M3 18h18"/>
            </svg>
          </button>
          <span className="admin-topbar-title">Panel Admin</span>
          <a href="#" className="btn-ghost" style={{fontSize: 11}}>↗ Ver sitio</a>
        </div>
        {content}
      </main>
    </div>
  );
}

// Export
Object.assign(window, {
  AdminLogin, AdminDashboard, AdminProducts, ProductEditor,
  AdminBanners, BannerEditor, AdminOrders, AdminConfig,
  AdminDiscountCodes, DiscountCodeEditor, AdminShell,
});
