/* ============================================================
   SYMPHO · PAKAL — vistas core
   Router + roles · Cockpit · Parque + Ficha de activo · Ubicaciones/Rack
   ============================================================ */

// ---------- helpers ----------
function pkClient(id) { return (window.PK_CLIENTS.find(c => c.id === id) || { name: id, hue: "var(--text-3)" }); }
function pkSite(id) { return (window.PK_SITES.find(s => s.id === id) || { name: id }); }
function pkVendor(id) { return (window.PK_VENDORS.find(v => v.id === id) || { name: id }); }
function healthHue(h) { return h >= 85 ? "var(--ok)" : h >= 65 ? "var(--warn)" : "var(--bad)"; }

function PkHead({ role, title, sub, right, action }) {
  const a = window.APPS.find(x => x.id === "pakal");
  const rc = window.PAKAL_ROLES[role];
  return (
    <div className="pagehead">
      <Glyph app={a} size={40} />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 9, flexWrap: "wrap" }}>
          <h1 className="disp" style={{ fontSize: 23, fontWeight: 600, letterSpacing: "-0.02em" }}>{title}</h1>
          <span className="mono" style={{ fontSize: 11, color: a.hue }}>Pakal</span>
          {rc && <span className="badge" style={{ background: "var(--pakal-dim)", color: "var(--pakal)" }}><Icon name={rc.icon} size={12} /> {rc.label}</span>}
        </div>
        {sub && <p className="muted" style={{ fontSize: 13, marginTop: 4 }}>{sub}</p>}
      </div>
      {right}
      {action && <button className="btn btn-primary" style={{ background: a.hue }}><Icon name={action.icon} size={15} /> {action.label}</button>}
    </div>
  );
}

function PkState({ s }) { return <span className="pk-state" data-s={s}>{s}</span>; }

function PkHealth({ h }) {
  return (
    <span className="pk-health">
      <span className="pk-health-bar"><i style={{ width: h + "%", background: healthHue(h) }} /></span>
      <span className="mono" style={{ fontSize: 11.5, color: healthHue(h) }}>{h}</span>
    </span>
  );
}

// component icon map
const PK_COMP_ICON = { CPU: "chipx", RAM: "ram", Disco: "disk", Fuente: "plug", Ventilador: "fan", SFP: "sfp", Controladora: "server" };

// ============================================================
//  APP ROUTER
// ============================================================
function PakalApp({ sub, role }) {
  role = role || "am";
  switch (sub) {
    case "cockpit": return <PkCockpit role={role} />;
    case "parque": return <PkParque role={role} />;
    case "ubicaciones": return <PkUbicaciones role={role} />;
    case "garantias": return <PkGarantias role={role} />;
    case "contratos": return <PkContratos role={role} />;
    case "rma": return <PkRMA role={role} />;
    case "refacciones": return <PkRefacciones role={role} />;
    case "matching": return <PkMatching role={role} />;
    case "ciclo": return <PkCiclo role={role} />;
    case "campo": return <PkCampo role={role} />;
    case "copilot": return <PkCopilot role={role} />;
    // client portal
    case "misEquipos": return <PkParque role={role} clientPortal />;
    case "misGarantias": return <PkGarantias role={role} clientPortal />;
    case "misRma": return <PkRMA role={role} clientPortal />;
    default: return <PkCockpit role={role} />;
  }
}

