/* ============================================================
   INside Cotizador Pro — Catálogo (Módulo A)
   ============================================================ */

function CatalogView() {
  const { products, settings, adminMode, updateProduct, addProduct, removeProduct, clearAllProducts, addItemToQuote, currentItems } =
    React.useContext(window.AppCtx);
  const [filter, setFilter] = React.useState("ALL");
  const [search, setSearch] = React.useState("");
  const [editing, setEditing] = React.useState(null); // {id, field}
  const [showNew, setShowNew] = React.useState(false);
  const [confirm, setConfirm] = React.useState(null);
  const fileRef = React.useRef(null);

  const cats = window.AppData.CATEGORIES;
  const inQuote = new Set((currentItems || []).map((i) => i.product_id));

  const filtered = products.filter((p) => {
    if (filter !== "ALL" && p.category !== filter) return false;
    if (search) {
      const q = search.toLowerCase();
      return (p.name + p.sku + p.category + (p.zone || "")).toLowerCase().includes(q);
    }
    return true;
  });

  const counts = products.reduce((a, p) => { a[p.category] = (a[p.category] || 0) + 1; return a; }, {});

  return (
    <div style={{ padding: "28px 36px 80px", maxWidth: 1500, margin: "0 auto" }}>
      {/* header */}
      <div style={{ display: "flex", alignItems: "flex-end", justifyContent: "space-between", marginBottom: 24, gap: 20, flexWrap: "wrap" }}>
        <div>
          <div className="eyebrow">Módulo · Catálogo</div>
          <h1 className="page-title">Catálogo de productos</h1>
          <p className="page-sub">{products.length} productos en {Object.keys(counts).length} líneas · precios y márgenes editables inline</p>
        </div>
        <div style={{ display: "flex", gap: 10 }}>
          <input ref={fileRef} type="file" accept=".xlsx,.xls,.csv" style={{ display: "none" }}
            onChange={(e) => { const f = e.target.files[0]; if (f) alert("Archivo «" + f.name + "» recibido.\n\nLa importación de catálogo desde Excel se conectará a tu hoja real en la versión final. Por ahora puedes crear productos manualmente con «Nuevo producto»."); e.target.value = ""; }} />
          {products.length > 0 && (
            <window.Btn variant="outline" icon="trash" size="md"
              onClick={() => setConfirm({ title: "Vaciar catálogo completo", message: `Se eliminarán los ${products.length} productos del catálogo y se vaciará la cotización en curso. Esta acción no se puede deshacer.`, confirmLabel: "Eliminar todos", onConfirm: clearAllProducts })}>
              Eliminar todos
            </window.Btn>
          )}
          <window.Btn variant="outline" icon="upload" size="md" onClick={() => fileRef.current && fileRef.current.click()}>Importar Excel</window.Btn>
          <window.Btn variant="gold" icon="plus" size="md" onClick={() => setShowNew(true)}>Nuevo producto</window.Btn>
        </div>
      </div>

      {/* controls */}
      <div style={{ display: "flex", gap: 12, marginBottom: 22, alignItems: "center", flexWrap: "wrap" }}>
        <div className="searchbox" style={{ flex: "1 1 260px", maxWidth: 360 }}>
          <window.Icon name="search" size={16} />
          <input value={search} onChange={(e) => setSearch(e.target.value)} placeholder="Buscar por nombre, SKU o zona…" />
        </div>
        <div style={{ display: "flex", gap: 7, flexWrap: "wrap" }}>
          <FilterChip active={filter === "ALL"} onClick={() => setFilter("ALL")} label="Todos" count={products.length} />
          {Object.keys(cats).map((c) => (
            <FilterChip key={c} active={filter === c} onClick={() => setFilter(c)} label={cats[c].label} count={counts[c] || 0} hue={cats[c].hue} />
          ))}
        </div>
      </div>

      {/* grid */}
      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(268px, 1fr))", gap: 16 }}>
        {filtered.map((p) => {
          const added = inQuote.has(p.id);
          const margin = window.effectiveMargin(p, settings);
          return (
            <window.Card key={p.id} hoverable pad={0} style={{ overflow: "hidden", display: "flex", flexDirection: "column" }}>
              <div style={{ position: "relative" }}>
                <CardImage product={p} onUpload={(url) => updateProduct(p.id, { image_url: url })} />
                <div style={{ position: "absolute", top: 10, left: 10 }}><window.CatBadge cat={p.category} /></div>
                <button className="card-del" title="Eliminar producto"
                  onClick={(e) => { e.stopPropagation(); setConfirm({ title: "Eliminar producto", message: `Se eliminará «${p.name}» del catálogo. Esta acción no se puede deshacer.`, onConfirm: () => removeProduct(p.id) }); }}>
                  <window.Icon name="trash" size={14} />
                </button>
                {added && (
                  <div style={{ position: "absolute", bottom: 10, left: 10, display: "inline-flex", alignItems: "center", gap: 5,
                    padding: "4px 8px", borderRadius: 6, fontSize: 10.5, fontWeight: 500, color: "var(--accent-ink)", background: "var(--gold)", whiteSpace: "nowrap" }}>
                    <window.Icon name="check" size={12} stroke={2.5} /> En cotización
                  </div>
                )}
              </div>
              <div style={{ padding: 15, display: "flex", flexDirection: "column", gap: 10, flex: 1 }}>
                <div>
                  <div style={{ fontSize: 14.5, fontWeight: 600, lineHeight: 1.25, marginBottom: 4, textWrap: "pretty" }}>{p.name}</div>
                  <div style={{ display: "flex", gap: 8, alignItems: "center", fontFamily: "var(--mono)", fontSize: 10.5, color: "var(--muted)" }}>
                    <span>{p.sku}</span><span>·</span><span>{p.zone}</span>
                  </div>
                </div>
                <p style={{ fontSize: 12, color: "var(--muted)", lineHeight: 1.5, margin: 0, flex: 1,
                  display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical", overflow: "hidden" }}>{p.description}</p>

                <div style={{ display: "flex", alignItems: "flex-end", justifyContent: "space-between", paddingTop: 10, borderTop: "1px solid var(--border)" }}>
                  <div>
                    <div className="lbl">Precio venta · {p.unit}</div>
                    <EditableNum value={p.sale_price} prefix="$"
                      editing={editing && editing.id === p.id && editing.field === "sale"}
                      onStart={() => setEditing({ id: p.id, field: "sale" })}
                      onCommit={(v) => { updateProduct(p.id, { sale_price: v }); setEditing(null); }}
                      big />
                    {adminMode && (
                      <div style={{ fontFamily: "var(--mono)", fontSize: 11, color: "var(--muted)", marginTop: 3 }}>
                        costo {window.fmtMoney(p.cost_price)}
                      </div>
                    )}
                  </div>
                  <div style={{ textAlign: "right" }}>
                    {adminMode && <div style={{ marginBottom: 6 }}><window.MarginPill pct={margin} /></div>}
                    <window.Btn variant={added ? "outline" : "gold"} size="sm" icon={added ? "check" : "plus"}
                      onClick={() => addItemToQuote(p)}>{added ? "Agregado" : "Agregar"}</window.Btn>
                  </div>
                </div>
              </div>
            </window.Card>
          );
        })}
      </div>
      {filtered.length === 0 && (
        <div className="empty">
          {products.length === 0
            ? <>El catálogo está vacío. Usa «Nuevo producto» para agregar, o importa tu Excel.</>
            : <>Sin resultados para «{search}»</>}
        </div>
      )}

      {showNew && <NewProductModal onClose={() => setShowNew(false)} onCreate={(prod) => { addProduct(prod); setShowNew(false); }} settings={settings} />}
      <window.ConfirmModal open={!!confirm} title={confirm && confirm.title} message={confirm && confirm.message}
        confirmLabel={(confirm && confirm.confirmLabel) || "Eliminar"}
        onConfirm={() => confirm && confirm.onConfirm()} onClose={() => setConfirm(null)} />
    </div>
  );
}

// ---------- new product modal ----------
function NewProductModal({ onClose, onCreate, settings }) {
  const cats = window.AppData.CATEGORIES;
  const [f, setF] = React.useState({
    name: "", sku: "", category: "PREMO", unit: "m2", zone: "",
    description: "", cost_price: "", sale_price: "", image_url: null,
  });
  const set = (patch) => setF((s) => ({ ...s, ...patch }));
  const fileRef = React.useRef(null);
  const readImg = (file) => { if (!file || !file.type.startsWith("image/")) return; const r = new FileReader(); r.onload = (e) => set({ image_url: e.target.result }); r.readAsDataURL(file); };

  const valid = f.name.trim() && f.sale_price !== "" && !isNaN(parseFloat(f.sale_price));
  const save = () => {
    if (!valid) return;
    onCreate({
      name: f.name.trim(), sku: f.sku.trim() || (f.category.slice(0, 2) + "-" + Date.now().toString().slice(-5)),
      category: f.category, unit: f.unit, zone: f.zone.trim(), description: f.description.trim(),
      cost_price: parseFloat(f.cost_price) || 0, sale_price: parseFloat(f.sale_price) || 0, image_url: f.image_url,
    });
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()} style={{ width: 560, maxHeight: "90vh", overflowY: "auto" }}>
        <div className="modal-head">
          <div>
            <div className="eyebrow">Catálogo</div>
            <h3 style={{ margin: "3px 0 0", fontFamily: "var(--display)", fontSize: 20, fontWeight: 600 }}>Nuevo producto</h3>
          </div>
          <button className="iconbtn" onClick={onClose}><window.Icon name="x" size={18} /></button>
        </div>

        <div style={{ padding: "8px 22px 4px", display: "grid", gridTemplateColumns: "120px 1fr", gap: 16 }}>
          <div>
            <div className="imgcell" style={{ position: "relative", width: 120, borderRadius: 10, overflow: "hidden" }}>
              <window.ImageSlot cat={f.category} src={f.image_url} label="foto" radius={10} />
              <input ref={fileRef} type="file" accept="image/*" style={{ display: "none" }} onChange={(e) => readImg(e.target.files[0])} />
              <button className="imgcell-edit" style={{ inset: "auto 0 0 0", top: "auto", height: 30, background: "linear-gradient(transparent, rgba(8,8,8,0.72))" }}
                onClick={() => fileRef.current && fileRef.current.click()}>
                <span style={{ fontSize: 10.5, fontWeight: 600, display: "inline-flex", gap: 5, alignItems: "center" }}><window.Icon name="upload" size={12} /> Foto</span>
              </button>
            </div>
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: 11 }}>
            <div>
              <label className="field-lbl">Nombre del producto *</label>
              <input className="inp" autoFocus value={f.name} onChange={(e) => set({ name: e.target.value })} placeholder="Panel acústico…" />
            </div>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
              <div>
                <label className="field-lbl">Línea / categoría</label>
                <window.Select value={f.category} onChange={(v) => set({ category: v })}
                  options={Object.keys(cats).map((c) => ({ value: c, label: cats[c].label }))} style={{ width: "100%" }} />
              </div>
              <div>
                <label className="field-lbl">SKU</label>
                <input className="inp" value={f.sku} onChange={(e) => set({ sku: e.target.value })} placeholder="auto" />
              </div>
            </div>
          </div>
        </div>

        <div style={{ padding: "4px 22px 0" }}>
          <label className="field-lbl">Descripción</label>
          <textarea className="inp" rows={2} value={f.description} onChange={(e) => set({ description: e.target.value })}
            placeholder="Especificaciones técnicas, acabado, prestaciones…" style={{ resize: "vertical", fontFamily: "var(--body)" }} />
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr 1fr", gap: 10, marginTop: 11 }}>
            <div>
              <label className="field-lbl">Unidad</label>
              <window.Select value={f.unit} onChange={(v) => set({ unit: v })}
                options={[{ value: "m2", label: "m²" }, { value: "und", label: "und" }, { value: "ml", label: "ml" }, { value: "global", label: "global" }]} style={{ width: "100%" }} />
            </div>
            <div>
              <label className="field-lbl">Zona típica</label>
              <input className="inp" value={f.zone} onChange={(e) => set({ zone: e.target.value })} placeholder="Oficina" />
            </div>
            <div>
              <label className="field-lbl">Costo $</label>
              <input className="inp" inputMode="decimal" value={f.cost_price} onChange={(e) => set({ cost_price: e.target.value })} placeholder="0.00" style={{ fontFamily: "var(--mono)" }} />
            </div>
            <div>
              <label className="field-lbl">Venta $ *</label>
              <input className="inp" inputMode="decimal" value={f.sale_price} onChange={(e) => set({ sale_price: e.target.value })} placeholder="0.00" style={{ fontFamily: "var(--mono)" }} />
            </div>
          </div>
          {f.cost_price && f.sale_price && parseFloat(f.sale_price) > 0 && (
            <div style={{ marginTop: 12, display: "flex", alignItems: "center", gap: 10 }}>
              <span className="lbl">Margen resultante</span>
              <window.MarginPill pct={((parseFloat(f.sale_price) - parseFloat(f.cost_price)) / parseFloat(f.sale_price)) * 100} showLabel />
            </div>
          )}
        </div>

        <div className="modal-foot">
          <div style={{ flex: 1 }} />
          <window.Btn variant="outline" onClick={onClose}>Cancelar</window.Btn>
          <window.Btn variant="gold" icon="check" onClick={save} disabled={!valid}>Crear producto</window.Btn>
        </div>
      </div>
    </div>
  );
}

