// =====================================================================
// 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
// =====================================================================
const REMITO_COLOR = "#ef7911"; // color institucional de la marca para casillas destacadas
const REMITO_LAO_TSE = "\"Nada es más blando o flexible que el agua, pero nada puede resistirla.\"  \"Lao Tsu\"";
const REMITO_DESPACHO_DEFAULT = "DESPACHO PRODUCTO FINAL  R-DPF-BPN.01";

// Convierte índice 0..N en letras A, B, C, ..., Z, AA, AB, ...
function idxToLetter(idx) {
  let n = idx;
  let result = "";
  do {
    result = String.fromCharCode(65 + (n % 26)) + result;
    n = Math.floor(n / 26) - 1;
  } while (n >= 0);
  return result;
}

// Genera el número de remito con formato NN-DDMMYY:
// NN = secuencia del pedido dentro del día (01, 02, ...) según orden cronológico.
// DDMMYY = fecha del pedido. allOrders se usa para calcular la secuencia diaria.
function genRemitoNumero(order, allOrders) {
  const d = order ? new Date(order.ts) : new Date();
  const dd = String(d.getDate()).padStart(2, "0");
  const mm = String(d.getMonth() + 1).padStart(2, "0");
  const yy = String(d.getFullYear()).slice(-2);
  const fechaStr = `${dd}${mm}${yy}`;

  let seq = 1;
  if (order && Array.isArray(allOrders)) {
    const sameDay = allOrders
      .filter((o) => {
        const od = new Date(o.ts);
        return od.getDate() === d.getDate() && od.getMonth() === d.getMonth() && od.getFullYear() === d.getFullYear();
      })
      .sort((a, b) => a.ts - b.ts);
    const idx = sameDay.findIndex((o) => o.id === order.id);
    seq = idx >= 0 ? idx + 1 : sameDay.length + 1;
  }
  return `${String(seq).padStart(2, "0")}-${fechaStr}`;
}

function buildRemitoTableHtml({ numero, fecha, cliente, dni, items, descuentoMode, descuentoPct, descuentoFijo, subtotal, discAmt, total, totalCant, logoUrl, loteGlobal, entregaTipo, shippingCost, datosDespacho, domicilioEntrega, tierDiscAmt, tierName, tierPct, couponDiscAmt, couponCode, couponPct }) {
  const rowsHtml = items.map((item, idx) => {
    const loteShow = item.lote || loteGlobal || "";
    return `
    <tr style="background:${idx % 2 === 0 ? "#f0f4f8" : "#fff"}">
      <td width="28" style="width:28px;text-align:center;border:1px solid #bbb;padding:7px 2px;font-size:12px;font-weight:700">${idxToLetter(idx)}</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">${loteShow}</td>
    </tr>`;
  }).join("");

  // Líneas de descuento dinámicas: cada concepto va por separado (tier, cupón, manual)
  const discountLines = [];
  if (Number(tierDiscAmt) > 0) {
    const pctStr = tierPct ? ` (${tierPct}%)` : "";
    const tierLbl = tierName ? `DESCUENTO ${String(tierName).toUpperCase()}${pctStr}` : `DESCUENTO${pctStr}`;
    discountLines.push({ label: tierLbl, amount: Number(tierDiscAmt) });
  }
  if (Number(couponDiscAmt) > 0) {
    const code = couponCode ? String(couponCode).toUpperCase() : "";
    discountLines.push({ label: code ? `CUPÓN ${code}` : "CUPÓN", amount: Number(couponDiscAmt) });
  }
  // Descuento manual: SOLO se muestra si no hay tier ni cupón (remito manual)
  if (discountLines.length === 0) {
    const manualAmt = descuentoMode === "fijo"
      ? Math.min(Number(descuentoFijo) || 0, subtotal)
      : Math.round(subtotal * Number(descuentoPct) / 100);
    if (manualAmt > 0) {
      const manualLbl = descuentoMode === "fijo" ? "DESCUENTO" : `DESCUENTO (${descuentoPct}%)`;
      discountLines.push({ label: manualLbl, amount: manualAmt });
    }
  }

  // Envío: SIEMPRE se muestra una línea según el tipo de entrega seleccionado.
  const envioLabel = entregaTipo === "domicilio"
    ? "ENVÍO A DOMICILIO"
    : entregaTipo === "local"
      ? "RETIRO EN LOCAL"
      : "ENVÍO A SUCURSAL";
  const envioMonto = Number(shippingCost) || 0;
  const envioValorTxt = envioMonto > 0 ? `+ $${envioMonto.toLocaleString("es-AR")},00` : "GRATIS";
  const envioColor = envioMonto > 0 ? "#1c6cae" : "#2a9d5c";

  const discountRowsHtml = discountLines.map((d) => `
    <tr>
      <td colspan="3" style="border:1px solid #bbb;padding:5px 10px;font-size:11px;text-align:right;color:#c0392b">${d.label}</td>
      <td colspan="2" style="border:1px solid #bbb;padding:5px 10px;text-align:right;font-size:12px;color:#c0392b">− $${d.amount.toLocaleString("es-AR")},00</td>
      <td style="border:1px solid #bbb"></td>
    </tr>`).join("");

  const summaryRows = `
    <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>
    ${discountRowsHtml}
    <tr>
      <td colspan="3" style="border:1px solid #bbb;padding:5px 10px;font-size:11px;text-align:right;color:${envioColor}">${envioLabel}</td>
      <td colspan="2" style="border:1px solid #bbb;padding:5px 10px;text-align:right;font-size:12px;color:${envioColor}">${envioValorTxt}</td>
      <td style="border:1px solid #bbb"></td>
    </tr>`;

  const despachoBlock = (datosDespacho || domicilioEntrega) ? `
<table style="width:100%;border-collapse:collapse;border:2px solid #333;margin-top:12px;table-layout:fixed">
  <colgroup>
    <col style="width:28px"/><col style="width:38%"/><col style="width:8%"/>
    <col style="width:16%"/><col style="width:17%"/><col style="width:20%"/>
  </colgroup>
  <tr style="background:#e0e0e0">
    <td colspan="3" style="border:1px solid #bbb;padding:6px 10px;font-weight:700;font-size:11px;letter-spacing:1px;text-align:center">DATOS DE DESPACHO</td>
    <td colspan="3" style="border:1px solid #bbb;padding:6px 10px;font-weight:700;font-size:11px;letter-spacing:1px;text-align:center">DOMICILIO DE ENTREGA</td>
  </tr>
  <tr>
    <td colspan="3" style="border:1px solid #bbb;padding:10px;font-size:12px;vertical-align:top;white-space:pre-wrap">${datosDespacho || ""}</td>
    <td colspan="3" style="border:1px solid #bbb;padding:10px;font-size:12px;vertical-align:top;white-space:pre-wrap">${domicilioEntrega || ""}</td>
  </tr>
</table>` : "";

  return `<table style="width:100%;border-collapse:collapse;border:2px solid #333;table-layout:fixed">
  <colgroup>
    <col style="width:28px"/><col style="width:38%"/><col style="width:8%"/>
    <col style="width:16%"/><col style="width:17%"/><col style="width:20%"/>
  </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"}${dni ? ` <span style="font-size:11px;font-weight:600;color:#555;text-transform:none">— DNI ${dni}</span>` : ""}</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 width="28" style="width:28px;border:1px solid #bbb;padding:8px 2px;font-weight:700;font-size:11px;letter-spacing:1px;text-align:center">ÍTEM</td>
    <td style="border:1px solid #bbb;padding:8px 10px;font-weight:700;font-size:11px;letter-spacing:1px">DESCRIPCIÓN</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}${summaryRows}
  <tr style="background:${REMITO_COLOR};color:#fff">
    <td colspan="2" style="border:1px solid #bbb;padding:10px 14px;vertical-align:middle">
      <div style="font-size:10px;font-style:italic;line-height:1.4">${REMITO_LAO_TSE}</div>
      ${loteGlobal ? `<div style="margin-top:6px;font-size:10px;font-weight:700;letter-spacing:1px">LOTE GENERAL: <span style="font-weight:700">${loteGlobal}</span></div>` : ""}
    </td>
    <td style="border:1px solid #bbb;padding:10px 4px;text-align:center;font-weight:700;font-size:18px;color:#fff">${totalCant}</td>
    <td colspan="2" style="border:1px solid #bbb;padding:10px;text-align:right;font-weight:700;font-size:16px;color:#fff">$${total.toLocaleString("es-AR")},00</td>
    <td style="border:1px solid #bbb;padding:8px 6px;color:#fff">
      <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>
${despachoBlock}`;
}