// ============================================================
//  COCKPIT
// ============================================================
function PkCockpit({ role }) {
  const S = window.PK_STATS;
  const exec = role === "dir";
  return (
    <div className="canvas-in wide rise pakal">
      <PkHead role={role} title={exec ? "Tablero ejecutivo" : "Cockpit"}
        sub="Salud del parque, ocupación de sitios, vencimientos de pólizas y casos abiertos" />

      <div className="pk-kpi-strip" style={{ marginBottom: 14 }}>
        <Stat icon="server" label="Activos en el parque" value={S.total} hue="var(--pakal)" sub="producción + almacén" />
        <Stat icon="check" label="En producción" value={S.prod} hue="var(--ok)" />
        <Stat icon="boxes" label="Disponibles en bodega" value={S.disponibles} hue="var(--pakal)" sub="listos para proyecto" />
        <Stat icon="shieldx" label="Pólizas por vencer" value={S.porVencer + S.sinGarantia} hue="var(--warn)" sub="≤ 90 días / vencidas" />
      </div>

      <div className="grid-2" style={{ alignItems: "start", gridTemplateColumns: "minmax(0,1.4fr) minmax(0,1fr)", marginBottom: 14 }}>
        {/* park by category + sites */}
        <div className="card" style={{ padding: 20 }}>
          <Section title="Distribución del parque" sub="Por categoría · clic para ver el parque" style={{ marginBottom: 16 }} />
          <div style={{ display: "flex", gap: 28, alignItems: "center", flexWrap: "wrap" }}>
            <Donut segments={window.PK_CATS} size={150} thickness={16}
              center={<><div className="disp" style={{ fontSize: 24, fontWeight: 600 }}>{S.total}</div><div className="mono" style={{ fontSize: 10, color: "var(--text-4)" }}>activos</div></>} />
            <div style={{ flex: 1, minWidth: 200, display: "flex", flexDirection: "column", gap: 10 }}>
              {window.PK_CATS.map(c => (
                <div key={c.cat} style={{ display: "flex", alignItems: "center", gap: 9, fontSize: 12.5 }}>
                  <span className="dot" style={{ background: c.hue }} />
                  <span style={{ flex: 1, color: "var(--text-2)" }}>{c.cat}</span>
                  <span className="mono" style={{ color: "var(--text)" }}>{c.n}</span>
                </div>
              ))}
              <div style={{ marginTop: 8, paddingTop: 12, borderTop: "1px solid var(--line)", display: "flex", gap: 18 }}>
                <div><div className="disp" style={{ fontSize: 20, fontWeight: 600, color: "var(--ok)" }}>{S.prod}</div><div className="muted" style={{ fontSize: 11 }}>producción</div></div>
                <div><div className="disp" style={{ fontSize: 20, fontWeight: 600, color: "var(--pakal)" }}>{S.bodega}</div><div className="muted" style={{ fontSize: 11 }}>almacén</div></div>
                <div><div className="disp" style={{ fontSize: 20, fontWeight: 600, color: "var(--bad)" }}>{S.retiro}</div><div className="muted" style={{ fontSize: 11 }}>retiro</div></div>
              </div>
            </div>
          </div>
        </div>

        {/* sites occupancy */}
        <div className="card" style={{ padding: 20 }}>
          <Section title="Sitios" sub="Ocupación por sitio" style={{ marginBottom: 14 }} />
          <div style={{ display: "flex", flexDirection: "column", gap: 13 }}>
            {window.PK_SITES.map(s => (
              <div key={s.id}>
                <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 5 }}>
                  <span className="dot" style={{ background: s.hue }} />
                  <span style={{ flex: 1, fontSize: 12.5, color: "var(--text)" }}>{s.name}</span>
                  <span className="mono" style={{ fontSize: 11, color: "var(--text-4)" }}>{s.kind}</span>
                  <span className="mono" style={{ fontSize: 11.5, color: "var(--text-2)", width: 34, textAlign: "right" }}>{s.ocupacionPct}%</span>
                </div>
                <div className="bar"><i style={{ width: s.ocupacionPct + "%", background: s.hue }} /></div>
              </div>
            ))}
          </div>
        </div>
      </div>

      <div className="grid-2" style={{ alignItems: "start", gridTemplateColumns: "minmax(0,1fr) minmax(0,1fr)" }}>
        {/* warranty expiry */}
        <div className="card" style={{ padding: 0, overflow: "hidden" }}>
          <div className="card-head"><b style={{ fontSize: 14 }}>Vencimientos de póliza</b><span className="badge warn dot">{window.PK_EXPIRY.length} en riesgo</span></div>
          <table className="tbl">
            <thead><tr><th>Equipo</th><th>Cliente</th><th>Vence</th><th>Estado</th></tr></thead>
            <tbody>
              {window.PK_EXPIRY.map((e, i) => (
                <tr key={i}>
                  <td><span className="mono" style={{ fontSize: 11.5, color: "var(--text)" }}>{e.tag}</span><div className="muted" style={{ fontSize: 11 }}>{e.name}</div></td>
                  <td>{pkClient(e.client).name}</td>
                  <td className="mono" style={{ fontSize: 12 }}>{e.end}</td>
                  <td><Pill status={e.status} /></td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>

        {/* RMA open + manik */}
        <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
          <div className="card" style={{ padding: 0, overflow: "hidden" }}>
            <div className="card-head"><b style={{ fontSize: 14 }}>Casos RMA abiertos</b><span className="mono" style={{ fontSize: 11, color: "var(--text-4)" }}>SLA en seguimiento</span></div>
            <table className="tbl">
              <thead><tr><th>Caso</th><th>Equipo</th><th>SLA</th><th>Estado</th></tr></thead>
              <tbody>
                {window.PK_RMA.filter(r => r.status !== "Cerrado").map((r, i) => (
                  <tr key={i}>
                    <td className="mono" style={{ fontSize: 12, color: "var(--text)" }}>{r.id}</td>
                    <td className="mono" style={{ fontSize: 11.5 }}>{r.asset}</td>
                    <td className="mono" style={{ fontSize: 11.5, color: "var(--text-3)" }}>{r.sla}</td>
                    <td><Pill status={r.status === "En intercambio" ? "En proceso" : r.status} /></td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
          <div className="card" style={{ padding: 18, display: "flex", gap: 14, alignItems: "center" }}>
            <span className="feed-ic" style={{ "--c": "var(--manik)" }}><Icon name="recycle" size={17} /></span>
            <div style={{ flex: 1 }}>
              <b style={{ fontSize: 13.5 }}>Pinza con Manik</b>
              <p className="muted" style={{ fontSize: 12, marginTop: 3, lineHeight: 1.5 }}>1 activo (PK-SRV-0390) marcado <b style={{ color: "var(--text-2)" }}>En retiro</b> → candidato a lote de custodia. Al cerrar el lote, Manik da de baja el activo aquí.</p>
            </div>
            <span className="pk-sync"><Icon name="sync" size={12} /> sincronizado</span>
          </div>
        </div>
      </div>
    </div>
  );
}

// ============================================================
//  PARQUE  (master + ficha)
// ============================================================
function PkParque({ role, clientPortal }) {
  const all = window.PK_ASSETS;
  const [estado, setEstado] = useState("Todos");
  const [sitio, setSitio] = useState("Todos");
  const [cat, setCat] = useState("Todas");
  const [q, setQ] = useState("");
  const [sel, setSel] = useState(all[0].tag);

  // client portal: restrict to one client (Helios demo)
  const base = clientPortal ? all.filter(a => a.client === "helios") : all;
  const estados = ["Todos", "Producción", "Bodega", "Reservado", "RMA", "Retiro", "Desmontado"];
  const filtered = base.filter(a =>
    (estado === "Todos" || a.state === estado || (estado === "RMA" && a.warranty && window.PK_RMA.some(r => r.asset === a.tag && r.status !== "Cerrado"))) &&
    (sitio === "Todos" || a.site === sitio) &&
    (cat === "Todas" || a.cat === cat) &&
    (q === "" || (a.tag + a.name + a.serial + a.cpu + a.ram).toLowerCase().includes(q.toLowerCase()))
  );
  const current = base.find(a => a.tag === sel) || filtered[0] || base[0];

  return (
    <div className="canvas-in wide rise pakal">
      <PkHead role={role} title={clientPortal ? "Mis equipos" : "Parque"}
        sub={clientPortal ? "Equipos en producción y resguardo a tu nombre" : "Parque completo de servidores y equipo: producción, almacén y desmontados"}
        action={clientPortal ? null : { label: "Agregar activo", icon: "plus" }} />

      {/* filters */}
      <div className="card" style={{ padding: 12, marginBottom: 14, display: "flex", gap: 10, alignItems: "center", flexWrap: "wrap" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 7, flex: 1, minWidth: 200 }}>
          <Icon name="search" size={16} style={{ color: "var(--text-4)" }} />
          <input className="field" placeholder="Buscar tag, serie, modelo, CPU…" value={q} onChange={e => setQ(e.target.value)} style={{ height: 34, border: "none", background: "transparent", padding: 0 }} />
        </div>
        <select className="field" value={estado} onChange={e => setEstado(e.target.value)} style={{ width: 150, height: 34 }}>{estados.map(s => <option key={s}>{s}</option>)}</select>
        {!clientPortal && <select className="field" value={sitio} onChange={e => setSitio(e.target.value)} style={{ width: 165, height: 34 }}><option value="Todos">Todos los sitios</option>{window.PK_SITES.map(s => <option key={s.id} value={s.id}>{s.name}</option>)}</select>}
        <select className="field" value={cat} onChange={e => setCat(e.target.value)} style={{ width: 150, height: 34 }}><option value="Todas">Todas las categorías</option>{["Servidores","Networking","Almacenamiento"].map(c => <option key={c}>{c}</option>)}</select>
        <span className="mono" style={{ fontSize: 11.5, color: "var(--text-4)" }}>{filtered.length} resultados</span>
      </div>

      <div className="pk-split">
        {/* master table */}
        <div className="card" style={{ padding: 0, overflow: "hidden" }}>
          <table className="tbl">
            <thead><tr><th>Tag / Equipo</th><th>Categoría</th><th>Ubicación</th><th>Salud</th><th>Estado</th></tr></thead>
            <tbody>
              {filtered.map((a) => (
                <tr key={a.tag} onClick={() => setSel(a.tag)} className={a.tag === current.tag ? "pk-row-sel" : ""} style={{ cursor: "pointer" }}>
                  <td><span className="mono" style={{ fontSize: 11.5, color: "var(--text)" }}>{a.tag}</span><div style={{ fontSize: 12.5, color: "var(--text-2)" }}>{a.name}</div></td>
                  <td>{a.cat}</td>
                  <td className="mono" style={{ fontSize: 11 }}>{pkSite(a.site).code}{a.rack !== "—" && a.u > 0 ? ` · ${a.rack} · U${a.u}` : a.rack !== "—" ? ` · ${a.rack}` : ""}</td>
                  <td><PkHealth h={a.health} /></td>
                  <td><PkState s={a.state} /></td>
                </tr>
              ))}
              {!filtered.length && <tr><td colSpan={5} style={{ textAlign: "center", padding: 30, color: "var(--text-4)" }}>Sin equipos con esos filtros.</td></tr>}
            </tbody>
          </table>
        </div>

        {/* ficha detail */}
        <div className="pk-ficha">{current && <PkFicha asset={current} />}</div>
      </div>
    </div>
  );
}

// ---------- Ficha de activo ----------
function PkFicha({ asset: a }) {
  const cl = pkClient(a.client);
  const site = pkSite(a.site);
  const v = pkVendor(a.warranty.vendor);
  const retiro = a.state === "Retiro" || a.state === "Desmontado";
  return (
    <div className="card" style={{ padding: 18, display: "flex", flexDirection: "column", gap: 16 }}>
      {/* header */}
      <div>
        <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 6, flexWrap: "wrap" }}>
          <span className="mono" style={{ fontSize: 12, color: "var(--pakal)" }}>{a.tag}</span>
          <PkState s={a.state} />
          {retiro && <span className="pk-sync"><Icon name="recycle" size={11} /> Manik</span>}
        </div>
        <h3 className="disp" style={{ fontSize: 17, fontWeight: 600 }}>{a.name}</h3>
        <div className="muted" style={{ fontSize: 12, marginTop: 3 }}>{a.brand} {a.model} · {a.type} · <span className="mono">{a.serial}</span></div>
      </div>

      {/* client + health + location */}
      <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
        <Avatar name={cl.name} initials={cl.name.slice(0,2).toUpperCase()} hue={cl.hue} size={28} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 12.5, color: "var(--text)" }}>{cl.name}</div>
          <div className="mono" style={{ fontSize: 10.5, color: "var(--text-4)" }}>cliente</div>
        </div>
        <PkHealth h={a.health} />
      </div>

      {/* location line */}
      <div style={{ display: "flex", alignItems: "flex-start", gap: 9, padding: "11px 12px", background: "var(--bg-2)", border: "1px solid var(--line)", borderRadius: 10 }}>
        <Icon name="pin" size={16} style={{ color: "var(--pakal)", marginTop: 1 }} />
        <div style={{ fontSize: 12, lineHeight: 1.5 }}>
          <b style={{ color: "var(--text)" }}>{site.name}</b>
          <div className="mono" style={{ fontSize: 11, color: "var(--text-3)", marginTop: 2 }}>
            {a.fase !== "—" ? `${a.fase} · ${a.jaula} · ` : ""}{a.rack}{a.u > 0 ? ` · Nivel U${a.u}` : ""}
          </div>
        </div>
      </div>

      {/* specs */}
      <div>
        <div className="eyebrow" style={{ marginBottom: 8 }}>Características físicas</div>
        <div className="pk-spec">
          <div><div className="k">CPU</div><div className="v">{a.cpu}</div></div>
          <div><div className="k">Memoria</div><div className="v">{a.ram}</div></div>
          <div><div className="k">Discos</div><div className="v">{a.disks}</div></div>
          <div><div className="k">Fuentes</div><div className="v">{a.psu}</div></div>
          <div><div className="k">Ventiladores</div><div className="v">{a.fans}</div></div>
          <div><div className="k">Firmware</div><div className="v">{a.fw}</div></div>
          <div><div className="k">Puertos / Uplinks</div><div className="v">{a.netPorts} · {a.uplinks}</div></div>
          <div><div className="k">SFP's</div><div className="v">{a.sfp}</div></div>
        </div>
      </div>

      {/* component tree */}
      <div>
        <div className="eyebrow" style={{ marginBottom: 8 }}>Componentes ({a.comps.reduce((s,c)=>s+c.qty,0)} piezas)</div>
        <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
          {a.comps.map((c, i) => (
            <div key={i} className="pk-comp">
              <span className="pk-comp-ic"><Icon name={PK_COMP_ICON[c.k] || "boxes"} size={15} /></span>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 12.5, color: "var(--text)" }}>{c.v}</div>
                <div className="mono" style={{ fontSize: 10, color: "var(--text-4)" }}>{c.k}</div>
              </div>
              <span className="pk-comp-q">×{c.qty}</span>
              <span className="badge" style={c.state === "OK" ? { background: "color-mix(in oklch, var(--ok) 16%, transparent)", color: "color-mix(in oklch, var(--ok) 80%, white)" } :
                c.state === "Falla" || c.state === "Degradado" ? { background: "color-mix(in oklch, var(--bad) 18%, transparent)", color: "color-mix(in oklch, var(--bad) 82%, white)" } :
                { background: "var(--pakal-dim)", color: "var(--pakal)" }}>{c.state}</span>
            </div>
          ))}
        </div>
      </div>

      {/* photos */}
      <div>
        <div className="eyebrow" style={{ marginBottom: 8 }}>Fotografías</div>
        <div className="pk-photos">
          {[0,1,2].map(i => (
            <div key={i} className="pk-photo">
              <image-slot id={`pk-photo-${a.tag}-${i}`} shape="rect" placeholder={i===0?"Frontal":i===1?"Etiqueta":"Rack"}></image-slot>
            </div>
          ))}
        </div>
      </div>

      {/* warranty */}
      <div style={{ padding: "13px 14px", borderRadius: 11, background: "var(--bg-2)", border: "1px solid var(--line)" }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 10 }}>
          <div className="eyebrow">Garantía & póliza</div>
          <Pill status={a.warranty.status} />
        </div>
        {[["Fabricante", v.name], ["Integrador", pkVendor(a.warranty.integrator).name || a.warranty.integrator], ["Póliza", a.warranty.policy], ["Vence", a.warranty.end], ["Fin de vida", a.eol]].map(([k,val]) => (
          <div key={k} style={{ display: "flex", justifyContent: "space-between", padding: "5px 0", fontSize: 12 }}>
            <span className="muted">{k}</span><span className="mono" style={{ color: "var(--text)" }}>{val}</span>
          </div>
        ))}
      </div>

      {a.note && <p className="muted" style={{ fontSize: 11.5, lineHeight: 1.5, fontStyle: "italic" }}>{a.note}</p>}

      <div style={{ display: "flex", gap: 8 }}>
        <button className="btn btn-sm" style={{ flex: 1, justifyContent: "center" }}><Icon name="qr" size={14} /> Etiqueta QR</button>
        <button className="btn btn-sm" style={{ flex: 1, justifyContent: "center" }}><Icon name="history" size={14} /> Historial</button>
      </div>
    </div>
  );
}

