/* global React, Icon, formatCOP, formatCompactCOP, LegalDot, EstadoPill, VENTURES, CAMPAIGNS, DEALS, LEGAL_MATTERS, STAGES, STAGE_PROB, CHANNEL_COLOR, VentureEditModal */
const { useState: useStateVD, useEffect: useEffectVD } = React;

/* ------- mini sparkline SVG del historial de ventas ------- */
function VentasSpark({ points }) {
  if (!points || points.length < 2) return null;
  const w = 220, h = 48, max = Math.max(...points, 1), min = Math.min(...points, 0);
  const span = max - min || 1;
  const xy = points.map((v, i) => `${(i / (points.length - 1)) * w},${h - 6 - ((v - min) / span) * (h - 12)}`).join(" ");
  return (
    <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`} className="mt-2">
      <polyline points={xy} fill="none" stroke="#f59e0b" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}

function DCard({ icon, title, accent, children, full }) {
  return (
    <div className={`rounded-xl bg-white p-5 ring-1 ring-taupe-200/70 shadow-sm ${full ? "lg:col-span-2 xl:col-span-3" : ""}`}>
      <div className="mb-3.5 flex items-center gap-2.5">
        <span className={`grid h-8 w-8 place-items-center rounded-lg ${accent || "bg-taupe-100 text-taupe-600"}`}>
          <Icon name={icon} size={16} />
        </span>
        <h4 className="font-bold tracking-tight text-taupe-900">{title}</h4>
      </div>
      {children}
    </div>
  );
}
function DRow({ label, value, tone }) {
  return (
    <div className="flex items-center justify-between gap-3 border-b border-taupe-50 py-1.5 text-sm last:border-0">
      <span className="text-taupe-500">{label}</span>
      <span className={`text-right font-semibold ${tone || "text-taupe-900"}`}>{value}</span>
    </div>
  );
}
function fuenteDatos(updatedBy) {
  if (!updatedBy) return "manual";
  if (updatedBy === "api:lobbypms") return "LobbyPMS (automático)";
  if (updatedBy.startsWith("api:")) return "API del negocio (automático)";
  if (updatedBy.startsWith("agente")) return "agente 3H";
  return `manual (${updatedBy})`;
}
function hace(ts) {
  const m = Math.round((Date.now() - ts) / 60000);
  return m < 60 ? `hace ${m} min` : m < 1440 ? `hace ${Math.round(m / 60)} h` : `hace ${Math.round(m / 1440)} d`;
}

/* ------- catálogo comercial: precios, planes y ofertas (fuente: Hub) ------- */
function OfferRow({ item, canEdit, onSave, onDelete }) {
  const [confirm, setConfirm] = useStateVD(false);
  return (
    <div className="flex flex-wrap items-center gap-x-3 gap-y-1 border-b border-taupe-50 py-2 last:border-0">
      <div className="min-w-0 flex-1">
        <div className="flex items-center gap-2">
          <span className={`truncate text-sm font-semibold ${item.activo ? "text-taupe-900" : "text-taupe-400 line-through"}`}>{item.nombre}</span>
          <span className="shrink-0 rounded-full bg-taupe-100 px-2 py-0.5 text-[10px] font-bold uppercase tracking-wide text-taupe-500">{item.tipo}</span>
          {item.destacado && <Icon name="Star" size={12} className="shrink-0 text-amber-500" />}
        </div>
        {item.descripcion && <div className="truncate text-[11px] text-taupe-400">{item.descripcion}</div>}
      </div>
      {canEdit ? (
        <input
          key={`${item.id}:${item.precio}`}
          type="number"
          defaultValue={item.precio || ""}
          onKeyDown={(e) => { if (e.key === "Enter") e.target.blur(); }}
          onBlur={(e) => { const v = Math.round(Number(e.target.value) || 0); if (v !== item.precio) onSave(item.id, { precio: v }); }}
          className="w-32 rounded-lg border border-taupe-200 bg-white px-2 py-1 text-right text-sm font-semibold tabular-nums text-taupe-900 focus:border-amber-400 focus:outline-none"
        />
      ) : (
        <span className="text-sm font-semibold tabular-nums text-taupe-900">{item.precio ? formatCOP(item.precio) : "—"}</span>
      )}
      {item.periodo && <span className="text-[11px] text-taupe-400">/{item.periodo}</span>}
      {canEdit && (
        <React.Fragment>
          <button onClick={() => onSave(item.id, { activo: !item.activo })}
            className={`rounded-full px-2.5 py-1 text-[10px] font-bold ring-1 transition ${item.activo ? "bg-emerald-50 text-emerald-700 ring-emerald-200 hover:bg-emerald-100" : "bg-taupe-100 text-taupe-500 ring-taupe-200 hover:bg-taupe-200"}`}
            title={item.activo ? "Visible en la página y para el agente" : "Oculto del público"}>
            {item.activo ? "Publicado" : "Oculto"}
          </button>
          {confirm ? (
            <button onClick={() => onDelete(item.id)} className="rounded-full bg-red-600 px-2.5 py-1 text-[10px] font-bold text-white">¿Eliminar?</button>
          ) : (
            <button onClick={() => { setConfirm(true); setTimeout(() => setConfirm(false), 2500); }} className="grid h-7 w-7 place-items-center rounded-lg text-taupe-300 transition hover:bg-red-50 hover:text-red-600" title="Eliminar">
              <Icon name="Trash2" size={13} />
            </button>
          )}
        </React.Fragment>
      )}
    </div>
  );
}

function OffersCard({ venture, canEdit }) {
  /* EXCEPCIÓN: Mística no se alimenta desde el Hub — tarifas dinámicas del PMS. */
  if (venture.id === "mistica") {
    return (
      <DCard icon="Tags" title="Precios, planes y ofertas" accent="bg-amber-100 text-amber-700" full>
        <p className="text-sm leading-relaxed text-taupe-600">
          Las tarifas de Mística Hostels <strong>no se alimentan desde el Hub</strong>: las gestiona el PMS (LobbyPMS) con precios dinámicos por fecha y ocupación, y el agente de ventas las consulta en vivo al cotizar. Cualquier cambio de tarifa se hace directamente en LobbyPMS.
        </p>
      </DCard>
    );
  }
  const live = window.__dataSource === "live";
  const [items, setItems] = useStateVD(null);
  const [q, setQ] = useStateVD("");
  const [adding, setAdding] = useStateVD(false);
  const [draft, setDraft] = useStateVD({ nombre: "", tipo: "precio", precio: "", periodo: "", descripcion: "" });
  const [msg, setMsg] = useStateVD("");

  const load = () => fetch(`/api/offers/${venture.id}`, { credentials: "include" })
    .then((r) => (r.ok ? r.json() : null))
    .then((d) => setItems(d ? d.items || [] : []))
    .catch(() => setItems([]));
  useEffectVD(() => { if (live) load(); else setItems([]); }, [venture.id]);

  const flash = (t) => { setMsg(t); setTimeout(() => setMsg(""), 2600); };
  const save = (id, patch) =>
    fetch(`/api/offers/item/${id}`, { method: "PUT", credentials: "include", headers: { "content-type": "application/json" }, body: JSON.stringify(patch) })
      .then((r) => { if (r.ok) { flash("Guardado · página y agente actualizados ✓"); load(); } else flash("No se pudo guardar"); });
  const del = (id) =>
    fetch(`/api/offers/item/${id}`, { method: "DELETE", credentials: "include" })
      .then((r) => { if (r.ok) { flash("Eliminado ✓"); load(); } else flash("No se pudo eliminar"); });
  const add = () => {
    if (!draft.nombre) return;
    fetch(`/api/offers/${venture.id}`, { method: "POST", credentials: "include", headers: { "content-type": "application/json" }, body: JSON.stringify({ ...draft, precio: Number(draft.precio) || 0 }) })
      .then((r) => { if (r.ok) { setAdding(false); setDraft({ nombre: "", tipo: "precio", precio: "", periodo: "", descripcion: "" }); flash("Creado ✓"); load(); } else flash("No se pudo crear"); });
  };

  const list = items || [];
  const activos = list.filter((i) => i.activo);
  const precios = activos.map((i) => i.precio).filter((p) => p > 0);
  const filtered = q ? list.filter((i) => (i.nombre + " " + (i.descripcion || "")).toLowerCase().includes(q.toLowerCase())) : list;
  const publicUrl = `${location.origin}/api/public/offers/${venture.id}`;
  const inputCls = "rounded-lg border border-taupe-200 bg-white px-2.5 py-1.5 text-sm text-taupe-900 focus:border-amber-400 focus:outline-none";

  return (
    <DCard icon="Tags" title="Precios, planes y ofertas" accent="bg-amber-100 text-amber-700" full>
      <div className="mb-2.5 flex flex-wrap items-center gap-2">
        <span className="rounded-full bg-emerald-50 px-2 py-0.5 text-[11px] font-semibold text-emerald-700 ring-1 ring-emerald-200">{activos.length} publicados</span>
        <span className="rounded-full bg-taupe-100 px-2 py-0.5 text-[11px] font-semibold text-taupe-500 ring-1 ring-taupe-200">{list.length - activos.length} ocultos</span>
        {precios.length > 0 && (
          <span className="rounded-full bg-amber-50 px-2 py-0.5 text-[11px] font-semibold text-amber-700 ring-1 ring-amber-200">
            desde {formatCompactCOP(Math.min(...precios))} hasta {formatCompactCOP(Math.max(...precios))}
          </span>
        )}
        <span className="flex-1" />
        {msg && <span className="text-[11px] font-semibold text-emerald-600">{msg}</span>}
        {list.length > 6 && (
          <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Buscar ítem…" className={`${inputCls} w-36`} />
        )}
        {canEdit && (
          <button onClick={() => setAdding(!adding)} className="inline-flex items-center gap-1.5 rounded-full bg-taupe-900 px-3 py-1.5 text-[11px] font-bold text-amber-300 transition hover:bg-taupe-800">
            <Icon name={adding ? "X" : "Plus"} size={12} /> {adding ? "Cancelar" : "Agregar ítem"}
          </button>
        )}
      </div>

      {adding && (
        <div className="mb-3 grid gap-2 rounded-xl bg-taupe-50 p-3 ring-1 ring-taupe-100 sm:grid-cols-2 lg:grid-cols-6">
          <input value={draft.nombre} onChange={(e) => setDraft({ ...draft, nombre: e.target.value })} placeholder="Nombre *" className={`${inputCls} lg:col-span-2`} />
          <select value={draft.tipo} onChange={(e) => setDraft({ ...draft, tipo: e.target.value })} className={inputCls}>
            <option value="precio">precio</option><option value="plan">plan</option><option value="oferta">oferta</option><option value="lote">lote</option><option value="servicio">servicio</option>
          </select>
          <input value={draft.precio} onChange={(e) => setDraft({ ...draft, precio: e.target.value })} type="number" placeholder="Precio COP" className={inputCls} />
          <input value={draft.periodo} onChange={(e) => setDraft({ ...draft, periodo: e.target.value })} placeholder="Periodo (mes…)" className={inputCls} />
          <button onClick={add} disabled={!draft.nombre} className="rounded-lg bg-emerald-600 px-3 py-1.5 text-sm font-bold text-white transition hover:bg-emerald-700 disabled:opacity-40">Crear</button>
          <input value={draft.descripcion} onChange={(e) => setDraft({ ...draft, descripcion: e.target.value })} placeholder="Descripción corta (opcional)" className={`${inputCls} sm:col-span-2 lg:col-span-6`} />
        </div>
      )}

      {items === null && <div className="text-sm text-taupe-400">Cargando catálogo…</div>}
      {items !== null && list.length === 0 && (
        <div className="text-sm text-taupe-400">Sin precios publicados aún. {canEdit ? "Agrega el primero: la página del proyecto y el agente de ventas lo toman automáticamente." : ""}</div>
      )}
      <div className="max-h-80 overflow-y-auto pr-1">
        {filtered.map((it) => <OfferRow key={it.id} item={it} canEdit={canEdit} onSave={save} onDelete={del} />)}
        {items !== null && list.length > 0 && filtered.length === 0 && <div className="py-2 text-sm text-taupe-400">Nada coincide con "{q}".</div>}
      </div>

      <p className="mt-3 border-t border-taupe-100 pt-2.5 text-[11px] leading-relaxed text-taupe-500">
        Fuente única de verdad: lo que edites aquí alimenta la página del proyecto y el conocimiento del agente de ventas al instante.
        API pública para conectar cualquier sitio: <code className="select-all rounded bg-taupe-100 px-1.5 py-0.5 font-mono text-[10px] text-taupe-700">{publicUrl}</code>
      </p>
    </DCard>
  );
}

function VentureDetail({ venture, canEdit, canOffers, onBack }) {
  const live = window.__dataSource === "live";
  const [hist, setHist] = useStateVD([]);
  const [acts, setActs] = useStateVD([]);
  const [strats, setStrats] = useStateVD(null);
  const [editing, setEditing] = useStateVD(false);

  useEffectVD(() => {
    let off = false;
    if (!live) return;
    fetch(`/api/ingest/${venture.id}`, { credentials: "include" })
      .then((r) => (r.ok ? r.json() : null))
      .then((d) => { if (!off && d) setHist((d.metrics || []).slice().reverse()); })
      .catch(() => {});
    fetch("/api/agents", { credentials: "include" })
      .then((r) => (r.ok ? r.json() : null))
      .then((d) => { if (!off && d) setActs((d.actions || []).filter((a) => a.venture === venture.id)); })
      .catch(() => {});
    if (venture.alzioPropertyId) {
      fetch(`/api/marketing-agency/strategies/${venture.alzioPropertyId}`, { credentials: "include" })
        .then((r) => (r.ok ? r.json() : []))
        .then((d) => { if (!off) setStrats(Array.isArray(d) ? d : (d.items || [])); })
        .catch(() => { if (!off) setStrats([]); });
    } else setStrats([]);
    return () => { off = true; };
  }, [venture.id]);

  const camps = CAMPAIGNS.filter((c) => c.venture === venture.id);
  const activas = camps.filter((c) => c.activa);
  const borradores = camps.filter((c) => !c.activa);
  const inversion = activas.reduce((a, c) => a + (c.presupuesto || 0), 0);
  const leads = activas.reduce((a, c) => a + (c.leads || 0), 0);
  const porCanal = {};
  activas.forEach((c) => { porCanal[c.canal] = (porCanal[c.canal] || 0) + (c.presupuesto || 0); });

  const ds = DEALS.filter((d) => d.venture === venture.id);
  const cerrados = ds.filter((d) => d.etapa === "Cerrado");
  const abiertos = ds.filter((d) => d.etapa !== "Cerrado").sort((a, b) => b.valor * STAGE_PROB[b.etapa] - a.valor * STAGE_PROB[a.etapa]);
  const pipeline = abiertos.reduce((a, d) => a + d.valor, 0);
  const ponderado = abiertos.reduce((a, d) => a + d.valor * STAGE_PROB[d.etapa], 0);

  const orden = { rojo: 0, amarillo: 1, verde: 2 };
  const ms = LEGAL_MATTERS.filter((m) => m.venture === venture.id).sort((a, b) => orden[a.estado] - orden[b.estado]);
  const rojo = ms.filter((m) => m.estado === "rojo").length, amarillo = ms.filter((m) => m.estado === "amarillo").length;

  const canal = acts.find((a) => a.tipo === "canal");
  const planMkt = acts.find((a) => a.tipo === "plan");
  const margen = venture.ventasMes > 0 ? Math.round((venture.utilidad / venture.ventasMes) * 100) : null;
  const stActuales = (strats || []).filter((s) => ["approved", "active", "in_progress"].includes(s.status));
  const stPotenciales = (strats || []).filter((s) => s.status === "proposed");

  return (
    <div className="space-y-5">
      {/* Header de la ficha */}
      <div className="flex flex-wrap items-center justify-between gap-3">
        <div className="flex min-w-0 items-center gap-3">
          <button onClick={onBack} className="grid h-9 w-9 shrink-0 place-items-center rounded-lg bg-white text-taupe-700 ring-1 ring-taupe-200 transition hover:bg-taupe-50" title="Volver">
            <Icon name="ArrowLeft" size={16} />
          </button>
          <span className="grid h-11 w-11 shrink-0 place-items-center rounded-xl bg-taupe-900 text-amber-300">
            <Icon name={venture.icon} size={22} />
          </span>
          <div className="min-w-0">
            <div className="flex flex-wrap items-center gap-2">
              <h2 className="text-xl font-extrabold tracking-tight text-taupe-900">{venture.name}</h2>
              <EstadoPill estado={venture.estado} />
              <LegalDot level={venture.legal} withLabel />
            </div>
            <div className="truncate text-xs text-taupe-500">{venture.sector} · ficha 360° del negocio</div>
          </div>
        </div>
        {canEdit && (
          <button onClick={() => setEditing(true)} className="inline-flex items-center gap-1.5 rounded-full bg-taupe-900 px-3.5 py-2 text-xs font-bold text-amber-300 transition hover:bg-taupe-800">
            <Icon name="Pencil" size={13} /> Editar datos
          </button>
        )}
      </div>
      {editing && <VentureEditModal venture={venture} onClose={() => setEditing(false)} />}

      <div className="grid gap-4 lg:grid-cols-2 xl:grid-cols-3">
        {/* Estado operativo */}
        <DCard icon="Activity" title="Estado operativo" accent="bg-taupe-900 text-amber-300">
          <DRow label="Estado" value={venture.estado} />
          <DRow label="Desarrollo" value={`${venture.desarrollo}%`} />
          <DRow label="Sitio web" value={venture.url ? venture.url : "sin sitio"} tone={venture.url ? "text-taupe-900" : "text-taupe-300"} />
          {venture.conexiones && venture.conexiones.length > 0 && (
            <DRow label="Sinergias" value={venture.conexiones.map((c) => (VENTURES.find((v) => v.id === c) || {}).name || c).join(", ")} />
          )}
          <p className="mt-3 border-t border-taupe-100 pt-2.5 text-xs leading-relaxed text-taupe-500">{venture.blurb}</p>
        </DCard>

        {/* Ventas reales */}
        <DCard icon="DollarSign" title="Ventas reales" accent="bg-emerald-100 text-emerald-700">
          <div className="text-[26px] font-extrabold leading-none tracking-tight text-taupe-900">{formatCompactCOP(venture.ventasMes)}</div>
          <div className="mt-1 text-xs text-taupe-500">{formatCOP(venture.ventasMes)} este mes</div>
          <VentasSpark points={hist.map((m) => m.ventasMes || 0).filter((v) => v !== null)} />
          <DRow label="Fuente de datos" value={fuenteDatos(venture.updatedBy)} />
          <DRow label="Registros de historial" value={hist.length} />
        </DCard>

        {/* Rentabilidad y gastos */}
        <DCard icon="TrendingUp" title="Rentabilidad y gastos" accent="bg-amber-100 text-amber-700">
          <DRow label="Utilidad del mes" value={formatCompactCOP(venture.utilidad)} tone={venture.utilidad < 0 ? "text-red-600" : "text-emerald-700"} />
          {margen !== null && <DRow label="Margen" value={`${margen}%`} />}
          <DRow label="Costos estimados" value={venture.ventasMes > 0 ? formatCompactCOP(venture.ventasMes - venture.utilidad) : "—"} />
          <DRow label="Inversión en marketing" value={formatCompactCOP(inversion)} />
          <div className="mt-2.5 space-y-1.5">
            {Object.entries(porCanal).map(([canal_, monto]) => (
              <div key={canal_} className="flex items-center justify-between text-xs">
                <span className="inline-flex items-center gap-1.5 font-medium text-taupe-600">
                  <span className="h-2 w-2 rounded-full" style={{ background: CHANNEL_COLOR[canal_] || "#9d8980" }} /> {canal_}
                </span>
                <span className="font-mono font-bold text-taupe-700">{formatCompactCOP(monto)}</span>
              </div>
            ))}
            {activas.length === 0 && <div className="text-xs text-taupe-400">Sin campañas activas: el agente ya propuso borradores.</div>}
          </div>
        </DCard>

        {/* Clientes actuales */}
        <DCard icon="UserCheck" title={`Clientes actuales (${cerrados.length})`} accent="bg-emerald-100 text-emerald-700">
          {cerrados.length === 0 && <div className="text-sm text-taupe-400">Aún sin ventas cerradas registradas.</div>}
          {cerrados.slice(0, 5).map((d) => (
            <DRow key={d.id} label={d.cliente} value={formatCompactCOP(d.valor)} />
          ))}
          {cerrados.length > 0 && <DRow label="Total cerrado" value={formatCompactCOP(cerrados.reduce((a, d) => a + d.valor, 0))} tone="text-emerald-700" />}
        </DCard>

        {/* Clientes potenciales */}
        <DCard icon="Users" title={`Clientes potenciales (${abiertos.length})`} accent="bg-taupe-100 text-taupe-700">
          {abiertos.length === 0 && <div className="text-sm text-taupe-400">Pipeline vacío: revisa el plan de prospección del agente.</div>}
          {abiertos.slice(0, 5).map((d) => (
            <div key={d.id} className="flex items-center justify-between gap-2 border-b border-taupe-50 py-1.5 text-sm last:border-0">
              <span className="min-w-0 truncate text-taupe-700">{d.cliente}</span>
              <span className="shrink-0 rounded-full bg-taupe-100 px-2 py-0.5 text-[10px] font-semibold text-taupe-600">{d.etapa}</span>
              <span className="shrink-0 font-semibold text-taupe-900">{formatCompactCOP(d.valor)}</span>
            </div>
          ))}
          <DRow label="Pipeline" value={formatCompactCOP(pipeline)} />
          <DRow label="Ponderado por etapa" value={formatCompactCOP(Math.round(ponderado))} tone="text-amber-600" />
        </DCard>

        {/* Estado jurídico */}
        <DCard icon="Scale" title="Estado jurídico" accent="bg-red-100 text-red-700">
          <div className="mb-2 flex gap-2 text-[11px] font-semibold">
            <span className="rounded-full bg-red-50 px-2 py-0.5 text-red-700 ring-1 ring-red-200">{rojo} acción</span>
            <span className="rounded-full bg-amber-50 px-2 py-0.5 text-amber-700 ring-1 ring-amber-200">{amarillo} en revisión</span>
            <span className="rounded-full bg-emerald-50 px-2 py-0.5 text-emerald-700 ring-1 ring-emerald-200">{ms.length - rojo - amarillo} al día</span>
          </div>
          {ms.length === 0 && <div className="text-sm text-taupe-400">Sin asuntos registrados: el agente jurídico abrirá los de cumplimiento base.</div>}
          {ms.slice(0, 5).map((m) => (
            <div key={m.id} className="flex items-center justify-between gap-2 border-b border-taupe-50 py-1.5 text-sm last:border-0">
              <span className="flex min-w-0 items-center gap-2 truncate text-taupe-700"><LegalDot level={m.estado} /> <span className="truncate">{m.asunto}</span></span>
              <span className="shrink-0 text-xs text-taupe-400">{m.vence}</span>
            </div>
          ))}
        </DCard>

        {/* Estrategias de marketing */}
        <DCard icon="Lightbulb" title="Estrategias de marketing" accent="bg-amber-100 text-amber-700">
          {strats === null && <div className="text-sm text-taupe-400">Cargando estrategias…</div>}
          {strats !== null && (
            <div className="space-y-2.5">
              <div>
                <div className="mb-1 font-mono text-[10px] uppercase tracking-wide text-taupe-400">Actuales ({stActuales.length})</div>
                {stActuales.length === 0 && <div className="text-xs text-taupe-400">Ninguna activa aún.</div>}
                {stActuales.slice(0, 3).map((s) => <div key={s.id} className="truncate text-sm font-semibold text-taupe-800">• {s.title}</div>)}
              </div>
              <div>
                <div className="mb-1 font-mono text-[10px] uppercase tracking-wide text-taupe-400">Potenciales ({stPotenciales.length + borradores.length})</div>
                {stPotenciales.slice(0, 3).map((s) => <div key={s.id} className="truncate text-sm text-taupe-700">• {s.title} <span className="text-[10px] text-amber-600">(por aprobar)</span></div>)}
                {borradores.slice(0, 2).map((c) => <div key={c.id} className="truncate text-sm text-taupe-700">• Campaña "{c.nombre}" <span className="text-[10px] text-amber-600">(borrador)</span></div>)}
                {stPotenciales.length + borradores.length === 0 && <div className="text-xs text-taupe-400">Genera una en Marketing → Estrategias.</div>}
              </div>
              {planMkt && <p className="border-t border-taupe-100 pt-2 text-[11px] leading-snug text-taupe-500">Último plan del agente: {hace(planMkt.ts)}.</p>}
            </div>
          )}
        </DCard>

        {/* Conexiones y redes */}
        <DCard icon="Plug" title="Conexiones y redes" accent="bg-taupe-900 text-amber-300">
          <DRow label="Chat / WhatsApp" value={canal ? (canal.estado === "hecho" ? "Activo (agente)" : "Por conectar") : "Por conectar"} tone={canal && canal.estado === "hecho" ? "text-emerald-700" : "text-amber-600"} />
          <DRow label="Sitio web" value={venture.url ? "Conectado" : "Por crear"} tone={venture.url ? "text-emerald-700" : "text-amber-600"} />
          <DRow label="Datos de ventas" value={venture.updatedBy && String(venture.updatedBy).startsWith("api:") ? "Sincronizado" : "Manual / llave lista"} tone={venture.updatedBy && String(venture.updatedBy).startsWith("api:") ? "text-emerald-700" : "text-amber-600"} />
          <DRow label="Redes sociales" value="Por conectar" tone="text-amber-600" />
          <DRow label="Perfil de Google" value="Por crear" tone="text-amber-600" />
          <p className="mt-2 border-t border-taupe-100 pt-2 text-[11px] text-taupe-400">El agente de marketing deja el contenido listo; al conectar cada canal, publica y responde solo.</p>
        </DCard>

        {/* Precios, planes y ofertas (catálogo central) */}
        <OffersCard venture={venture} canEdit={canOffers !== undefined ? canOffers : canEdit} />

        {/* Ejecución de los agentes */}
        <DCard icon="Bot" title="Ejecución de los agentes" accent="bg-taupe-900 text-amber-300" full>
          {acts.length === 0 && <div className="text-sm text-taupe-400">Sin acciones registradas todavía para este negocio.</div>}
          <div className="grid gap-2 lg:grid-cols-2">
            {acts.slice(0, 10).map((a) => (
              <div key={a.id} className="rounded-lg bg-taupe-50 px-3 py-2 ring-1 ring-taupe-100">
                <div className="flex flex-wrap items-center justify-between gap-x-3 gap-y-0.5">
                  <span className="text-xs font-semibold text-taupe-800">{a.titulo}</span>
                  <span className="font-mono text-[10px] text-taupe-400">{a.agente} · {a.estado === "sugerido" ? "sugerencia · " : ""}{hace(a.ts)}</span>
                </div>
                {a.detalle && <div className="mt-0.5 line-clamp-2 text-[11px] leading-snug text-taupe-500">{a.detalle}</div>}
              </div>
            ))}
          </div>
        </DCard>
      </div>
    </div>
  );
}

Object.assign(window, { VentureDetail });