// Genera datos de remito a partir de un pedido.
// Si ya existe un remito guardado (order.remito), lo retorna pero garantiza que tenga
// los campos nuevos (datosDespacho default, totales recalculados con shipping, etc).
// Para pedidos sin remito guardado, deriva los valores DIRECTAMENTE del pedido para
// que el remito coincida exactamente con lo que pagó el cliente.
function buildRemitoFromOrder(order, allOrders) {
  // Datos comunes
  const today  = new Date(order.ts);
  const fecha  = today.toLocaleDateString("es-AR", { day: "2-digit", month: "2-digit", year: "numeric" });
  const numero = genRemitoNumero(order, allOrders);
  const domicilioParts = [order.domicilio, order.city, order.postalCode].filter(Boolean);
  const domicilioEntregaAuto = domicilioParts.join(", ");

  // Items SIEMPRE desde los del pedido original (precios reales pagados)
  const items = (order.items || []).map((i, idx) => ({
    id: String(idx + 1),
    desc: `${i.productName} — ${i.presLabel}`,
    cant: i.qty,
    unitario: i.price,
    lote: "",
  }));

  // Subtotal: usar el del pedido si existe (es lo que realmente se calculó), si no, recalcular
  const subtotalOrder = order.subtotal ?? items.reduce((s, i) => s + i.cant * i.unitario, 0);

  // Descuentos separados: tier (mayorista/distribuidor) y cupón van en líneas distintas
  const tierDiscAmt   = order.tierDiscAmt   || 0;
  const couponDiscAmt = order.couponDiscAmt || 0;
  const tierName  = order.tierName  || "";
  const couponCode = order.couponCode || "";
  const tierPct   = (tierDiscAmt   && subtotalOrder) ? Math.round((tierDiscAmt   / subtotalOrder) * 100) : 0;
  const couponPct = (couponDiscAmt && subtotalOrder) ? Math.round((couponDiscAmt / subtotalOrder) * 100) : 0;
  const discAmt   = tierDiscAmt + couponDiscAmt;

  // Envío
  const entregaTipo  = order.entregaTipo  || "sucursal";
  const shippingCost = order.shippingCost || 0;
  const shippingAmt  = entregaTipo === "domicilio" ? shippingCost : 0;

  // Total: el del pedido es la verdad. Si no está, lo reconstruimos.
  const total = order.total ?? (subtotalOrder - discAmt + shippingAmt);

  // Si ya tiene remito guardado, lo respetamos pero garantizamos defaults para los campos nuevos
  if (order.remito) {
    return {
      datosDespacho: REMITO_DESPACHO_DEFAULT,
      tierDiscAmt, tierName, tierPct,
      couponDiscAmt, couponCode, couponPct,
      entregaTipo, shippingCost,
      ...order.remito,
      // Número con el formato NN-DDMMYY (corrige remitos guardados con formato viejo)
      numero,
      dni: order.remito.dni || order.dni || "",
    };
  }

  return {
    numero, fecha,
    cliente: order.name || "", dni: order.dni || "",
    items,
    // Descuento manual = 0 cuando viene de pedido (tier y cupón ya están separados)
    descuentoMode: "pct", descuentoPct: 0, descuentoFijo: 0,
    // Descuentos del pedido para mostrar en líneas separadas
    tierDiscAmt, tierName, tierPct,
    couponDiscAmt, couponCode, couponPct,
    subtotal: subtotalOrder, discAmt, total,
    loteGlobal: "",
    entregaTipo, shippingCost,
    datosDespacho: REMITO_DESPACHO_DEFAULT,
    domicilioEntrega: domicilioEntregaAuto,
  };
}

