// Módulos nuevos v3.1 — Recomendaciones de Venta · Predicción de Stocks · Predicción de Fuga

// ════════════════════════════════════════════════════════════
// 1 — Recomendaciones de Venta
// ════════════════════════════════════════════════════════════
function RecomendacionesVenta() {
  const { t } = useLang();
  const D = window.APP_DATA;
  const [client, setClient] = React.useState("OBRAMAT Rivas");

  const REC = {
    "OBRAMAT Rivas": {
      argument: "Cliente Clase A con alto consumo de selladores MS pero sin apenas rotación de espumas PU. Rappel al 95% — a 250 uds de cerrar el 5%. Oportunidad clara de upsell en espumas y cierre de rappel este mes.",
      items: ["Orbafoam PRO 65", "Orbafoam Fijación Tejas", "Aqua Protect"],
      promo: "Pack Espumas Q3 — 8% dto. en pedidos ≥ 100 uds",
      price: "6,10 €/ud",
      discount: "8% + rappel 5% al cierre",
      lote: "Palet completo (48 cajas) — porte incluido",
      similar: ["BigMat Leganés", "Distribuciones Alcorcón"],
    },
    "Leroy Merlín Getafe": {
      argument: "Gran superficie DIY con fuerte rotación de espumas y consumo creciente 18% YoY. No tiene rappel activo pese al volumen — riesgo de que la competencia entre por precio. Priorizar activación de rappel.",
      items: ["Sintex MS-35", "Perfect Finish", "1000 Usos"],
      promo: "Activación rappel escalado 3/5/8% por volumen trimestral",
      price: "5,80 €/ud",
      discount: "12% (Clase A gran superficie)",
      lote: "Multipalet — reposición quincenal programada",
      similar: ["Bricodepôt Alcorcón", "BigMat Leganés"],
    },
    "BigMat Leganés": {
      argument: "Almacén de construcción con buen mix pero pedido retenido en finanzas. Consumo estable de adhesivos MS. Oportunidad de cross-sell en impermeabilizantes, categoría que aún no trabaja.",
      items: ["Aqua Protect", "MS Instant Turbo", "Sintex DM-30"],
      promo: "Lanzamiento Aqua Protect — 15% dto. introductorio",
      price: "8,20 €/ud",
      discount: "10% + muestra gratuita",
      lote: "Media paleta (24 cajas)",
      similar: ["OBRAMAT Rivas", "Distribuciones Alcorcón"],
    },
    "Materiales García": {
      argument: "Ferretería profesional con caída de pedidos del 32% en 60 días — riesgo de fuga. Consumo histórico centrado en siliconas y adhesivos. Recomendada oferta de reactivación antes de perder la cuenta.",
      items: ["Sintex N-25 Color", "Fijación 60 Segundos", "1000 Usos"],
      promo: "Oferta reactivación — 10% dto. primer pedido tras 60 días",
      price: "3,80 €/ud",
      discount: "10% reactivación",
      lote: "Caja individual (12 uds) — sin mínimo",
      similar: ["Ferretería Rivas Centro", "Almacenes F. Martín"],
    },
    "Distribuciones Alcorcón": {
      argument: "Distribuidor profesional con rappel al 55% y crecimiento sostenido. Base sólida de selladores. Margen para introducir gama premium de siliconas neutras.",
      items: ["Orbasil N-39", "Perfect Finish", "Sintex Madera"],
      promo: "Gama premium siliconas — 6% dto. cartera",
      price: "4,20 €/ud",
      discount: "6%",
      lote: "Palet mixto configurable",
      similar: ["BigMat Leganés", "OBRAMAT Rivas"],
    },
  };

  const clientList = ["OBRAMAT Rivas", "Leroy Merlín Getafe", "BigMat Leganés", "Materiales García", "Distribuciones Alcorcón"];
  const r = REC[client] || REC["OBRAMAT Rivas"];
  const prod = (name) => D.products.find(p => p.name === name) || {};

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
      <div className="card">
        <div style={{ display: "flex", gap: 16, alignItems: "flex-end", flexWrap: "wrap" }}>
          <div style={{ flex: 1, minWidth: 240 }}>
            <label className="label">{t("Cliente mayorista")}</label>
            <select className="select" value={client} onChange={e => setClient(e.target.value)}>
              {clientList.map(c => <option key={c} value={c}>{c}</option>)}
            </select>
          </div>
          <span className="badge info" style={{ marginBottom: 4 }}>
            <Icon.Spark /> {t("Basado en clientes similares e histórico de ventas")}
          </span>
        </div>
      </div>

      {/* Argumentario */}
      <div className="card" style={{ borderLeft: "3px solid var(--accent)" }}>
        <h3><Icon.Spark /> {t("Argumentario de venta")}</h3>
        <p style={{ margin: 0, fontSize: 14, lineHeight: 1.65, color: "var(--ink-soft)" }}>{t(r.argument)}</p>
        <div style={{ marginTop: 12, display: "flex", gap: 6, flexWrap: "wrap", alignItems: "center" }}>
          <span style={{ fontSize: 12, color: "var(--ink-muted)" }}>{t("Clientes similares:")}</span>
          {r.similar.map(s => <span key={s} className="badge neutral">{s}</span>)}
        </div>
      </div>

      {/* Sugerencias grid */}
      <div className="grid-2">
        <div className="card">
          <h3><Icon.Box /> {t("Artículos recomendados")}</h3>
          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            {r.items.map((it, i) => {
              const p = prod(it);
              return (
                <div key={it} style={{ display: "flex", alignItems: "center", gap: 12, padding: "8px 0", borderTop: i > 0 ? "1px solid var(--border)" : "none" }}>
                  <div style={{ width: 30, height: 30, background: "var(--accent-soft)", color: "var(--accent)", borderRadius: 6, display: "grid", placeItems: "center", fontWeight: 700, fontSize: 13 }}>{i + 1}</div>
                  <div style={{ flex: 1 }}>
                    <div style={{ fontWeight: 500, fontSize: 13 }}>{it}</div>
                    <div className="mono">{p.sku || "—"} · {t(p.family || "")}</div>
                  </div>
                  <span className="badge ok">{t("Alta afinidad")}</span>
                </div>
              );
            })}
          </div>
        </div>

        <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
          <div className="card">
            <h3><Icon.Tag /> {t("Oferta / promoción sugerida")}</h3>
            <div style={{ background: "var(--accent-soft)", borderRadius: 8, padding: 12, fontSize: 13.5, color: "var(--accent-ink)", fontWeight: 500 }}>
              {t(r.promo)}
            </div>
          </div>
          <div className="card">
            <h3><Icon.Chart /> {t("Condiciones sugeridas")}</h3>
            <div style={{ display: "grid", gap: 10 }}>
              <SugItem label={t("Precio sugerido")} value={r.price} />
              <SugItem label={t("Descuento sugerido")} value={t(r.discount)} accent />
              <SugItem label={t("Lote/formato sugerido")} value={t(r.lote)} />
            </div>
          </div>
        </div>
      </div>

      <div style={{ display: "flex", justifyContent: "flex-end", gap: 8 }}>
        <button className="btn-secondary">{t("Generar argumentario PDF")}</button>
        <button className="btn"><Icon.Doc /> {t("Crear pedido con recomendación")}</button>
      </div>
    </div>
  );
}

