/* =====================================================================
   PageDashboard (PgDash) — KPIs, analisis de ventas, ranking
   Render function: recibe `app` con state/setters/helpers de App
   ===================================================================== */

function PgDash(app) {
  const {
    D, setD, view, setView, modal, setModal, edt, setEdt, search, setSearch,
    cotFEstado, setCotFEstado, cotFCliente, setCotFCliente,
    catFTipo, setCatFTipo, catFTextil, setCatFTextil,
    eu, setEu, nu, setNu,
    dDesde, setDDesde, dHasta, setDHasta, filtroEst, setFiltroEst,
    editMq, setEditMq, ep, setEp, newPago, setNewPago, stab, setStab,
    saved, setSaved, ok,
    pdfCot, setPdfCot, pdfKind, setPdfKind, pdfPaperSize, setPdfPaperSize, pdfHtml,
    emailModal, setEmailModal, session, setSession, loginErr, setLoginErr,
    convertCot, setConvertCot, convertTipo, setConvertTipo,
    up, filt, del, openNew, openEd, saveForm,
    cotNombre, genCotNum, nuevaCot, saveCot, cotAPedido,
    tbl, verPDF, verPedPDF, openEmail, doLogin,
    puede, nivelLabel, nivelColor,
    menu, menuFull,
    showBulk, setShowBulk, bulkText, setBulkText,
    showBulkIns, setShowBulkIns, bulkTextIns, setBulkTextIns,
    showBulkProv, setShowBulkProv, bulkTextProv, setBulkTextProv,
    bulkMsg, setBulkMsg,
    splitLine, doBulkImport, doBulkImportIns, doBulkImportProv,
    mc,
  } = app;


    // ─── Date range filter ───
    const preset = (tipo) => {
      const h = new Date();
      const yy = h.getFullYear(); const mm = h.getMonth(); const dd = h.getDate();
      const f = d => d.toISOString().split("T")[0];
      if (tipo === "mes") { setDDesde(f(new Date(yy, mm, 1))); setDHasta(f(h)); }
      else if (tipo === "trim") { setDDesde(f(new Date(yy, mm - 2, 1))); setDHasta(f(h)); }
      else if (tipo === "anio") { setDDesde(`${yy}-01-01`); setDHasta(f(h)); }
      else { setDDesde(""); setDHasta(""); }
    };
    const inRange = (fecha) => {
      if (!fecha) return true;
      if (dDesde && fecha < dDesde) return false;
      if (dHasta && fecha > dHasta) return false;
      return true;
    };

    // ─── Data aggregation (filtered by date range) ───
    const cots = (D.cotizaciones || []).filter(c => inRange(c.fecha));
    const aprobadas = cots.filter(c => ["Aprobada", "Pedido realizado"].includes(c.estado));
    const noAprobadas = cots.filter(c => c.estado === "No aprobada");
    const enviadas = cots.filter(c => ["Enviada", "Aprobada", "Pedido realizado", "No aprobada"].includes(c.estado));

    // Compute all items with costs
    const allItems = cots.flatMap(c => (c.items || []).map(it => {
      const rc = motorCosteo(it, D.insumos);
      return { ...rc, _cotEstado: c.estado, _cotId: c.id, _cotNum: c.numero, _cliente: c.clienteNombre || "", _clienteId: c.clienteId, _fecha: c.fecha };
    }));
    const apItems = allItems.filter(x => ["Aprobada", "Pedido realizado"].includes(x._cotEstado));

    // B1 — Ventas generales
    const totalIngresos = apItems.reduce((s, it) => s + it._netoSinIVA * it.cantidad, 0);
    const totalIVA = apItems.reduce((s, it) => s + it._iva * it.cantidad, 0);
    const totalUnidades = apItems.reduce((s, it) => s + it.cantidad, 0);
    const ticketProm = aprobadas.length > 0 ? Math.round(totalIngresos / aprobadas.length) : 0;
    const pctConv = enviadas.length > 0 ? ((aprobadas.length / enviadas.length) * 100).toFixed(1) : "0.0";

    // B2 — Producto más vendido (por nombre comercial o tipo prenda)
    const prodMap = {};
    apItems.forEach(it => {
      const k = it.nombreComercial || it.tipoPrenda || "Sin nombre";
      if (!prodMap[k]) prodMap[k] = { nombre: k, unidades: 0, ingresos: 0, utilidad: 0, cotizados: 0, aprobados: 0, costoTextil: 0, costoConf: 0, costoEst: 0, costoIns: 0, costoMaq: 0, costoCargos: 0 };
      prodMap[k].unidades += it.cantidad;
      prodMap[k].ingresos += it._netoSinIVA * it.cantidad;
      prodMap[k].utilidad += it._utilidad * it.cantidad;
      prodMap[k].aprobados++;
      prodMap[k].costoTextil += (it._cTextil || 0) * it.cantidad;
      prodMap[k].costoConf += (it.costoConfeccion || 0) * it.cantidad;
      prodMap[k].costoEst += (it._cEstampados || 0) * it.cantidad;
      prodMap[k].costoIns += (it._cInsumos || 0) * it.cantidad;
      prodMap[k].costoMaq += ((it.costoTrazo || 0) + (it.costoCorte || 0) + (it.costoEmpaque || 0)) * it.cantidad;
      prodMap[k].costoCargos += (it._totalCargos || 0) * it.cantidad;
    });
    // Count all cotizados (incl. no aprobadas)
    allItems.forEach(it => {
      const k = it.nombreComercial || it.tipoPrenda || "Sin nombre";
      if (!prodMap[k]) prodMap[k] = { nombre: k, unidades: 0, ingresos: 0, utilidad: 0, cotizados: 0, aprobados: 0, costoTextil: 0, costoConf: 0, costoEst: 0, costoIns: 0, costoMaq: 0, costoCargos: 0 };
      prodMap[k].cotizados++;
    });
    const prods = Object.values(prodMap);
    const topVendidos = [...prods].sort((a, b) => b.unidades - a.unidades).slice(0, 5);
    const topRentables = [...prods].sort((a, b) => b.utilidad - a.utilidad).slice(0, 5);
    const topIngresos = [...prods].sort((a, b) => b.ingresos - a.ingresos).slice(0, 5);

    // B4 — Conversión por producto
    const convProds = prods.filter(p => p.cotizados > 0).map(p => ({ ...p, convPct: p.cotizados > 0 ? ((p.aprobados / p.cotizados) * 100).toFixed(0) : 0 })).sort((a, b) => a.convPct - b.convPct);

    // B5 — Estructura de costos (global aprobadas)
    const totalCostoDir = apItems.reduce((s, it) => s + it._subDirecto * it.cantidad, 0);
    const pctCosto = (v) => totalCostoDir > 0 ? ((v / totalCostoDir) * 100).toFixed(1) : "0";
    const cGlobalTextil = apItems.reduce((s, it) => s + (it._cTextil || 0) * it.cantidad, 0);
    const cGlobalConf = apItems.reduce((s, it) => s + (it.costoConfeccion || 0) * it.cantidad, 0);
    const cGlobalEst = apItems.reduce((s, it) => s + (it._cEstampados || 0) * it.cantidad, 0);
    const cGlobalIns = apItems.reduce((s, it) => s + (it._cInsumos || 0) * it.cantidad, 0);
    const cGlobalMaq = apItems.reduce((s, it) => s + ((it.costoTrazo || 0) + (it.costoCorte || 0) + (it.costoEmpaque || 0)) * it.cantidad, 0);

    // B6 — Cliente
    const cliMap = {};
    // All cotizaciones per client (for conversion)
    cots.forEach(c => {
      const k = c.clienteNombre || (D.clientes.find(x => x.id === c.clienteId) || {}).razon || "Sin cliente";
      if (!cliMap[k]) cliMap[k] = { nombre: k, ingresos: 0, utilidad: 0, unidades: 0, cotsAprobadas: 0, cotsTotal: 0, cotsEnviadas: 0, topProducto: {} };
      cliMap[k].cotsTotal++;
      if (["Aprobada", "Pedido realizado"].includes(c.estado)) cliMap[k].cotsAprobadas++;
      if (["Enviada", "Aprobada", "Pedido realizado", "No aprobada"].includes(c.estado)) cliMap[k].cotsEnviadas++;
    });
    apItems.forEach(it => {
      const k = it._cliente || "Sin cliente";
      if (!cliMap[k]) cliMap[k] = { nombre: k, ingresos: 0, utilidad: 0, unidades: 0, cotsAprobadas: 0, cotsTotal: 0, cotsEnviadas: 0, topProducto: {} };
      cliMap[k].ingresos += it._netoSinIVA * it.cantidad;
      cliMap[k].utilidad += it._utilidad * it.cantidad;
      cliMap[k].unidades += it.cantidad;
      const prod = it.nombreComercial || it.tipoPrenda || "—";
      cliMap[k].topProducto[prod] = (cliMap[k].topProducto[prod] || 0) + it.cantidad;
    });
    const clientes = Object.values(cliMap).map(c => {
      const topProd = Object.entries(c.topProducto).sort((a, b) => b[1] - a[1])[0];
      return { ...c, margen: c.ingresos > 0 ? ((c.utilidad / c.ingresos) * 100).toFixed(1) : 0, convPct: c.cotsEnviadas > 0 ? ((c.cotsAprobadas / c.cotsEnviadas) * 100).toFixed(0) : "—", topProdNombre: topProd ? topProd[0] : "—" };
    }).sort((a, b) => b.ingresos - a.ingresos);

    // B8 — Razones de pérdida
    const razones = {};
    noAprobadas.forEach(c => { if (c.razonNo) razones[c.razonNo] = (razones[c.razonNo] || 0) + 1; });
    const razonesArr = Object.entries(razones).sort((a, b) => b[1] - a[1]);
    const totalRazones = razonesArr.reduce((s, [, n]) => s + n, 0);

    // B10 — Alertas
    const alertas = [];
    prods.filter(p => p.cotizados >= 2 && p.aprobados / p.cotizados < 0.3).forEach(p => alertas.push({ tipo: "danger", msg: `${p.nombre}: baja conversión (${((p.aprobados / p.cotizados) * 100).toFixed(0)}%)`, insight: "Revisar precio o propuesta" }));
    prods.filter(p => p.ingresos > 0 && (p.utilidad / p.ingresos) < 0.10).forEach(p => alertas.push({ tipo: "warning", msg: `${p.nombre}: margen bajo (${((p.utilidad / p.ingresos) * 100).toFixed(1)}%)`, insight: "Revisar estructura de costos" }));
    prods.filter(p => p.cotizados >= 3 && p.aprobados === 0).forEach(p => alertas.push({ tipo: "danger", msg: `${p.nombre}: cotizado ${p.cotizados} veces, nunca aprobado`, insight: "Considerar eliminar o recostear" }));
    // Cotizaciones sin seguimiento (Enviadas hace más de 7 días)
    const hoyMs = new Date().getTime();
    cots.filter(c => c.estado === "Enviada" || c.estado === "Borrador").forEach(c => {
      const dias = Math.floor((hoyMs - new Date(c.fecha).getTime()) / 86400000);
      if (dias > 7) alertas.push({ tipo: "warning", msg: `COT ${c.numero} (${c.clienteNombre || "—"}): ${dias} días sin respuesta`, insight: "Hacer seguimiento comercial" });
    });
    // Clientes poco rentables
    clientes.filter(c => parseFloat(c.margen) < 10 && c.ingresos > 0).forEach(c => alertas.push({ tipo: "warning", msg: `${c.nombre}: margen promedio ${c.margen}%`, insight: "Revisar precios para este cliente" }));

    // B — Insights: productos con alto volumen cotizado pero baja venta
    const insightProds = prods.filter(p => p.cotizados >= 2).map(p => {
      const conv = p.cotizados > 0 ? p.aprobados / p.cotizados : 0;
      const mg = p.ingresos > 0 ? p.utilidad / p.ingresos : 0;
      let tag = null;
      if (conv < 0.3 && p.cotizados >= 3) tag = { color: "#b91c1c", bg: "#fee2e2", text: "Se cotiza mucho pero no convierte" };
      else if (mg > 0.30 && p.unidades >= 10) tag = { color: "#065f46", bg: "#dcfce7", text: "Alta rentabilidad + buen volumen" };
      else if (p.unidades > 0 && mg < 0.10) tag = { color: "#854d0e", bg: "#fef9c3", text: "Rota bien pero margen bajo" };
      else if (p.utilidad > 0 && p.unidades <= 5) tag = { color: "#1e40af", bg: "#dbeafe", text: "Buena utilidad pero poca rotación" };
      return { ...p, conv: (conv * 100).toFixed(0), mg: (mg * 100).toFixed(1), tag };
    }).filter(p => p.tag).slice(0, 5);

    // Peor margen
    const peorMargen = prods.filter(p => p.ingresos > 0).sort((a, b) => (a.utilidad / a.ingresos) - (b.utilidad / b.ingresos)).slice(0, 3);

    // ─── Styles ───
    const kpi = { ...S.card, textAlign: "center", padding: "16px 10px" };
    const kpiN = { fontSize: 24, fontWeight: 800, fontFamily: "Georgia,serif" };
    const kpiL = { fontSize: 10, color: "#9ca3af", marginTop: 2 };
    const secT = { margin: "18px 0 8px", fontSize: 13, fontWeight: 600, color: "#0a2540", fontFamily: "Georgia,serif", borderBottom: "1px solid #e5e1d8", paddingBottom: 4 };
    const bar = (pct, color) => ({ height: 8, borderRadius: 4, background: `linear-gradient(90deg, ${color} ${pct}%, #e5e1d8 ${pct}%)` });

    return (
      <div>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 10 }}>
          <h2 style={{ margin: 0, color: "#0a2540", fontFamily: "Georgia,serif", fontSize: 18 }}>Dashboard</h2>
          <button style={S.btn} onClick={nuevaCot}><Ic name="plus" size={14} /> Nueva Cotización</button>
        </div>
        {/* Filtro de fechas */}
        <div style={{ ...S.card, padding: "8px 12px", marginBottom: 10, display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
          <span style={{ fontSize: 11, fontWeight: 600, color: "#0a2540" }}>Período:</span>
          <input style={{ ...S.inp, width: 130, fontSize: 11 }} type="date" value={dDesde} onChange={e => setDDesde(e.target.value)} />
          <span style={{ fontSize: 11, color: "#9ca3af" }}>a</span>
          <input style={{ ...S.inp, width: 130, fontSize: 11 }} type="date" value={dHasta} onChange={e => setDHasta(e.target.value)} />
          <div style={{ display: "flex", gap: 4 }}>
            <button style={{ ...S.btn2, fontSize: 10, fontWeight: dDesde && new Date(dDesde).getDate() === 1 && new Date(dDesde).getMonth() === new Date().getMonth() ? 700 : 400 }} onClick={() => preset("mes")}>Este mes</button>
            <button style={{ ...S.btn2, fontSize: 10 }} onClick={() => preset("trim")}>Último trimestre</button>
            <button style={{ ...S.btn2, fontSize: 10 }} onClick={() => preset("anio")}>Este año</button>
            <button style={{ ...S.btn2, fontSize: 10, fontWeight: !dDesde && !dHasta ? 700 : 400 }} onClick={() => preset("todo")}>Todo</button>
          </div>
          {(dDesde || dHasta) && <span style={{ fontSize: 10, color: "#6b7280" }}>Mostrando {cots.length} cotizaciones · {(D.pedidos || []).filter(p => inRange(p.fecha)).length} pedidos</span>}
        </div>

        {/* KPIs principales */}
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr 1fr 1fr", gap: 8 }}>
          <div style={kpi}><div style={{ ...kpiN, color: "#0a2540" }}>{cots.length}</div><div style={kpiL}>Cotizaciones</div></div>
          <div style={kpi}><div style={{ ...kpiN, color: "#065f46" }}>{fmt(totalIngresos)}</div><div style={kpiL}>Ingresos aprobados</div></div>
          <div style={kpi}><div style={{ ...kpiN, color: "#1e40af" }}>{pctConv}%</div><div style={kpiL}>Conversión</div></div>
          <div style={kpi}><div style={{ ...kpiN, color: "#0a2540" }}>{fmtN(totalUnidades)}</div><div style={kpiL}>Unidades vendidas</div></div>
          <div style={kpi}><div style={{ ...kpiN, color: "#b91c1c" }}>{noAprobadas.length}</div><div style={kpiL}>No aprobadas</div></div>
        </div>

        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 8, marginTop: 8 }}>
          <div style={kpi}><div style={{ ...kpiN, fontSize: 16, color: "#065f46" }}>{fmt(ticketProm)}</div><div style={kpiL}>Ticket promedio</div></div>
          <div style={kpi}><div style={{ ...kpiN, fontSize: 16, color: "#065f46" }}>{fmt(apItems.reduce((s, it) => s + it._utilidad * it.cantidad, 0))}</div><div style={kpiL}>Utilidad total</div></div>
          <div style={kpi}><div style={{ ...kpiN, fontSize: 16, color: "#1e40af" }}>{totalIngresos > 0 ? ((apItems.reduce((s, it) => s + it._utilidad * it.cantidad, 0) / totalIngresos) * 100).toFixed(1) : 0}%</div><div style={kpiL}>Margen promedio</div></div>
        </div>

        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 8 }}>
          {/* Top vendidos */}
          <div>
            <div style={secT}>Top por volumen (uds)</div>
            <div style={S.card}>{topVendidos.length === 0 ? <p style={{ color: "#9ca3af", fontSize: 11 }}>Sin datos</p> : topVendidos.map((p, i) => (
              <div key={i} style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "5px 0", borderBottom: "1px solid #f0ede6", fontSize: 12 }}>
                <div><strong style={{ fontSize: 11 }}>{i + 1}. {p.nombre}</strong></div>
                <div style={{ textAlign: "right" }}><strong>{fmtN(p.unidades)}</strong> uds</div>
              </div>
            ))}</div>
          </div>

          {/* Top ingresos */}
          <div>
            <div style={secT}>Top por ingresos ($)</div>
            <div style={S.card}>{topIngresos.length === 0 ? <p style={{ color: "#9ca3af", fontSize: 11 }}>Sin datos</p> : topIngresos.map((p, i) => (
              <div key={i} style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "5px 0", borderBottom: "1px solid #f0ede6", fontSize: 12 }}>
                <div><strong style={{ fontSize: 11 }}>{i + 1}. {p.nombre}</strong></div>
                <div style={{ textAlign: "right" }}><strong style={{ color: "#065f46" }}>{fmt(p.ingresos)}</strong></div>
              </div>
            ))}</div>
          </div>

          {/* Top rentables */}
          <div>
            <div style={secT}>Top por utilidad ($)</div>
            <div style={S.card}>{topRentables.length === 0 ? <p style={{ color: "#9ca3af", fontSize: 11 }}>Sin datos</p> : topRentables.map((p, i) => {
              const mg = p.ingresos > 0 ? ((p.utilidad / p.ingresos) * 100).toFixed(1) : 0;
              return (
                <div key={i} style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "5px 0", borderBottom: "1px solid #f0ede6", fontSize: 12 }}>
                  <div><strong style={{ fontSize: 11 }}>{i + 1}. {p.nombre}</strong></div>
                  <div style={{ textAlign: "right" }}><strong style={{ color: "#065f46" }}>{fmt(p.utilidad)}</strong> <span style={{ fontSize: 10, color: "#9ca3af" }}>{mg}%</span></div>
                </div>
              );
            })}</div>
          </div>
        </div>

        {/* Insights estratégicos */}
        {insightProds.length > 0 && <>
          <div style={secT}>Insights de producto</div>
          <div style={S.card}>
            {insightProds.map((p, i) => (
              <div key={i} style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "6px 0", borderBottom: "1px solid #f0ede6", fontSize: 11 }}>
                <div>
                  <strong>{p.nombre}</strong>
                  <span style={{ marginLeft: 8, padding: "1px 6px", borderRadius: 4, fontSize: 9, background: p.tag.bg, color: p.tag.color }}>{p.tag.text}</span>
                </div>
                <div style={{ textAlign: "right", fontSize: 10, color: "#6b7280" }}>{fmtN(p.unidades)} uds · Conv {p.conv}% · Margen {p.mg}%</div>
              </div>
            ))}
          </div>
        </>}

        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 8 }}>
          {/* Estructura de costos */}
          <div>
            <div style={secT}>Estructura de costos</div>
            <div style={S.card}>
              {totalCostoDir === 0 ? <p style={{ color: "#9ca3af", fontSize: 11 }}>Sin datos</p> : <>
                {[["Textil", cGlobalTextil, "#3b82f6"], ["Confección", cGlobalConf, "#8b5cf6"], ["Estampado", cGlobalEst, "#f59e0b"], ["Insumos", cGlobalIns, "#10b981"], ["Maquila", cGlobalMaq, "#ef4444"]].map(([label, val, color]) => (
                  <div key={label} style={{ marginBottom: 6 }}>
                    <div style={{ display: "flex", justifyContent: "space-between", fontSize: 11 }}><span>{label}</span><strong>{pctCosto(val)}%</strong></div>
                    <div style={bar(parseFloat(pctCosto(val)), color)}></div>
                  </div>
                ))}
              </>}
            </div>
          </div>

          {/* Razones de pérdida */}
          <div>
            <div style={secT}>Razones de pérdida</div>
            <div style={S.card}>
              {razonesArr.length === 0 ? <p style={{ color: "#9ca3af", fontSize: 11 }}>Sin datos</p> : razonesArr.map(([r, n]) => (
                <div key={r} style={{ marginBottom: 6 }}>
                  <div style={{ display: "flex", justifyContent: "space-between", fontSize: 11 }}><span>{r}</span><strong>{n} ({totalRazones > 0 ? ((n / totalRazones) * 100).toFixed(0) : 0}%)</strong></div>
                  <div style={bar(totalRazones > 0 ? (n / totalRazones) * 100 : 0, "#ef4444")}></div>
                </div>
              ))}
            </div>
          </div>

          {/* Peor margen */}
          <div>
            <div style={secT}>Productos con peor margen</div>
            <div style={S.card}>
              {peorMargen.length === 0 ? <p style={{ color: "#9ca3af", fontSize: 11 }}>Sin datos</p> : peorMargen.map((p, i) => {
                const mg = p.ingresos > 0 ? ((p.utilidad / p.ingresos) * 100).toFixed(1) : 0;
                return (
                  <div key={i} style={{ padding: "5px 0", borderBottom: "1px solid #f0ede6", fontSize: 11 }}>
                    <div style={{ display: "flex", justifyContent: "space-between" }}><strong>{p.nombre}</strong><span style={{ color: parseFloat(mg) < 10 ? "#b91c1c" : "#854d0e", fontWeight: 700 }}>{mg}%</span></div>
                    <div style={{ fontSize: 10, color: "#9ca3af" }}>Utilidad: {fmt(p.utilidad)} · {fmtN(p.unidades)} uds</div>
                  </div>
                );
              })}
            </div>
          </div>
        </div>

        <div style={S.g2}>
          {/* Conversión por producto */}
          <div>
            <div style={secT}>Conversión por producto</div>
            <div style={S.card}>{convProds.length === 0 ? <p style={{ color: "#9ca3af", fontSize: 11 }}>Sin datos</p> : convProds.slice(0, 8).map((p, i) => {
              const pct = parseInt(p.convPct);
              const color = pct >= 60 ? "#065f46" : pct >= 30 ? "#854d0e" : "#b91c1c";
              return (
                <div key={i} style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "4px 0", borderBottom: "1px solid #f0ede6", fontSize: 11 }}>
                  <span>{p.nombre}</span>
                  <div><span style={{ color, fontWeight: 700 }}>{p.convPct}%</span> <span style={{ color: "#9ca3af", fontSize: 10 }}>({p.aprobados}/{p.cotizados})</span></div>
                </div>
              );
            })}</div>
          </div>

          {/* Clientes */}
          <div>
            <div style={secT}>Clientes</div>
            <div style={S.card}>{clientes.length === 0 ? <p style={{ color: "#9ca3af", fontSize: 11 }}>Sin datos</p> : clientes.slice(0, 6).map((c, i) => (
              <div key={i} style={{ padding: "5px 0", borderBottom: "1px solid #f0ede6", fontSize: 11 }}>
                <div style={{ display: "flex", justifyContent: "space-between" }}><strong>{c.nombre}</strong><span style={{ color: "#065f46" }}>{fmt(c.ingresos)}</span></div>
                <div style={{ display: "flex", gap: 8, fontSize: 10, color: "#9ca3af", marginTop: 1, flexWrap: "wrap" }}>
                  <span>{c.cotsAprobadas}/{c.cotsTotal} cot.</span>
                  <span>Conv: <strong style={{ color: parseInt(c.convPct) >= 50 ? "#065f46" : parseInt(c.convPct) >= 30 ? "#854d0e" : "#b91c1c" }}>{c.convPct}%</strong></span>
                  <span>Margen: {c.margen}%</span>
                  <span>Top: {c.topProdNombre}</span>
                </div>
              </div>
            ))}</div>
          </div>
        </div>

        {/* Alertas */}
        {alertas.length > 0 && <>
          <div style={secT}>Alertas y seguimiento ({alertas.length})</div>
          <div style={S.card}>
            {alertas.map((a, i) => (
              <div key={i} style={{ display: "flex", alignItems: "flex-start", gap: 8, padding: "6px 0", borderBottom: "1px solid #f0ede6", fontSize: 11 }}>
                <span style={{ ...S.badge(a.tipo === "danger" ? "red" : "yellow"), fontSize: 9, flexShrink: 0, marginTop: 1 }}>{a.tipo === "danger" ? "ALERTA" : "AVISO"}</span>
                <div><div>{a.msg}</div>{a.insight && <div style={{ fontSize: 10, color: "#6b7280", fontStyle: "italic", marginTop: 1 }}>{a.insight}</div>}</div>
              </div>
            ))}
          </div>
        </>}

        {/* ═══ Unidades de Negocio ═══ */}
        {(() => {
          const peds = (D.pedidos || []).filter(p => inRange(p.fecha));
          if (peds.length === 0) return null;
          const negMap = {};
          peds.forEach(p => {
            const tipo = p.tipoNegocio || "Sin clasificar";
            if (!negMap[tipo]) negMap[tipo] = { tipo, pedidos: 0, unidades: 0, ingresos: 0, utilidad: 0, costoTotal: 0, entregados: 0 };
            negMap[tipo].pedidos++;
            if (p.estado === "Entregado") negMap[tipo].entregados++;
            (p.items || []).forEach(it => {
              const rc = motorCosteo(it, D.insumos);
              negMap[tipo].unidades += it.cantidad;
              negMap[tipo].ingresos += rc._netoSinIVA * it.cantidad;
              negMap[tipo].utilidad += rc._utilidad * it.cantidad;
              negMap[tipo].costoTotal += rc._subDirecto * it.cantidad;
            });
          });
          const negs = Object.values(negMap).sort((a, b) => b.ingresos - a.ingresos);
          const maxIng = Math.max(...negs.map(n => n.ingresos), 1);
          const totalIngNeg = negs.reduce((s, n) => s + n.ingresos, 0);
          const totalUtilNeg = negs.reduce((s, n) => s + n.utilidad, 0);
          const totalUdsNeg = negs.reduce((s, n) => s + n.unidades, 0);
          const totalPedsNeg = negs.reduce((s, n) => s + n.pedidos, 0);
          const colores = { "Promocionales": "#3b82f6", "Clubes Sociales y Deportivos / Institucional": "#10b981", "B2B2C (Página Web)": "#f59e0b", "B2C": "#8b5cf6", "Licitaciones": "#ef4444", "Sin clasificar": "#9ca3af" };
          return <>
            <div style={secT}>Unidades de negocio ({negs.length})</div>
            {/* KPIs globales de pedidos */}
            <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 8, marginBottom: 10 }}>
              <div style={{ ...S.card, textAlign: "center", padding: 10 }}><div style={{ fontSize: 20, fontWeight: 700, color: "#0a2540" }}>{totalPedsNeg}</div><div style={{ fontSize: 10, color: "#9ca3af" }}>Pedidos totales</div></div>
              <div style={{ ...S.card, textAlign: "center", padding: 10 }}><div style={{ fontSize: 20, fontWeight: 700, color: "#0a2540" }}>{fmt(totalIngNeg)}</div><div style={{ fontSize: 10, color: "#9ca3af" }}>Ingresos totales</div></div>
              <div style={{ ...S.card, textAlign: "center", padding: 10 }}><div style={{ fontSize: 20, fontWeight: 700, color: "#065f46" }}>{fmt(totalUtilNeg)}</div><div style={{ fontSize: 10, color: "#9ca3af" }}>Utilidad total</div></div>
              <div style={{ ...S.card, textAlign: "center", padding: 10 }}><div style={{ fontSize: 20, fontWeight: 700, color: "#0a2540" }}>{fmtN(totalUdsNeg)}</div><div style={{ fontSize: 10, color: "#9ca3af" }}>Unidades totales</div></div>
            </div>
            {/* Cards por tipo de negocio */}
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
              {negs.map(n => {
                const margen = n.ingresos > 0 ? ((n.utilidad / n.ingresos) * 100).toFixed(1) : "0.0";
                const ticket = n.pedidos > 0 ? Math.round(n.ingresos / n.pedidos) : 0;
                const pctIng = totalIngNeg > 0 ? ((n.ingresos / totalIngNeg) * 100).toFixed(1) : "0";
                const color = colores[n.tipo] || "#6b7280";
                return (
                  <div key={n.tipo} style={{ ...S.card, borderLeft: `3px solid ${color}` }}>
                    <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 8 }}>
                      <div>
                        <div style={{ fontSize: 12, fontWeight: 700, color: "#0a2540" }}>{n.tipo}</div>
                        <div style={{ fontSize: 10, color: "#9ca3af" }}>{n.pedidos} pedido(s) · {fmtN(n.unidades)} uds</div>
                      </div>
                      <div style={{ textAlign: "right" }}>
                        <div style={{ fontSize: 14, fontWeight: 800, color: "#0a2540" }}>{fmt(n.ingresos)}</div>
                        <div style={{ fontSize: 10, color: "#9ca3af" }}>{pctIng}% del total</div>
                      </div>
                    </div>
                    {/* Barra de participación */}
                    <div style={{ background: "#f3f4f6", borderRadius: 4, height: 6, marginBottom: 8 }}>
                      <div style={{ background: color, height: 6, borderRadius: 4, width: `${(n.ingresos / maxIng) * 100}%`, transition: "width 0.3s" }} />
                    </div>
                    <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr 1fr", gap: 6 }}>
                      <div><div style={{ fontSize: 9, color: "#9ca3af", textTransform: "uppercase" }}>Utilidad</div><div style={{ fontSize: 12, fontWeight: 700, color: "#065f46" }}>{fmt(n.utilidad)}</div></div>
                      <div><div style={{ fontSize: 9, color: "#9ca3af", textTransform: "uppercase" }}>Margen</div><div style={{ fontSize: 12, fontWeight: 700, color: parseFloat(margen) >= 25 ? "#065f46" : parseFloat(margen) >= 15 ? "#92400e" : "#b91c1c" }}>{margen}%</div></div>
                      <div><div style={{ fontSize: 9, color: "#9ca3af", textTransform: "uppercase" }}>Ticket prom.</div><div style={{ fontSize: 12, fontWeight: 700 }}>{fmt(ticket)}</div></div>
                      <div><div style={{ fontSize: 9, color: "#9ca3af", textTransform: "uppercase" }}>Entregados</div><div style={{ fontSize: 12, fontWeight: 700 }}>{n.entregados}/{n.pedidos}</div></div>
                    </div>
                  </div>
                );
              })}
            </div>
          </>;
        })()}

        {/* Maestros */}
        <div style={{ ...secT, marginTop: 18 }}>Maestros registrados</div>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(6, 1fr)", gap: 8 }}>
          {[["textiles", "Textiles"], ["insumos", "Insumos"], ["tecnicas", "Técnicas"], ["tiposPrenda", "Prendas"], ["clientes", "Clientes"], ["proveedores", "Proveedores"]].map(([k, l]) => <div key={k} style={{ ...S.card, textAlign: "center", padding: 10 }}><div style={{ fontSize: 20, fontWeight: 700 }}>{(D[k] || []).length}</div><div style={{ fontSize: 10, color: "#9ca3af" }}>{l}</div></div>)}
        </div>
      </div>
    );

}

// ── Exports a global scope (Babel standalone aisla cada <script>) ──
window.PgDash      = PgDash;