function CardImage({ product, onUpload }) {
  const ref = React.useRef(null);
  const read = (file) => {
    if (!file || !file.type.startsWith("image/")) return;
    const r = new FileReader();
    r.onload = (e) => onUpload(e.target.result);
    r.readAsDataURL(file);
  };
  return (
    <div className="imgcell" style={{ position: "relative" }}>
      <window.ImageSlot cat={product.category} src={product.image_url} label={product.name.toLowerCase()} radius={0} />
      <input ref={ref} type="file" accept="image/*" style={{ display: "none" }} onChange={(e) => read(e.target.files[0])} />
      <button className="imgcell-edit" style={{ height: 34, top: "auto", bottom: 0, inset: "auto 0 0 0", background: "linear-gradient(transparent, rgba(8,8,8,0.7))" }}
        onClick={(e) => { e.stopPropagation(); ref.current && ref.current.click(); }} title="Subir / cambiar foto">
        <span style={{ display: "inline-flex", alignItems: "center", gap: 6, fontSize: 11, fontWeight: 600 }}>
          <window.Icon name="upload" size={13} /> {window.isRealImage(product.image_url) ? "Cambiar" : "Subir foto"}
        </span>
      </button>
    </div>
  );
}

function FilterChip({ active, onClick, label, count, hue }) {
  return (
    <button onClick={onClick} style={{
      display: "inline-flex", alignItems: "center", gap: 7, padding: "7px 13px", borderRadius: 8, cursor: "pointer",
      fontFamily: "var(--body)", fontSize: 12.5, fontWeight: active ? 600 : 500, transition: "all .15s ease",
      color: active ? "var(--accent-ink)" : "var(--text)",
      background: active ? "var(--text)" : "var(--panel)",
      border: "1px solid " + (active ? "var(--text)" : "var(--border)"),
    }}>
      {hue != null && <span style={{ width: 6, height: 6, borderRadius: 8, background: active ? "rgba(10,10,10,0.5)" : "rgba(244,244,244,0.5)" }} />}
      {label}
      <span style={{ fontFamily: "var(--mono)", fontSize: 10.5, opacity: 0.6 }}>{count}</span>
    </button>
  );
}

function EditableNum({ value, prefix = "", editing, onStart, onCommit, big }) {
  const [v, setV] = React.useState(String(value));
  React.useEffect(() => { if (editing) setV(String(value)); }, [editing]);
  if (editing) {
    return (
      <input autoFocus value={v} onChange={(e) => setV(e.target.value)}
        onBlur={() => onCommit(parseFloat(v) || 0)}
        onKeyDown={(e) => { if (e.key === "Enter") onCommit(parseFloat(v) || 0); if (e.key === "Escape") onCommit(value); }}
        style={{ width: big ? 96 : 64, fontFamily: "var(--mono)", fontSize: big ? 18 : 13, fontWeight: 600,
          background: "var(--bg)", border: "1px solid var(--gold)", borderRadius: 6, color: "var(--text)", padding: "2px 6px" }} />
    );
  }
  return (
    <button onClick={onStart} className="editnum" style={{
      fontFamily: "var(--mono)", fontSize: big ? 19 : 13, fontWeight: 600, color: "var(--text)",
      background: "none", border: "none", cursor: "text", padding: 0, letterSpacing: "-.01em",
    }}>{prefix}{window.fmtNum(value)}</button>
  );
}

window.CatalogView = CatalogView;