function SugItem({ label, value, accent }) {
  return (
    <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", borderBottom: "1px solid var(--border)", paddingBottom: 8 }}>
      <span style={{ color: "var(--ink-muted)", fontSize: 12.5 }}>{label}</span>
      <span style={{ fontWeight: 600, fontSize: 13.5, color: accent ? "var(--accent)" : "var(--ink)", textAlign: "right", maxWidth: "60%" }}>{value}</span>
    </div>
  );
}

// ════════════════════════════════════════════════════════════
// 2 — Predicción de Stocks
// ════════════════════════════════════════════════════════════
function PrediccionStocks() {
  const { t } = useLang();
  const [client, setClient] = React.useState("OBRAMAT Rivas");
  const [sortBy, setSortBy] = React.useState("risk");

  // Datos de ejemplo por cliente
  const STOCK = {
    "OBRAMAT Rivas":            { stock: 340, rate: 420, days: 24, depletion: "27/07/2026", risk: "alto",  top: "Sintex MS-35" },
    "Leroy Merlín Getafe":      { stock: 1250, rate: 680, days: 55, depletion: "27/08/2026", risk: "bajo",  top: "Perfect Finish" },
    "BigMat Leganés":           { stock: 210, rate: 380, days: 17, depletion: "20/07/2026", risk: "alto",  top: "MS Instant Turbo" },
    "Almacenes F. Martín":      { stock: 95,  rate: 110, days: 26, depletion: "29/07/2026", risk: "medio", top: "Fijación 60 Segundos" },
    "Distribuciones Alcorcón":  { stock: 720, rate: 340, days: 63, depletion: "04/09/2026", risk: "bajo",  top: "Perfect Finish" },
    "Materiales García":        { stock: 140, rate: 90,  days: 47, depletion: "19/08/2026", risk: "medio", top: "Sintex N-25 Color" },
    "Reformas Rivas S.L.":      { stock: 60,  rate: 200, days: 9,  depletion: "12/07/2026", risk: "alto",  top: "Orbafoam PRO 65" },
  };

  const riskRank = { alto: 0, medio: 1, bajo: 2 };
  const rows = Object.entries(STOCK).map(([name, d]) => ({ name, ...d }));
  const sorted = [...rows].sort((a, b) =>
    sortBy === "risk" ? riskRank[a.risk] - riskRank[b.risk] : a.days - b.days
  );

  const c = STOCK[client];
  const pct = Math.min(100, Math.round((c.days / 90) * 100));

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
      {/* Gráfica de predicción de agotamiento */}
      <div className="card">
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 8, flexWrap: "wrap", gap: 10 }}>
          <div>
            <h3 className="with-sub" style={{ margin: 0 }}>{t("Previsión de consumo y agotamiento")}</h3>
            <div className="h3-sub" style={{ marginBottom: 0 }}>{t("Predicción basada en histórico de ventas del cliente")}</div>
          </div>
          <select className="select" style={{ width: "auto" }} value={client} onChange={e => setClient(e.target.value)}>
            {Object.keys(STOCK).map(k => <option key={k} value={k}>{k}</option>)}
          </select>
        </div>
        <StockForecastChart stock={c.stock} rate={c.rate} days={c.days} depletion={c.depletion} risk={c.risk} t={t} />
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginTop: 10, flexWrap: "wrap", gap: 8 }}>
          <div style={{ display: "flex", gap: 14, fontSize: 11.5, color: "var(--ink-muted)", flexWrap: "wrap" }}>
            <LegendDot color="var(--accent)" label={t("Stock previsto")} />
            <LegendDot color="var(--warn)" label={t("Punto de reposición")} dash />
            <LegendDot color="var(--err)" label={t("Agotamiento estimado")} />
          </div>
          <span style={{ fontSize: 11.5, color: "var(--ink-muted)" }}>{t("Acotado a Selena Iberia (~3.000 clientes activos, mayoristas y retailers)")}</span>
        </div>
      </div>

      {/* Detalle cliente seleccionado */}
      <div className="grid-chart">
        <div className="card">
          <h3 style={{ margin: "0 0 14px" }}>{t("Predicción de agotamiento")} — {client}</h3>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 10, marginBottom: 16 }}>
            <KPI label={t("STOCK ESTIMADO")} value={c.stock} sub={t("uds en cliente")} />
            <KPI label={t("RITMO CONSUMO")} value={c.rate} sub={t("uds/mes")} subType="info" />
            <KPI label={t("DÍAS RESTANTES")} value={c.days} sub={t("hasta rotura")} subType={c.risk === "alto" ? "err" : c.risk === "medio" ? "" : "ok"} />
          </div>
          <div style={{ fontSize: 12, color: "var(--ink-muted)", marginBottom: 6, display: "flex", justifyContent: "space-between" }}>
            <span>{t("Producto principal:")} <b style={{ color: "var(--ink)" }}>{c.top}</b></span>
            <span>{t("Agotamiento estimado:")} <b style={{ color: "var(--ink)" }}>{c.depletion}</b></span>
          </div>
          <div className="progress" style={{ height: 10 }}>
            <div className={"progress-fill " + (c.risk === "alto" ? "cta" : c.risk === "bajo" ? "ok" : "")} style={{ width: pct + "%" }} />
          </div>
          <div style={{ display: "flex", justifyContent: "space-between", fontSize: 11, color: "var(--ink-muted)", marginTop: 4 }}>
            <span>{t("Hoy")}</span><span>90 {t("días")}</span>
          </div>
        </div>

        <div className="card" style={{ display: "flex", flexDirection: "column", justifyContent: "center", gap: 12 }}>
          <div style={{ textAlign: "center" }}>
            <RiskBadge risk={c.risk} big />
            <div style={{ fontSize: 12.5, color: "var(--ink-muted)", marginTop: 10, lineHeight: 1.5 }}>
              {c.risk === "alto"
                ? t("Reposición urgente recomendada. El cliente agotará stock antes de la próxima visita programada.")
                : c.risk === "medio"
                ? t("Vigilar. Incluir en la próxima ruta comercial para valorar reposición.")
                : t("Stock holgado. Sin acción inmediata requerida.")}
            </div>
          </div>
          <button className="btn" style={{ justifyContent: "center" }}><Icon.Doc /> {t("Generar pedido de reposición")}</button>
        </div>
      </div>

      {/* Tabla ordenable */}
      <div className="card" style={{ padding: 0, overflow: "hidden" }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "14px 20px" }}>
          <h3 style={{ margin: 0 }}>{t("Riesgo de rotura de stock por cliente")}</h3>
          <div style={{ display: "flex", gap: 6 }}>
            <button className={sortBy === "risk" ? "btn" : "btn-secondary"} style={{ padding: "6px 12px", fontSize: 12 }} onClick={() => setSortBy("risk")}>{t("Por riesgo")}</button>
            <button className={sortBy === "days" ? "btn" : "btn-secondary"} style={{ padding: "6px 12px", fontSize: 12 }} onClick={() => setSortBy("days")}>{t("Por días restantes")}</button>
          </div>
        </div>
        <table className="table">
          <thead><tr><th>{t("Cliente")}</th><th>{t("Producto principal")}</th><th>{t("Stock est.")}</th><th>{t("Días restantes")}</th><th>{t("Agotamiento")}</th><th>{t("Riesgo rotura")}</th><th></th></tr></thead>
          <tbody>
            {sorted.map(row => (
              <tr key={row.name}>
                <td style={{ fontWeight: 500 }}>{row.name}</td>
                <td style={{ color: "var(--ink-soft)" }}>{row.top}</td>
                <td>{row.stock} uds</td>
                <td style={{ fontWeight: 600, color: row.risk === "alto" ? "var(--err)" : "var(--ink)" }}>{row.days} {t("días")}</td>
                <td className="mono">{row.depletion}</td>
                <td><RiskBadge risk={row.risk} /></td>
                <td><button className="btn-ghost" style={{ padding: "4px 10px", fontSize: 12, borderRadius: 6 }}>{t("Sugerir reposición")}</button></td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

// ════════════════════════════════════════════════════════════
// 3 — Predicción de Fuga de Clientes
// ════════════════════════════════════════════════════════════
function PrediccionFuga() {
  const { t } = useLang();
  const [filter, setFilter] = React.useState("todos");
  const [sortDir, setSortDir] = React.useState("desc");

  const CHURN = [
    { name: "Materiales García",            type: "mayorista", risk: "alto",  score: 82, reason: "Caída de pedidos 32% en últimos 60 días", action: "Ofrecer descuento de reactivación 10%", competitor: null },
    { name: "Ferretería Rivas Centro",       type: "minorista", risk: "alto",  score: 91, reason: "Sin pedidos en 90 días", action: "Visita comercial urgente", competitor: "Ceys" },
    { name: "Reformas Rivas S.L.",           type: "minorista", risk: "alto",  score: 78, reason: "Pasó a comprar a la competencia por precio", action: "Igualar oferta + soporte técnico", competitor: "Sika" },
    { name: "Construcciones Hermanos López", type: "mayorista", risk: "medio", score: 58, reason: "Frecuencia de pedido bajó de mensual a trimestral", action: "Llamada de seguimiento + catálogo Q3", competitor: null },
    { name: "Almacenes F. Martín",           type: "minorista", risk: "medio", score: 54, reason: "Ticket medio −18% en 3 meses", action: "Promo cruzada adhesivos + siliconas", competitor: "Henkel" },
    { name: "Distribuciones Alcorcón",       type: "mayorista", risk: "bajo",  score: 24, reason: "Comportamiento estable, ligera bajada estacional", action: "Sin acción — monitorizar", competitor: null },
    { name: "BigMat Leganés",                type: "mayorista", risk: "bajo",  score: 19, reason: "Pedido retenido puntual (finanzas), relación sana", action: "Resolver retención de pago", competitor: null },
  ];

  const filtered = CHURN.filter(c => filter === "todos" || c.type === filter)
    .sort((a, b) => sortDir === "desc" ? b.score - a.score : a.score - b.score);
  const counts = {
    alto: CHURN.filter(c => c.risk === "alto").length,
    medio: CHURN.filter(c => c.risk === "medio").length,
    minorista: CHURN.filter(c => c.type === "minorista" && c.risk !== "bajo").length,
  };

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
      <div className="kpi-row">
        <KPI label={t("RIESGO ALTO")} value={counts.alto} sub={t("clientes en fuga inminente")} subType="err" />
        <KPI label={t("RIESGO MEDIO")} value={counts.medio} sub={t("a vigilar")} subType="" />
        <KPI label={t("TIENDAS EN RIESGO")} value={counts.minorista} sub={t("puntos de venta minoristas")} subType="err" />
        <KPI label={t("MODELO CHURN")} value="87%" sub={t("precisión histórica")} subType="ok" />
      </div>

      <div className="card">
        <div style={{ marginBottom: 4 }}>
          <h3 className="with-sub" style={{ margin: 0 }}>{t("Score de fuga por cliente")}</h3>
          <div className="h3-sub" style={{ marginBottom: 8 }}>{t("Predicción del modelo de churn sobre histórico de comportamiento")}</div>
        </div>
        <ChurnChart data={[...CHURN].sort((a, b) => b.score - a.score)} t={t} />
      </div>

      <div className="card" style={{ padding: "10px 16px", display: "flex", justifyContent: "space-between", alignItems: "center", flexWrap: "wrap", gap: 8 }}>
        <div style={{ display: "flex", gap: 6 }}>
          {[["todos", t("Todos")], ["mayorista", t("Mayoristas")], ["minorista", t("Minoristas / Tiendas")]].map(([k, l]) => (
            <button key={k} className={filter === k ? "btn" : "btn-secondary"} style={{ padding: "6px 14px", fontSize: 12.5 }} onClick={() => setFilter(k)}>{l}</button>
          ))}
        </div>
        <span style={{ fontSize: 12, color: "var(--ink-muted)" }}>{t("Acotado a Selena Iberia (~3.000 clientes activos, mayoristas y retailers)")}</span>
      </div>

      <div className="card" style={{ padding: 0, overflow: "hidden" }}>
        <table className="table">
          <thead><tr><th>{t("Cliente")}</th><th>{t("Tipo")}</th><th style={{ cursor: "pointer", userSelect: "none", whiteSpace: "nowrap" }} onClick={() => setSortDir(d => d === "desc" ? "asc" : "desc")}>{t("Score fuga")} {sortDir === "desc" ? "▼" : "▲"}</th><th>{t("Riesgo")}</th><th>{t("Motivo detectado")}</th><th>{t("Competidor origen")}</th><th>{t("Acción recomendada")}</th></tr></thead>
          <tbody>
            {filtered.map(c => (
              <tr key={c.name}>
                <td style={{ fontWeight: 500 }}>{c.name}</td>
                <td><span className={"badge " + (c.type === "mayorista" ? "info" : "neutral")}>{t(c.type === "mayorista" ? "Mayorista" : "Minorista")}</span></td>
                <td>
                  <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                    <div style={{ width: 44, height: 6, background: "var(--surface-2)", borderRadius: 99, overflow: "hidden" }}>
                      <div style={{ width: c.score + "%", height: "100%", background: c.risk === "alto" ? "var(--err)" : c.risk === "medio" ? "var(--warn)" : "var(--ok)" }} />
                    </div>
                    <span style={{ fontWeight: 600, fontVariantNumeric: "tabular-nums" }}>{c.score}</span>
                  </div>
                </td>
                <td><RiskBadge risk={c.risk} /></td>
                <td style={{ color: "var(--ink-soft)", maxWidth: 220 }}>{t(c.reason)}</td>
                <td>{c.competitor ? <span className="badge warn">{c.competitor}</span> : <span style={{ color: "var(--ink-muted)" }}>—</span>}</td>
                <td style={{ fontWeight: 500, maxWidth: 200 }}>{t(c.action)}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

// ── Gráfica de previsión de agotamiento de stock
function StockForecastChart({ stock, rate, days, depletion, risk, t }) {
  const W = 920, H = 210, padL = 46, padR = 20, padT = 14, padB = 30;
  const plotW = W - padL - padR, plotH = H - padT - padB;
  const maxDays = 90;
  const ratePerDay = rate / 30;
  const maxStock = Math.max(stock, 10);
  const safety = ratePerDay * 7; // 7 días de seguridad

  const X = (d) => padL + (d / maxDays) * plotW;
  const Y = (v) => padT + plotH - (Math.min(v, maxStock) / maxStock) * plotH;

  // Línea de stock previsto
  const pts = [];
  for (let d = 0; d <= maxDays; d += 2) {
    pts.push([d, Math.max(0, stock - ratePerDay * d)]);
  }
  const linePath = pts.map((p, i) => (i === 0 ? "M" : "L") + X(p[0]).toFixed(1) + " " + Y(p[1]).toFixed(1)).join(" ");
  const areaPath = linePath + " L" + X(Math.min(days, maxDays)).toFixed(1) + " " + Y(0).toFixed(1) + " L" + X(0).toFixed(1) + " " + Y(0).toFixed(1) + " Z";

  const depX = X(Math.min(days, maxDays));
  const col = risk === "alto" ? "var(--err)" : risk === "medio" ? "var(--warn)" : "var(--ok)";

  const yTicks = [0, 0.25, 0.5, 0.75, 1].map(f => Math.round(maxStock * f));
  const xTicks = [0, 15, 30, 45, 60, 75, 90];

  return (
    <svg viewBox={`0 0 ${W} ${H}`} style={{ width: "100%", display: "block" }}>
      <defs>
        <linearGradient id="stockArea" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" stopColor="var(--accent)" stopOpacity="0.28" />
          <stop offset="1" stopColor="var(--accent)" stopOpacity="0.02" />
        </linearGradient>
      </defs>
      {/* Grid + eje Y */}
      {yTicks.map((v, i) => (
        <g key={i}>
          <line x1={padL} y1={Y(v)} x2={W - padR} y2={Y(v)} stroke="var(--border)" strokeWidth="1" />
          <text x={padL - 8} y={Y(v) + 3} textAnchor="end" fontSize="10" fill="var(--ink-muted)">{v}</text>
        </g>
      ))}
      {/* Eje X */}
      {xTicks.map((d, i) => (
        <text key={i} x={X(d)} y={H - 10} textAnchor="middle" fontSize="10" fill="var(--ink-muted)">{d === 0 ? t("Hoy") : d + "d"}</text>
      ))}
      {/* Punto de reposición */}
      <line x1={padL} y1={Y(safety)} x2={W - padR} y2={Y(safety)} stroke="var(--warn)" strokeWidth="1.5" strokeDasharray="5 4" />
      <text x={W - padR} y={Y(safety) - 5} textAnchor="end" fontSize="9.5" fill="oklch(0.5 0.14 75)" fontWeight="600">{t("Punto de reposición")}</text>
      {/* Área + línea */}
      <path d={areaPath} fill="url(#stockArea)" />
      <path d={linePath} fill="none" stroke="var(--accent)" strokeWidth="2.5" strokeLinecap="round" />
      {/* Punto inicial (hoy) */}
      <circle cx={X(0)} cy={Y(stock)} r="4.5" fill="var(--accent)" stroke="#fff" strokeWidth="2" />
      {/* Marcador agotamiento */}
      <line x1={depX} y1={padT} x2={depX} y2={padT + plotH} stroke={col} strokeWidth="1.5" strokeDasharray="3 3" />
      <circle cx={depX} cy={Y(0)} r="5" fill={col} stroke="#fff" strokeWidth="2" />
      <g transform={`translate(${Math.min(depX, W - padR - 96)}, ${padT + 2})`}>
        <rect x="0" y="0" width="96" height="34" rx="6" fill={col} />
        <text x="48" y="14" textAnchor="middle" fontSize="9.5" fill="#fff" opacity="0.9">{t("Agotamiento")}</text>
        <text x="48" y="27" textAnchor="middle" fontSize="11" fill="#fff" fontWeight="700">{depletion}</text>
      </g>
    </svg>
  );
}

function LegendDot({ color, label, dash }) {
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 5 }}>
      {dash
        ? <span style={{ width: 14, height: 0, borderTop: `2px dashed ${color}` }} />
        : <span style={{ width: 10, height: 10, borderRadius: 3, background: color }} />}
      {label}
    </span>
  );
}

// ── Gráfica de riesgo de fuga (barras por score)
function ChurnChart({ data, t }) {
  const W = 920, H = 220, padL = 46, padR = 20, padT = 14, padB = 56;
  const plotW = W - padL - padR, plotH = H - padT - padB;
  const n = data.length;
  const gap = 18;
  const barW = (plotW - gap * (n - 1)) / n;
  const Y = (v) => padT + plotH - (v / 100) * plotH;
  const colOf = (r) => r === "alto" ? "var(--err)" : r === "medio" ? "var(--warn)" : "var(--ok)";

  return (
    <svg viewBox={`0 0 ${W} ${H}`} style={{ width: "100%", display: "block" }}>
      {[0, 25, 50, 75, 100].map((v, i) => (
        <g key={i}>
          <line x1={padL} y1={Y(v)} x2={W - padR} y2={Y(v)} stroke="var(--border)" strokeWidth="1" />
          <text x={padL - 8} y={Y(v) + 3} textAnchor="end" fontSize="10" fill="var(--ink-muted)">{v}</text>
        </g>
      ))}
      {/* Umbral riesgo alto */}
      <line x1={padL} y1={Y(70)} x2={W - padR} y2={Y(70)} stroke="var(--err)" strokeWidth="1.5" strokeDasharray="5 4" opacity="0.6" />
      <text x={W - padR} y={Y(70) - 5} textAnchor="end" fontSize="9.5" fill="var(--err)" fontWeight="600">{t("Umbral riesgo alto")}</text>
      {data.map((d, i) => {
        const x = padL + i * (barW + gap);
        const h = padT + plotH - Y(d.score);
        const col = colOf(d.risk);
        const short = d.name.length > 16 ? d.name.slice(0, 15) + "…" : d.name;
        return (
          <g key={d.name}>
            <rect x={x} y={Y(d.score)} width={barW} height={h} rx="5" fill={col} opacity="0.9" />
            <text x={x + barW / 2} y={Y(d.score) - 6} textAnchor="middle" fontSize="12" fontWeight="700" fill={col}>{d.score}</text>
            <text x={x + barW / 2} y={H - 34} textAnchor="middle" fontSize="9.5" fill="var(--ink-soft)">
              {short.split(" ").slice(0, 2).join(" ")}
            </text>
            <text x={x + barW / 2} y={H - 22} textAnchor="middle" fontSize="9.5" fill="var(--ink-soft)">
              {short.split(" ").slice(2).join(" ")}
            </text>
            <text x={x + barW / 2} y={H - 8} textAnchor="middle" fontSize="8.5" fill="var(--ink-muted)" style={{ textTransform: "uppercase", letterSpacing: "0.04em" }}>
              {t(d.type === "mayorista" ? "Mayorista" : "Minorista")}
            </text>
          </g>
        );
      })}
    </svg>
  );
}

// ── Compartido: badge de riesgo
function RiskBadge({ risk, big }) {
  const { t } = useLang();
  const map = { alto: "err", medio: "warn", bajo: "ok" };
  const label = { alto: t("Alto"), medio: t("Medio"), bajo: t("Bajo") };
  if (big) {
    const col = { alto: "var(--err)", medio: "oklch(0.5 0.14 75)", bajo: "var(--ok)" }[risk];
    const bg = { alto: "var(--err-soft)", medio: "var(--warn-soft)", bajo: "var(--ok-soft)" }[risk];
    return (
      <div style={{ display: "inline-flex", flexDirection: "column", alignItems: "center", gap: 4, background: bg, color: col, padding: "14px 28px", borderRadius: 12 }}>
        <span style={{ fontSize: 11, textTransform: "uppercase", letterSpacing: "0.06em", fontWeight: 600 }}>{t("Riesgo de rotura")}</span>
        <span style={{ fontSize: 22, fontWeight: 700 }}>{label[risk]}</span>
      </div>
    );
  }
  return <span className={"badge " + map[risk]}>{label[risk]}</span>;
}

Object.assign(window, { RecomendacionesVenta, PrediccionStocks, PrediccionFuga });