// ============================================================
//  UBICACIONES + RACK ELEVATION
// ============================================================
function PkUbicaciones({ role }) {
  const sites = window.PK_SITES;
  const [openSite, setOpenSite] = useState("cpd-aurora");
  const R = window.PK_RACK;

  return (
    <div className="canvas-in wide rise pakal">
      <PkHead role={role} title="Ubicaciones & mapa físico"
        sub="Jerarquía CPD → Fase → Jaula → Rack → Nivel/U · direcciones de cada sitio · elevación de rack"
        action={{ label: "Agregar ubicación", icon: "plus" }} />

      <div className="grid-2" style={{ alignItems: "start", gridTemplateColumns: "minmax(0,1fr) minmax(0,1.1fr)", marginBottom: 14 }}>
        {/* sites + tree */}
        <div className="card" style={{ padding: 16 }}>
          <Section title="Sitios" sub="CPDs, bodegas y sitios de cliente" style={{ marginBottom: 12 }} />
          <div className="pk-loc-rail">
            {sites.map(s => (
              <div key={s.id}>
                <div className="pk-loc-node" data-on={openSite === s.id} onClick={() => setOpenSite(openSite === s.id ? "" : s.id)}>
                  <span className="feed-ic" style={{ "--c": s.hue, width: 30, height: 30 }}><Icon name={s.kind === "Bodega" ? "warehouse" : s.kind === "Sitio cliente" ? "building" : "server"} size={15} /></span>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 13, color: "var(--text)", fontWeight: 500 }}>{s.name} <span className="mono" style={{ fontSize: 10.5, color: "var(--text-4)" }}>{s.code}</span></div>
                    <div className="muted" style={{ fontSize: 11 }}>{s.city} · {s.kind}</div>
                  </div>
                  <span className="mono" style={{ fontSize: 11, color: "var(--text-3)" }}>{s.ocupacionPct}%</span>
                  <Icon name="chevdown" size={14} style={{ color: "var(--text-4)", transform: openSite === s.id ? "rotate(180deg)" : "none", transition: "transform 0.18s" }} />
                </div>
                {openSite === s.id && (
                  <div style={{ padding: "4px 0 10px 40px" }}>
                    <div style={{ display: "flex", alignItems: "flex-start", gap: 8, padding: "8px 10px", background: "var(--bg-2)", border: "1px solid var(--line)", borderRadius: 9, marginBottom: 8 }}>
                      <Icon name="pin" size={13} style={{ color: s.hue, marginTop: 1 }} />
                      <span className="mono" style={{ fontSize: 11, color: "var(--text-3)", lineHeight: 1.5 }}>{s.addr}</span>
                    </div>
                    {s.racks > 0 ? (
                      <div style={{ display: "flex", gap: 14, fontSize: 11.5 }}>
                        <span className="muted"><b style={{ color: "var(--text)" }}>{s.fases}</b> fases</span>
                        <span className="muted"><b style={{ color: "var(--text)" }}>{s.jaulas}</b> jaulas</span>
                        <span className="muted"><b style={{ color: "var(--text)" }}>{s.racks}</b> racks</span>
                      </div>
                    ) : <span className="muted" style={{ fontSize: 11.5 }}>Almacén — sin layout de rack</span>}
                  </div>
                )}
              </div>
            ))}
          </div>
        </div>

        {/* rack elevation */}
        <div className="card" style={{ padding: 20 }}>
          <Section title="Elevación de rack" sub={`${R.id} · ${R.site} · ${R.jaula}`} right={<span className="chip" style={{ height: 24 }}>{R.units}U</span>} style={{ marginBottom: 16 }} />
          <div className="pk-rack-wrap">
            <div>
              <div className="pk-rack">
                <div className="pk-rack-top"><span className="mono" style={{ fontSize: 9, color: "var(--text-4)" }}>{R.id}</span></div>
                <div className="pk-rack-grid">
                  {buildRackUnits(R).map((u, i) => (
                    <div key={i} className={"pk-u" + (u.tag && u.cat !== "Libre" ? " clk" : "")} data-cat={u.cat} data-rma={u.state === "RMA"} style={{ height: u.uH * 19 }}>
                      <span className="pk-u-n">{u.uStart}{u.uH > 1 ? `–${u.uStart - u.uH + 1}` : ""}</span>
                      <span className="pk-u-label">{u.label}</span>
                    </div>
                  ))}
                </div>
                <div className="pk-rack-bottom"><span className="mono" style={{ fontSize: 9, color: "var(--text-4)" }}>PDU · A/B</span></div>
              </div>
            </div>
            <div style={{ minWidth: 0 }}>
              <div className="grid-2" style={{ marginBottom: 14 }}>
                <div className="card card-2" style={{ padding: 14 }}><div className="disp" style={{ fontSize: 20, fontWeight: 600 }}>{R.powerKW} <span style={{ fontSize: 12, color: "var(--text-4)" }}>/ {R.powerMaxKW} kW</span></div><div className="muted" style={{ fontSize: 11.5, marginTop: 3 }}>Consumo del rack</div><div className="bar" style={{ marginTop: 8 }}><i style={{ width: (R.powerKW/R.powerMaxKW*100)+"%", background: "var(--pakal)" }} /></div></div>
                <div className="card card-2" style={{ padding: 14 }}><div className="disp" style={{ fontSize: 20, fontWeight: 600 }}>{R.tempC}°C</div><div className="muted" style={{ fontSize: 11.5, marginTop: 3 }}>Temperatura</div><div className="mono" style={{ fontSize: 10.5, color: "var(--ok)", marginTop: 8 }}>dentro de rango</div></div>
              </div>
              <div style={{ display: "flex", flexDirection: "column", gap: 7 }}>
                {[["Servidores","var(--pakal)"],["Networking","var(--manik)"],["Reservado","var(--zamna)"],["Libre","var(--text-4)"]].map(([k,c]) => (
                  <div key={k} style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 12 }}>
                    <span style={{ width: 12, height: 12, borderRadius: 3, background: `color-mix(in oklch, ${c} 30%, var(--surface))`, border: `1px solid ${c}` }} />
                    <span className="muted">{k}</span>
                  </div>
                ))}
              </div>
              <div style={{ marginTop: 14, paddingTop: 14, borderTop: "1px solid var(--line)", display: "flex", alignItems: "center", gap: 8 }}>
                <Avatar name="Vega" initials="VT" hue="var(--manik)" size={24} />
                <span style={{ fontSize: 12, color: "var(--text-2)" }}>Rack asignado a <b style={{ color: "var(--text)" }}>Vega Telecom</b></span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

// build a full 1..units U list, filling gaps as libre
function buildRackUnits(R) {
  const occ = {};
  R.items.forEach(it => { for (let k = 0; k < it.uH; k++) occ[it.uStart - k] = it; });
  const rows = [];
  for (let u = R.units; u >= 1; u--) {
    const it = R.items.find(x => x.uStart === u);
    if (it) { rows.push(it); u -= (it.uH - 1); }
    else if (!occ[u]) rows.push({ uStart: u, uH: 1, label: "— libre —", cat: "Libre", state: "Libre" });
  }
  return rows;
}

Object.assign(window, { PakalApp, PkHead, PkState, PkHealth, PkFicha, pkClient, pkSite, pkVendor, healthHue, PK_COMP_ICON });