function downloadRemitosAsExcel(remitos, filename = "remitos.xls") {
  const logoUrl = window.location.origin + "/assets/logo-vertical.png";
  const blocks = remitos.map((r) => {
    const totalCant = r.items.reduce((s, i) => s + Number(i.cant), 0);
    return `${buildRemitoTableHtml({ ...r, totalCant, logoUrl })}<br/><br/>`;
  }).join("");

  const html = `<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40">
<head><meta charset="UTF-8"/>
<!--[if gte mso 9]><xml>
<x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet>
<x:Name>Remitos</x:Name>
<x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions>
</x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook>
</xml><![endif]-->
<style>body{font-family:Arial,Helvetica,sans-serif;font-size:12px;color:#111}</style>
</head><body>${blocks}</body></html>`;

  const blob = new Blob(["﻿" + html], { type: "application/vnd.ms-excel" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = filename;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  setTimeout(() => URL.revokeObjectURL(url), 1000);
}

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" });

  // Número con formato NN-DDMMYY. Si viene de pedido, usa la secuencia diaria; si es manual, 01-DDMMYY de hoy.
  const genNumero = () => genRemitoNumero(order || null, store?.orders);

  // Cuando viene un pedido con tier/cupón, no usamos un descuento manual: cada concepto
  // se muestra como línea separada. Por eso devolvemos 0 acá.
  const calcDiscountPct = () => 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 [dni, setDni]         = useStateA(order?.remito?.dni || order?.dni || "");
  // Siempre con el formato NN-DDMMYY (corrige también remitos guardados con formato viejo)
  const [numero, setNumero] = useStateA(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);
  // Descuentos del pedido (tier y cupón) — se muestran en líneas separadas y no se editan acá
  const tierDiscAmt   = order?.remito?.tierDiscAmt   ?? order?.tierDiscAmt   ?? 0;
  const couponDiscAmt = order?.remito?.couponDiscAmt ?? order?.couponDiscAmt ?? 0;
  const tierName      = order?.remito?.tierName      ?? order?.tierName      ?? "";
  const couponCode    = order?.remito?.couponCode    ?? order?.couponCode    ?? "";
  // Nuevos campos
  const [loteGlobal, setLoteGlobal]               = useStateA(order?.remito?.loteGlobal || "");
  const [entregaTipo, setEntregaTipo]             = useStateA(order?.remito?.entregaTipo || order?.entregaTipo || "sucursal");
  const [shippingCost, setShippingCost]           = useStateA(order?.remito?.shippingCost ?? order?.shippingCost ?? 0);
  const [datosDespacho, setDatosDespacho]         = useStateA(order?.remito?.datosDespacho || "DESPACHO PRODUCTO FINAL  R-DPF-BPN.01");
  const [domicilioEntrega, setDomicilioEntrega]   = useStateA(
    order?.remito?.domicilioEntrega ||
    [order?.domicilio, order?.city, order?.postalCode].filter(Boolean).join(", ") ||
    ""
  );
  const [items, setItems] = useStateA(initItems);
  const [saved, setSaved] = useStateA(false);

  // Cuando cambia el tipo de entrega → ajustar shippingCost por defecto
  useEffectA(() => {
    if (entregaTipo !== "domicilio") {
      setShippingCost(0);
    } else if (Number(shippingCost) === 0) {
      setShippingCost(7500); // valor default envío a domicilio
    }
  }, [entregaTipo]);

  const subtotal = items.reduce((s, i) => s + Number(i.cant) * Number(i.unitario), 0);
  // Cuando hay tier o cupón, IGNORAMOS el descuento manual (es un remito derivado de pedido).
  // El descuento manual solo aplica para remitos manuales sin tier/cupón.
  const hasOrderDiscounts = Number(tierDiscAmt) > 0 || Number(couponDiscAmt) > 0;
  const manualDiscAmt = hasOrderDiscounts ? 0 : (descuentoMode === "fijo"
    ? Math.min(Number(descuentoFijo) || 0, subtotal)
    : Math.round(subtotal * Number(descuentoPct) / 100));
  // discAmt total = tier + cupón + manual (manual=0 cuando hay tier/cupón)
  const discAmt  = Number(tierDiscAmt) + Number(couponDiscAmt) + manualDiscAmt;
  const shippingAmt = entregaTipo === "domicilio" ? Number(shippingCost) || 0 : 0;
  const total    = subtotal - discAmt + shippingAmt;
  const totalCant = items.reduce((s, i) => s + Number(i.cant), 0);
  // Porcentajes para mostrar en líneas separadas
  const tierPct   = (tierDiscAmt   && subtotal) ? Math.round((Number(tierDiscAmt)   / subtotal) * 100) : 0;
  const couponPct = (couponDiscAmt && subtotal) ? Math.round((Number(couponDiscAmt) / subtotal) * 100) : 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 remitoData = () => ({
    numero, fecha, cliente, dni, items,
    descuentoMode, descuentoPct: Number(descuentoPct), descuentoFijo: Number(descuentoFijo) || 0,
    tierDiscAmt: Number(tierDiscAmt) || 0, tierName, tierPct,
    couponDiscAmt: Number(couponDiscAmt) || 0, couponCode, couponPct,
    loteGlobal, entregaTipo, shippingCost: Number(shippingCost) || 0,
    datosDespacho, domicilioEntrega,
    subtotal, discAmt, shippingAmt, total,
  });

  const handleSave = () => {
    if (order?.id) {
      // Sincronizar con el pedido del dashboard: nombre, DNI, total y entrega
      const overrides = {
        name: cliente,
        dni,
        total,
        entregaTipo,
        shippingCost: Number(shippingCost) || 0,
      };
      store.updateOrderRemito(order.id, remitoData(), overrides);
    }
    setSaved(true);
    setTimeout(() => setSaved(false), 2000);
  };

  const handlePrint = () => {
    handleSave();
    printRemitos([remitoData()]);
  };

  const handleExcel = () => {
    handleSave();
    const safeName = (cliente || "remito").replace(/[^a-z0-9]/gi, "_").toLowerCase();
    downloadRemitosAsExcel([remitoData()], `remito_${safeName}_${numero}.xls`);
  };

  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>DNI</label>
              <input type="text" value={dni} onChange={(e) => setDni(e.target.value)} placeholder="Ej. 30.123.456"/>
            </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 className="field">
              <label>N° de lote</label>
              <input type="text" value={loteGlobal} onChange={(e) => setLoteGlobal(e.target.value)} placeholder="Lote general"/>
            </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>

          {/* Tipo de entrega + envío */}
          <div className="field-row" style={{ gap: 10, marginTop: 16, marginBottom: 16, alignItems: "flex-end" }}>
            <div className="field" style={{ maxWidth: 200 }}>
              <label>Tipo de entrega</label>
              <select value={entregaTipo} onChange={(e) => setEntregaTipo(e.target.value)}>
                <option value="sucursal">Sucursal Andreani</option>
                <option value="domicilio">A domicilio</option>
                <option value="local">Retiro en local</option>
              </select>
            </div>
            {entregaTipo === "domicilio" && (
              <div className="field" style={{ maxWidth: 200 }}>
                <label>Costo de envío ($)</label>
                <input type="number" value={shippingCost} min="0" step="100" onChange={(e) => setShippingCost(e.target.value)}/>
              </div>
            )}
          </div>

          {/* Datos de despacho y domicilio */}
          <div className="field-row" style={{ gap: 10, marginBottom: 16 }}>
            <div className="field">
              <label>Datos de despacho</label>
              <textarea rows="3" value={datosDespacho} onChange={(e) => setDatosDespacho(e.target.value)} placeholder="Transportista, número de seguimiento, fecha estimada, observaciones…" style={{ resize: "vertical" }}/>
            </div>
            <div className="field">
              <label>Domicilio de entrega</label>
              <textarea rows="3" value={domicilioEntrega} onChange={(e) => setDomicilioEntrega(e.target.value)} placeholder="Calle, número, piso, depto, localidad, CP…" style={{ resize: "vertical" }}/>
            </div>
          </div>

          {/* Preview de totales */}
          <div style={{ display: "flex", justifyContent: "flex-end", marginTop: 16, gap: 20, alignItems: "flex-end" }}>
            {(discAmt > 0 || shippingAmt > 0) && (
              <div style={{ textAlign: "right", fontSize: 13, color: "var(--ink-2)" }}>
                <div>Subtotal: {fmtPrice(subtotal)}</div>
                {Number(tierDiscAmt) > 0 && (
                  <div style={{ color: "#c0392b" }}>
                    Descuento {tierName || ""}{tierPct ? ` (${tierPct}%)` : ""}: − {fmtPrice(Number(tierDiscAmt))}
                  </div>
                )}
                {Number(couponDiscAmt) > 0 && (
                  <div style={{ color: "#c0392b" }}>
                    Cupón {couponCode}: − {fmtPrice(Number(couponDiscAmt))}
                  </div>
                )}
                {manualDiscAmt > 0 && (
                  <div style={{ color: "#c0392b" }}>
                    Descuento {descuentoMode === "pct" ? `(${descuentoPct}%)` : "(monto fijo)"}: − {fmtPrice(manualDiscAmt)}
                  </div>
                )}
                {shippingAmt > 0 && (
                  <div style={{ color: "#1c6cae" }}>
                    Envío a domicilio: + {fmtPrice(shippingAmt)}
                  </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-ghost" onClick={handleExcel}>Descargar Excel</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((o) => buildRemitoFromOrder(o, store.orders));
    const today = new Date();
    const stamp = `${today.getFullYear()}${String(today.getMonth()+1).padStart(2,"0")}${String(today.getDate()).padStart(2,"0")}`;
    downloadRemitosAsExcel(remitos, `remitos_${stamp}.xls`);
  };

  const printSelectedRemitos = () => {
    const orders = store.orders.filter((o) => selectedIds.has(o.id));
    if (!orders.length) return;
    orders.sort((a, b) => a.ts - b.ts);
    printRemitos(orders.map((o) => buildRemitoFromOrder(o, store.orders)));
  };

  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 && (
            <React.Fragment>
              <button className="btn-ghost" onClick={printSelectedRemitos} style={{ display: "flex", alignItems: "center", gap: 6 }}>
                Imprimir {selectedIds.size}
              </button>
              <button className="btn-primary" onClick={downloadSelectedRemitos} style={{ display: "flex", alignItems: "center", gap: 6 }}>
                Excel ({selectedIds.size} {selectedIds.size === 1 ? "remito" : "remitos"})
              </button>
            </React.Fragment>
          )}
          <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
// =====================================================================
// =====================================================================
// CUSTOMERS — helpers
// =====================================================================
function groupCustomersFromOrders(orders) {
  const map = new Map();
  for (const o of orders) {
    const key = (o.dni || o.email || o.name || "").trim().toLowerCase();
    if (!key) continue;
    if (!map.has(key)) {
      map.set(key, {
        key, name: o.name || "", dni: o.dni || "", email: o.email || "",
        contact: o.contact || "", domicilio: o.domicilio || "", city: o.city || "", postalCode: o.postalCode || "",
        orderCount: 0, totalSpent: 0, totalPaid: 0, totalPending: 0,
        firstOrder: o.ts, lastOrder: o.ts, orders: [],
      });
    }
    const c = map.get(key);
    c.orderCount++;
    const total = Number(o.total) || 0;
    const paid = (o.payments || []).reduce((s, p) => s + (Number(p.monto) || 0), 0);
    c.totalSpent += total;
    c.totalPaid += paid;
    if (o.paymentStatus !== "anulado") c.totalPending += (total - paid);
    if (o.ts < c.firstOrder) c.firstOrder = o.ts;
    if (o.ts > c.lastOrder) {
      c.lastOrder = o.ts;
      // Tomar los datos más recientes del cliente
      if (o.name) c.name = o.name;
      if (o.email) c.email = o.email;
      if (o.contact) c.contact = o.contact;
      if (o.domicilio) c.domicilio = o.domicilio;
      if (o.city) c.city = o.city;
      if (o.postalCode) c.postalCode = o.postalCode;
    }
    c.orders.push(o);
  }
  return Array.from(map.values()).sort((a, b) => b.lastOrder - a.lastOrder);
}

function exportCustomersAsExcel(customers, filename = "clientes.xls") {
  const headers = `<tr style="background:#ef7911;color:#fff;font-weight:700">
    <th style="border:1px solid #888;padding:6px 10px">Nombre</th>
    <th style="border:1px solid #888;padding:6px 10px">DNI</th>
    <th style="border:1px solid #888;padding:6px 10px">Email</th>
    <th style="border:1px solid #888;padding:6px 10px">Contacto</th>
    <th style="border:1px solid #888;padding:6px 10px">Domicilio</th>
    <th style="border:1px solid #888;padding:6px 10px">Localidad</th>
    <th style="border:1px solid #888;padding:6px 10px">CP</th>
    <th style="border:1px solid #888;padding:6px 10px">Pedidos</th>
    <th style="border:1px solid #888;padding:6px 10px">Total comprado</th>
    <th style="border:1px solid #888;padding:6px 10px">Pagado</th>
    <th style="border:1px solid #888;padding:6px 10px">Saldo pendiente</th>
    <th style="border:1px solid #888;padding:6px 10px">Primera compra</th>
    <th style="border:1px solid #888;padding:6px 10px">Última compra</th>
  </tr>`;
  const rows = customers.map(c => `<tr>
    <td style="border:1px solid #bbb;padding:5px 10px">${c.name || "—"}</td>
    <td style="border:1px solid #bbb;padding:5px 10px">${c.dni || ""}</td>
    <td style="border:1px solid #bbb;padding:5px 10px">${c.email || ""}</td>
    <td style="border:1px solid #bbb;padding:5px 10px">${c.contact || ""}</td>
    <td style="border:1px solid #bbb;padding:5px 10px">${c.domicilio || ""}</td>
    <td style="border:1px solid #bbb;padding:5px 10px">${c.city || ""}</td>
    <td style="border:1px solid #bbb;padding:5px 10px">${c.postalCode || ""}</td>
    <td style="border:1px solid #bbb;padding:5px 10px;text-align:center">${c.orderCount}</td>
    <td style="border:1px solid #bbb;padding:5px 10px;text-align:right">$${c.totalSpent.toLocaleString("es-AR")}</td>
    <td style="border:1px solid #bbb;padding:5px 10px;text-align:right;color:#2a9d5c">$${c.totalPaid.toLocaleString("es-AR")}</td>
    <td style="border:1px solid #bbb;padding:5px 10px;text-align:right;color:#c0392b">$${c.totalPending.toLocaleString("es-AR")}</td>
    <td style="border:1px solid #bbb;padding:5px 10px">${new Date(c.firstOrder).toLocaleDateString("es-AR")}</td>
    <td style="border:1px solid #bbb;padding:5px 10px">${new Date(c.lastOrder).toLocaleDateString("es-AR")}</td>
  </tr>`).join("");

  const html = `<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40">
<head><meta charset="UTF-8"/>
<!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet>
<x:Name>Clientes</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions>
</x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]-->
</head><body><table style="border-collapse:collapse;font-family:Arial,sans-serif;font-size:12px">
${headers}${rows}</table></body></html>`;
  const blob = new Blob(["﻿" + html], { type: "application/vnd.ms-excel" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a"); a.href = url; a.download = filename;
  document.body.appendChild(a); a.click(); document.body.removeChild(a);
  setTimeout(() => URL.revokeObjectURL(url), 1000);
}

// =====================================================================
// CLIENTES
// =====================================================================
function AdminClientes({ store }) {
  const [search, setSearch] = useStateA("");
  const [selectedKeys, setSelectedKeys] = useStateA(() => new Set());

  const customers = useMemoA(() => groupCustomersFromOrders(store.orders), [store.orders]);
  const filtered = useMemoA(() => {
    if (!search.trim()) return customers;
    const q = search.toLowerCase();
    return customers.filter(c =>
      (c.name || "").toLowerCase().includes(q) ||
      (c.dni || "").toLowerCase().includes(q) ||
      (c.email || "").toLowerCase().includes(q) ||
      (c.contact || "").toLowerCase().includes(q) ||
      (c.city || "").toLowerCase().includes(q)
    );
  }, [customers, search]);

  const toggle = (key) => setSelectedKeys(prev => {
    const next = new Set(prev);
    if (next.has(key)) next.delete(key); else next.add(key);
    return next;
  });
  const allVisibleSelected = filtered.length > 0 && filtered.every(c => selectedKeys.has(c.key));
  const toggleAll = () => setSelectedKeys(prev => {
    if (allVisibleSelected) { const n = new Set(prev); filtered.forEach(c => n.delete(c.key)); return n; }
    const n = new Set(prev); filtered.forEach(c => n.add(c.key)); return n;
  });

  const exportSelected = () => {
    const selected = customers.filter(c => selectedKeys.has(c.key));
    if (!selected.length) return;
    const stamp = new Date().toISOString().slice(0, 10).replace(/-/g, "");
    exportCustomersAsExcel(selected, `clientes_${stamp}.xls`);
  };
  const exportAll = () => {
    const stamp = new Date().toISOString().slice(0, 10).replace(/-/g, "");
    exportCustomersAsExcel(customers, `clientes_todos_${stamp}.xls`);
  };

  return (
    <div>
      <div className="admin-head">
        <div>
          <h1>Clientes</h1>
          <div className="sub">{customers.length} clientes únicos derivados de los pedidos.</div>
        </div>
        <div style={{ display: "flex", gap: 8 }}>
          {selectedKeys.size > 0 && (
            <button className="btn-primary" onClick={exportSelected}>
              Exportar {selectedKeys.size} seleccionados
            </button>
          )}
          <button className="btn-ghost" onClick={exportAll}>Exportar todos</button>
        </div>
      </div>

      <div className="panel">
        <div className="panel-head">
          <input
            type="text" placeholder="Buscar por nombre, DNI, email, contacto…"
            value={search} onChange={(e) => setSearch(e.target.value)}
            style={{border: "1px solid var(--line-2)", borderRadius: 6, padding: "8px 12px", fontSize: 13, width: 360}}
          />
          <span style={{ marginLeft: "auto", fontSize: 11, color: "var(--ink-3)", fontFamily: "var(--mono)" }}>
            {filtered.length} de {customers.length}
          </span>
        </div>
        {customers.length === 0 ? (
          <div style={{ padding: 60, textAlign: "center", color: "var(--ink-3)" }}>
            <p>No hay clientes todavía. Los pedidos generarán clientes automáticamente.</p>
          </div>
        ) : (
          <div className="tbl-wrap">
            <table className="tbl">
              <thead>
                <tr>
                  <th style={{ width: 32 }}>
                    <input type="checkbox" checked={allVisibleSelected} onChange={toggleAll} style={{ cursor: "pointer" }}/>
                  </th>
                  <th>Cliente</th>
                  <th>DNI</th>
                  <th>Email</th>
                  <th>Contacto</th>
                  <th style={{ textAlign: "right" }}>Pedidos</th>
                  <th style={{ textAlign: "right" }}>Total</th>
                  <th style={{ textAlign: "right" }}>Pagado</th>
                  <th style={{ textAlign: "right" }}>Saldo</th>
                  <th>Última compra</th>
                </tr>
              </thead>
              <tbody>
                {filtered.map(c => (
                  <tr key={c.key} style={selectedKeys.has(c.key) ? { background: "var(--primary-soft)" } : undefined}>
                    <td>
                      <input type="checkbox" checked={selectedKeys.has(c.key)} onChange={() => toggle(c.key)} style={{ cursor: "pointer" }}/>
                    </td>
                    <td>
                      <div style={{ fontWeight: 600 }}>{c.name || "—"}</div>
                      <div style={{ fontSize: 11, color: "var(--ink-3)" }}>{c.city}</div>
                    </td>
                    <td className="mono" style={{ fontSize: 11 }}>{c.dni || "—"}</td>
                    <td style={{ fontSize: 12 }}>{c.email || "—"}</td>
                    <td style={{ fontSize: 12 }}>{c.contact || "—"}</td>
                    <td style={{ textAlign: "right" }} className="mono">{c.orderCount}</td>
                    <td style={{ textAlign: "right" }} className="mono">{fmtPrice(c.totalSpent)}</td>
                    <td style={{ textAlign: "right", color: "#2a9d5c" }} className="mono">{fmtPrice(c.totalPaid)}</td>
                    <td style={{ textAlign: "right", color: c.totalPending > 0 ? "#c0392b" : "var(--ink-3)", fontWeight: c.totalPending > 0 ? 700 : 400 }} className="mono">
                      {fmtPrice(c.totalPending)}
                    </td>
                    <td style={{ fontSize: 12 }}>{new Date(c.lastOrder).toLocaleDateString("es-AR", { day: "2-digit", month: "short", year: "numeric" })}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>
    </div>
  );
}

// =====================================================================
// CUENTA CORRIENTE
// =====================================================================
function AdminCuentaCorriente({ store }) {
  const [selectedCustomerKey, setSelectedCustomerKey] = useStateA(null);
  const [monthFilter, setMonthFilter] = useStateA("todos"); // "todos" | "YYYY-MM"
  const [filterSaldo, setFilterSaldo] = useStateA("todos"); // "todos" | "con-saldo" | "sin-saldo"

  const customers = useMemoA(() => groupCustomersFromOrders(store.orders), [store.orders]);

  // Meses con pedidos
  const months = 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 = ["Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"];
    return `${meses[parseInt(m,10)-1]} ${y}`;
  };

  const filteredCustomers = useMemoA(() => {
    let list = customers;
    // Si filtramos por mes, recalculamos los totales SOLO con pedidos de ese mes
    // y excluimos clientes sin pedidos en el período.
    if (monthFilter !== "todos") {
      const recalc = [];
      customers.forEach(c => {
        const ordersInMonth = c.orders.filter(o => {
          const d = new Date(o.ts);
          return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,"0")}` === monthFilter;
        });
        if (ordersInMonth.length === 0) return;
        let totalSpent = 0, totalPaid = 0, totalPending = 0;
        ordersInMonth.forEach(o => {
          const total = Number(o.total) || 0;
          const paid = (o.payments || []).reduce((s, p) => s + (Number(p.monto) || 0), 0);
          if (o.paymentStatus === "anulado") return;
          totalSpent  += total;
          totalPaid   += paid;
          totalPending += (total - paid);
        });
        recalc.push({ ...c, orderCount: ordersInMonth.length, totalSpent, totalPaid, totalPending });
      });
      list = recalc;
    }
    return list.filter(c => {
      if (filterSaldo === "con-saldo" && c.totalPending <= 0) return false;
      if (filterSaldo === "sin-saldo" && c.totalPending > 0) return false;
      return true;
    });
  }, [customers, filterSaldo, monthFilter]);

  const selectedCustomer = customers.find(c => c.key === selectedCustomerKey);

  // Totales del mes seleccionado
  const monthTotals = useMemoA(() => {
    if (monthFilter === "todos") return null;
    const monthOrders = store.orders.filter(o => {
      const d = new Date(o.ts);
      return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,"0")}` === monthFilter;
    });
    let ventas = 0, cobrado = 0, pendiente = 0, efectivo = 0, transferencia = 0, anulado = 0;
    monthOrders.forEach(o => {
      if (o.paymentStatus === "anulado") { anulado++; return; }
      const total = Number(o.total) || 0;
      ventas += total;
      const paid = (o.payments || []).reduce((s, p) => s + (Number(p.monto)||0), 0);
      cobrado += paid;
      pendiente += (total - paid);
      (o.payments || []).forEach(p => {
        if (p.metodo === "Efectivo") efectivo += Number(p.monto)||0;
        else if (p.metodo === "Transferencia") transferencia += Number(p.monto)||0;
      });
    });
    return { ventas, cobrado, pendiente, efectivo, transferencia, anulado, count: monthOrders.length };
  }, [store.orders, monthFilter]);

  return (
    <div>
      <div className="admin-head">
        <div>
          <h1>Cuenta corriente</h1>
          <div className="sub">Saldos pendientes por cliente — ventas y pagos por mes.</div>
        </div>
      </div>

      {/* Filtros y resumen mensual */}
      <div className="panel">
        <div className="panel-head" style={{ flexDirection: "column", alignItems: "stretch", gap: 10 }}>
          <div className="chip-row" style={{ alignItems: "center" }}>
            <span style={{ fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.08em", color: "var(--ink-3)" }}>Mes:</span>
            <button className={"chip" + (monthFilter === "todos" ? " is-active" : "")} onClick={() => setMonthFilter("todos")}>Todos</button>
            {months.slice(0, 6).map(ym => (
              <button key={ym} className={"chip" + (monthFilter === ym ? " is-active" : "")} onClick={() => setMonthFilter(ym)}>{monthLabel(ym)}</button>
            ))}
            <span style={{ fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.08em", color: "var(--ink-3)", marginLeft: 16 }}>Saldo:</span>
            <button className={"chip" + (filterSaldo === "todos" ? " is-active" : "")} onClick={() => setFilterSaldo("todos")}>Todos</button>
            <button className={"chip" + (filterSaldo === "con-saldo" ? " is-active" : "")} onClick={() => setFilterSaldo("con-saldo")}>Con deuda</button>
            <button className={"chip" + (filterSaldo === "sin-saldo" ? " is-active" : "")} onClick={() => setFilterSaldo("sin-saldo")}>Saldadas</button>
          </div>
        </div>
        {monthTotals && (
          <div style={{ padding: "16px 24px", borderBottom: "1px solid var(--line)", display: "grid", gridTemplateColumns: "repeat(6, 1fr)", gap: 12, background: "var(--bg-2)" }}>
            <CCStat label="Ventas mes" value={fmtPrice(monthTotals.ventas)}/>
            <CCStat label="Cobrado"    value={fmtPrice(monthTotals.cobrado)} color="#2a9d5c"/>
            <CCStat label="Pendiente"  value={fmtPrice(monthTotals.pendiente)} color="#c0392b"/>
            <CCStat label="Efectivo"   value={fmtPrice(monthTotals.efectivo)}/>
            <CCStat label="Transfer."  value={fmtPrice(monthTotals.transferencia)}/>
            <CCStat label="Anulados"   value={String(monthTotals.anulado)}/>
          </div>
        )}

        {/* Layout: lista de clientes + detalle */}
        <div style={{ display: "grid", gridTemplateColumns: selectedCustomer ? "320px 1fr" : "1fr", minHeight: 400 }}>
          <div style={{ borderRight: selectedCustomer ? "1px solid var(--line)" : "none", overflowY: "auto", maxHeight: 600 }}>
            {filteredCustomers.length === 0 ? (
              <div style={{ padding: 40, textAlign: "center", color: "var(--ink-3)", fontSize: 13 }}>Sin clientes para mostrar.</div>
            ) : filteredCustomers.map(c => (
              <button
                key={c.key}
                onClick={() => setSelectedCustomerKey(c.key)}
                style={{
                  display: "block", width: "100%", textAlign: "left",
                  padding: "12px 16px", border: "none", borderBottom: "1px solid var(--line)",
                  background: selectedCustomerKey === c.key ? "var(--primary-soft)" : "white",
                  cursor: "pointer", fontFamily: "inherit",
                }}
              >
                <div style={{ fontWeight: 600, fontSize: 13 }}>{c.name || "—"}</div>
                <div style={{ fontSize: 11, color: "var(--ink-3)", marginTop: 2 }}>{c.dni && `DNI ${c.dni} · `}{c.orderCount} pedido{c.orderCount !== 1 ? "s" : ""}</div>
                <div style={{ display: "flex", justifyContent: "space-between", marginTop: 6 }}>
                  <span style={{ fontSize: 11, color: "var(--ink-3)" }}>Saldo</span>
                  <span className="mono" style={{ fontSize: 12, fontWeight: 700, color: c.totalPending > 0 ? "#c0392b" : "#2a9d5c" }}>
                    {fmtPrice(c.totalPending)}
                  </span>
                </div>
              </button>
            ))}
          </div>

          {selectedCustomer && (
            <CustomerAccountDetail
              customer={selectedCustomer}
              monthFilter={monthFilter}
              store={store}
              onClose={() => setSelectedCustomerKey(null)}
            />
          )}
        </div>
      </div>
    </div>
  );
}

function CCStat({ label, value, color }) {
  return (
    <div>
      <div style={{ fontSize: 10, color: "var(--ink-3)", textTransform: "uppercase", letterSpacing: "0.08em", fontWeight: 700 }}>{label}</div>
      <div className="mono" style={{ fontSize: 16, fontWeight: 700, color: color || "var(--ink)", marginTop: 2 }}>{value}</div>
    </div>
  );
}

function CustomerAccountDetail({ customer, monthFilter, store, onClose }) {
  const [paymentOrderId, setPaymentOrderId] = useStateA(null);

  // Filtrar pedidos del cliente por mes si aplica
  const orders = useMemoA(() => {
    let list = [...customer.orders].sort((a, b) => b.ts - a.ts);
    if (monthFilter !== "todos") {
      list = list.filter(o => {
        const d = new Date(o.ts);
        return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,"0")}` === monthFilter;
      });
    }
    return list;
  }, [customer.orders, monthFilter]);

  const paymentOrder = paymentOrderId ? store.orders.find(o => o.id === paymentOrderId) : null;

  return (
    <div style={{ padding: 24 }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 16 }}>
        <div>
          <h3 style={{ fontFamily: "var(--display)", fontSize: 22, fontWeight: 500, margin: 0 }}>{customer.name}</h3>
          <div style={{ fontSize: 12, color: "var(--ink-3)", marginTop: 4 }}>
            {customer.dni && <span>DNI {customer.dni} · </span>}
            {customer.email && <span>{customer.email} · </span>}
            {customer.contact && <span>{customer.contact}</span>}
          </div>
          {(customer.domicilio || customer.city) && (
            <div style={{ fontSize: 12, color: "var(--ink-3)" }}>
              📍 {[customer.domicilio, customer.city, customer.postalCode].filter(Boolean).join(", ")}
            </div>
          )}
        </div>
        <button className="icon-btn" onClick={onClose}><Icon.close width="16" height="16"/></button>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 12, marginBottom: 16 }}>
        <CCStat label="Total comprado" value={fmtPrice(customer.totalSpent)}/>
        <CCStat label="Total pagado"   value={fmtPrice(customer.totalPaid)} color="#2a9d5c"/>
        <CCStat label="Saldo pendiente" value={fmtPrice(customer.totalPending)} color={customer.totalPending > 0 ? "#c0392b" : "#2a9d5c"}/>
      </div>

      {orders.length === 0 ? (
        <div style={{ padding: 30, textAlign: "center", color: "var(--ink-3)" }}>Sin pedidos en el período seleccionado.</div>
      ) : (
        <div className="tbl-wrap">
          <table className="tbl">
            <thead><tr>
              <th>Fecha</th><th>Remito</th><th style={{textAlign:"right"}}>Monto</th>
              <th style={{textAlign:"right"}}>Pagado</th><th style={{textAlign:"right"}}>Saldo</th>
              <th>Estado</th><th></th>
            </tr></thead>
            <tbody>
              {orders.map(o => {
                const total = Number(o.total) || 0;
                const paid = (o.payments || []).reduce((s, p) => s + (Number(p.monto)||0), 0);
                const saldo = total - paid;
                const status = o.paymentStatus || (saldo === 0 ? "pagado" : paid > 0 ? "parcial" : "pendiente");
                const statusColor = { pagado: "#2a9d5c", parcial: "#e8a317", pendiente: "#c0392b", anulado: "var(--ink-3)" }[status] || "var(--ink-3)";
                return (
                  <tr key={o.id}>
                    <td style={{ fontSize: 12 }}>{new Date(o.ts).toLocaleDateString("es-AR", {day:"2-digit", month:"short", year:"2-digit"})}</td>
                    <td className="mono" style={{ fontSize: 11 }}>{o.remito?.numero || o.id}</td>
                    <td className="mono" style={{ textAlign: "right" }}>{fmtPrice(total)}</td>
                    <td className="mono" style={{ textAlign: "right", color: "#2a9d5c" }}>{fmtPrice(paid)}</td>
                    <td className="mono" style={{ textAlign: "right", fontWeight: saldo > 0 ? 700 : 400, color: saldo > 0 ? "#c0392b" : "var(--ink-3)" }}>{fmtPrice(saldo)}</td>
                    <td><span style={{ fontSize: 11, fontWeight: 700, textTransform: "uppercase", color: statusColor }}>{status}</span></td>
                    <td>
                      <button
                        onClick={() => setPaymentOrderId(o.id)}
                        style={{
                          fontSize: 11, fontWeight: 700, letterSpacing: "0.04em",
                          padding: "6px 14px", borderRadius: 6,
                          border: "1.5px solid var(--primary)",
                          background: status === "pagado" ? "transparent" : "var(--primary)",
                          color: status === "pagado" ? "var(--primary)" : "white",
                          cursor: "pointer", textTransform: "uppercase",
                        }}
                      >
                        {status === "pagado" ? "Ver pagos" : "Registrar pago"}
                      </button>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      )}

      {paymentOrder && (
        <PaymentModal order={paymentOrder} store={store} onClose={() => setPaymentOrderId(null)}/>
      )}
    </div>
  );
}

function PaymentModal({ order, store, onClose }) {
  const [payments, setPayments] = useStateA(order.payments || []);
  const [paymentStatus, setPaymentStatus] = useStateA(order.paymentStatus || "pendiente");
  const [adminNotes, setAdminNotes] = useStateA(order.adminNotes || "");
  const [saved, setSaved] = useStateA(false);

  const total = Number(order.total) || 0;
  const totalPaid = payments.reduce((s, p) => s + (Number(p.monto)||0), 0);
  const saldo = total - totalPaid;

  const addPayment = () => setPayments(prev => [...prev, {
    ts: Date.now(),
    fecha: new Date().toLocaleDateString("es-AR", {day:"2-digit", month:"2-digit", year:"numeric"}),
    monto: saldo > 0 ? saldo : 0,
    metodo: "Transferencia",
    notas: "",
  }]);
  const updatePay = (idx, field, val) => setPayments(prev => prev.map((p, i) => i === idx ? { ...p, [field]: val } : p));
  const removePay = (idx) => setPayments(prev => prev.filter((_, i) => i !== idx));

  // Auto-derivar status según saldo
  useEffectA(() => {
    if (paymentStatus === "anulado") return;
    if (saldo <= 0 && totalPaid > 0) setPaymentStatus("pagado");
    else if (totalPaid > 0) setPaymentStatus("parcial");
    else setPaymentStatus("pendiente");
  }, [totalPaid, saldo]);

  const save = () => {
    store.updateOrderPayments(order.id, {
      payments: payments.map(p => ({ ...p, monto: Number(p.monto) || 0 })),
      paymentStatus,
      adminNotes,
    });
    setSaved(true);
    setTimeout(() => setSaved(false), 1500);
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()} style={{ maxWidth: 720 }}>
        <div className="modal-head">
          <h3>Pagos — {order.remito?.numero || order.id}</h3>
          <button className="icon-btn" onClick={onClose}><Icon.close width="18" height="18"/></button>
        </div>
        <div className="modal-body">
          <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 12, marginBottom: 20 }}>
            <CCStat label="Monto total" value={fmtPrice(total)}/>
            <CCStat label="Pagado" value={fmtPrice(totalPaid)} color="#2a9d5c"/>
            <CCStat label="Saldo" value={fmtPrice(saldo)} color={saldo > 0 ? "#c0392b" : "#2a9d5c"}/>
          </div>

          <div className="field">
            <label>Estado del pago</label>
            <select value={paymentStatus} onChange={(e) => setPaymentStatus(e.target.value)}>
              <option value="pendiente">Pendiente</option>
              <option value="parcial">Pago parcial</option>
              <option value="pagado">Pagado</option>
              <option value="anulado">Anulado</option>
            </select>
          </div>

          <div style={{ marginTop: 16 }}>
            <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 8 }}>
              <strong>Pagos registrados</strong>
              <button className="btn-ghost" onClick={addPayment} style={{ fontSize: 12 }}>+ Agregar pago</button>
            </div>
            {payments.length === 0 ? (
              <p style={{ fontSize: 12, color: "var(--ink-3)" }}>No hay pagos registrados.</p>
            ) : (
              <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                {payments.map((p, i) => (
                  <div key={i} style={{ display: "grid", gridTemplateColumns: "110px 1fr 1fr 1.5fr 30px", gap: 6, alignItems: "center", padding: 8, border: "1px solid var(--line)", borderRadius: 6 }}>
                    <input type="text" value={p.fecha} onChange={(e) => updatePay(i, "fecha", e.target.value)} placeholder="dd/mm/aaaa" style={{ fontSize: 12 }}/>
                    <input type="number" value={p.monto} onChange={(e) => updatePay(i, "monto", e.target.value)} placeholder="Monto" style={{ fontSize: 12, textAlign: "right" }}/>
                    <select value={p.metodo} onChange={(e) => updatePay(i, "metodo", e.target.value)} style={{ fontSize: 12 }}>
                      <option value="Transferencia">Transferencia</option>
                      <option value="Efectivo">Efectivo</option>
                      <option value="MercadoPago">MercadoPago</option>
                      <option value="Otro">Otro</option>
                    </select>
                    <input type="text" value={p.notas} onChange={(e) => updatePay(i, "notas", e.target.value)} placeholder="Notas" style={{ fontSize: 12 }}/>
                    <button onClick={() => removePay(i)} style={{ background: "none", border: "none", color: "var(--ink-3)", cursor: "pointer", fontSize: 18 }}>×</button>
                  </div>
                ))}
              </div>
            )}
          </div>

          <div className="field" style={{ marginTop: 16 }}>
            <label>Notas administrativas</label>
            <textarea rows="2" value={adminNotes} onChange={(e) => setAdminNotes(e.target.value)} placeholder="Observaciones internas…"/>
          </div>
        </div>
        <div className="modal-foot">
          <button className="btn-ghost" onClick={onClose}>Cerrar</button>
          <button className="btn-primary" onClick={save}>{saved ? "✓ Guardado" : "Guardar pagos"}</button>
        </div>
      </div>
    </div>
  );
}

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: "clientes",    label: "Clientes",        href: "#admin/clientes" },
    { id: "cuenta",      label: "Cuenta corriente",href: "#admin/cuenta" },
    { 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 === "clientes")   content = <AdminClientes store={store}/>;
  else if (section === "cuenta")     content = <AdminCuentaCorriente 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,
});
