const { useState, useMemo, useEffect } = React;

const DEFAULTS = {
  nombre: "Departamento en preventa",
  ubicacion: "CDMX",
  precio: 4500000,
  engPct: 10,
  mensPct: 30,
  numMensualidades: 24,
  entregaPct: 60,
  escrituraPct: 7,
  // ROI
  tarifaProm: 2400,
  ocupacion: 70,
  comisionPct: 15,
  adminPct: 5,
  gastosFijos: 4500,
  plusvalia: 10,
  inflacionRenta: 5,
  horizonte: 10,
  usarCredito: true,
  tasaCredito: 11.5,
  plazoCredito: 20,
};

function App() {
  const { calcular, fmtMXN, fmtPct, fmtNum } = window.CalcLogic;

  const [tweaks, setTweaksLocal] = useState({ accent: "bronce", modoVista: "analisis" });
  useEffect(() => {
    window.__appSetTweak = (k, v) => setTweaksLocal((s) => ({ ...s, [k]: v }));
    return () => { delete window.__appSetTweak; };
  }, []);
  useEffect(() => {
    const accents = {
      bronce: "oklch(0.55 0.08 95)",
      indigo: "oklch(0.45 0.10 260)",
      bosque: "oklch(0.45 0.07 150)",
      vino: "oklch(0.45 0.10 25)",
    };
    document.documentElement.style.setProperty("--accent", accents[tweaks.accent] || accents.bronce);
  }, [tweaks.accent]);

  const [inputs, setInputs] = useState(DEFAULTS);
  const set = (k) => (v) => setInputs((s) => ({ ...s, [k]: v }));
  const setNum = (k) => (v) => setInputs((s) => ({ ...s, [k]: v === "" ? 0 : +v }));

  const r = useMemo(() => calcular(inputs), [inputs]);
  const roi = useMemo(() => window.CalcLogic.calcularROI(
    r.precio, r.contraEntrega, r.escrituracion, r.totalAPagar, inputs
  ), [r, inputs]);

  // Auto-balancear: si suma != 100, calcula faltante para sugerir
  const faltante = 100 - (inputs.engPct + inputs.mensPct + inputs.entregaPct);

  const setTweak = (k, v) => {
    setTweaksLocal((s) => ({ ...s, [k]: v }));
    window.parent.postMessage({ type: '__edit_mode_set_keys', edits: { [k]: v } }, '*');
  };
  const presentMode = tweaks.modoVista === "presentacion";

  return (
    <div className={"app " + (presentMode ? "app--present" : "")}>
      <InlineStyles />
      <Header inputs={inputs} setInputs={setInputs} presentMode={presentMode} setTweak={setTweak} />
      <main className="layout">
        {!presentMode && (
          <aside className="panel panel--inputs">
            <div className="panel__head">
              <h2 className="panel__title">Esquema de pagos</h2>
              <p className="panel__sub">Define el precio y los porcentajes</p>
            </div>
            <InputsForm inputs={inputs} set={set} setNum={setNum} faltante={faltante} balanceadoOk={r.balanceadoOk} />
          </aside>
        )}
        <section className="panel panel--results">
          <Results r={r} inputs={inputs} faltante={faltante} />
          {!presentMode && (
            <ROIInputs inputs={inputs} set={set} setNum={setNum} />
          )}
          <ROIResults roi={roi} r={r} inputs={inputs} />
          <PdfDownloadButton targetSelector=".panel--results" filename="reporte-inversion.pdf" />
        </section>
      </main>
      <Disclaimer />
      <PrintFooter inputs={inputs} />
    </div>
  );
}

function Disclaimer() {
  return (
    <section className="disclaimer">
      <div className="disclaimer__inner">
        <div className="disclaimer__label">Nota importante</div>
        <p className="disclaimer__text">
          Este documento es una simulación de carácter informativo y meramente ilustrativo.
          Las cifras aquí presentadas son estimaciones basadas en los datos proporcionados y
          las condiciones actuales del mercado. Los valores reales, tasas de interés, gastos
          notariales y rendimientos finales pueden variar al momento de la operación formal.
          AZ Real Estate no se hace responsable por variaciones en los resultados finales de
          la inversión.
        </p>
      </div>
    </section>
  );
}

function Header({ inputs, setInputs, presentMode, setTweak }) {
  return (
    <header className="header">
      <div className="header__brand">
        <img className="header__mark" src="logo.png" alt="AZ Real Estate" />
        <div>
          <div className="header__name">AZ Real Estate</div>
          <div className="header__tag">Calculadora de Rentabilidad Inmobilairia</div>
        </div>
      </div>
      <div className="header__property">
        <input
          className="header__title-input"
          value={inputs.nombre}
          onChange={(e) => setInputs((s) => ({ ...s, nombre: e.target.value }))}
        />
        <input
          className="header__sub-input"
          value={inputs.ubicacion}
          onChange={(e) => setInputs((s) => ({ ...s, ubicacion: e.target.value }))}
        />
      </div>
      <div className="header__actions">
        <button className="btn btn--ghost" onClick={() => setTweak("modoVista", presentMode ? "analisis" : "presentacion")}>
          {presentMode ? "Modo análisis" : "Modo presentación"}
        </button>
        <button className="btn btn--solid" onClick={() => window.print()}>Imprimir / PDF</button>
      </div>
    </header>
  );
}

function InputsForm({ inputs, set, setNum, faltante, balanceadoOk }) {
  const { fmtMXN, fmtPct } = window.CalcLogic;
  const precio = +inputs.precio || 0;

  return (
    <div className="form">
      <Section title="Precio del inmueble">
        <NumberField
          label="Precio total"
          prefix="$"
          value={inputs.precio}
          onChange={setNum("precio")}
          step={50000}
          hint={fmtMXN(precio) + " MXN"}
        />
      </Section>

      <Section title="Esquema de pagos" badge={fmtPct(inputs.engPct + inputs.mensPct + inputs.entregaPct, 1)} badgeOk={balanceadoOk}>
        <PctRow
          label="Enganche (firma)"
          value={inputs.engPct}
          onChange={set("engPct")}
          derivedAmount={precio * (inputs.engPct / 100)}
          accent="var(--accent)"
        />

        <PctRow
          label="Mensualidades (durante construcción)"
          value={inputs.mensPct}
          onChange={set("mensPct")}
          derivedAmount={precio * (inputs.mensPct / 100)}
          accent="var(--ink)"
        />

        <div className="form__row">
          <NumberField
            label="Número de mensualidades"
            value={inputs.numMensualidades}
            onChange={setNum("numMensualidades")}
            step={1}
            min={1}
            suffix="meses"
          />
          <NumberField
            label="Cada mensualidad"
            value={Math.round(precio * (inputs.mensPct / 100) / Math.max(1, inputs.numMensualidades))}
            onChange={() => { }}
            prefix="$"
            hint="Calculado automáticamente"
          />
        </div>

        <PctRow
          label="Saldo contra entrega"
          value={inputs.entregaPct}
          onChange={set("entregaPct")}
          derivedAmount={precio * (inputs.entregaPct / 100)}
          accent="oklch(0.65 0.06 95)"
        />

        {!balanceadoOk && (
          <div className={"balance " + (faltante > 0 ? "balance--less" : "balance--more")}>
            <span>
              {faltante > 0
                ? `Falta ${fmtPct(faltante, 1)} para completar el 100%`
                : `Excede ${fmtPct(-faltante, 1)} del precio total`}
            </span>
            <button
              className="balance__fix"
              onClick={() => set("entregaPct")(Math.max(0, +inputs.entregaPct + faltante))}
            >
              Ajustar contra entrega
            </button>
          </div>
        )}
      </Section>

      <Section title="Gastos adicionales">
        <PctRow
          label="Gastos de escrituración"
          value={inputs.escrituraPct}
          onChange={set("escrituraPct")}
          derivedAmount={precio * (inputs.escrituraPct / 100)}
          accent="oklch(0.7 0.04 60)"
        />
        <p className="form__note">
          Incluye notario, ISAI, avalúo y RPP. No forma parte del precio del depa.
        </p>
      </Section>
    </div>
  );
}

function Section({ title, badge, badgeOk, children }) {
  return (
    <div className="form__section">
      <div className="form__section-head">
        <div className="form__section-title">{title}</div>
        {badge !== undefined && (
          <span className={"badge " + (badgeOk ? "badge--ok" : "badge--warn")}>{badge}</span>
        )}
      </div>
      <div className="form__section-body">{children}</div>
    </div>
  );
}

function Results({ r, inputs, faltante }) {
  const { fmtMXN, fmtPct } = window.CalcLogic;

  return (
    <div className="results">
      <div className="results__headline">
        <div className="eyebrow">Informe del esquema de pagos</div>
        <h1 className="results__title">
          <span className="serif">Inversión total de </span>
          <span className="serif accent">{fmtMXN(r.totalAPagar, { compact: true })}</span>
        </h1>
        <p className="results__lead">
          Sobre <strong>{fmtMXN(r.precio)}</strong> de precio del inmueble más
          <strong> {fmtMXN(r.escrituracion)}</strong> de gastos de escrituración
          ({fmtPct(inputs.escrituraPct, 1)}).
          {!r.balanceadoOk && (
            <span className="results__alert">
              {" "}⚠ El esquema {faltante > 0 ? "no llega" : "excede"} el 100% por {fmtPct(Math.abs(faltante), 1)}.
            </span>
          )}
        </p>
      </div>

      {/* KPIs principales */}
      <div className="kpis">
        <KPI big tone="accent"
          label="Enganche"
          value={fmtMXN(r.enganche, { compact: true })}
          sub={`${fmtPct(inputs.engPct, 1)} del precio · al firmar`}
        />
        <KPI big
          label="Mensualidad"
          value={fmtMXN(r.mensualidad, { compact: true })}
          sub={`× ${r.numMensualidades} meses · ${fmtPct(inputs.mensPct, 1)} total`}
        />
        <KPI big
          label="Contra entrega"
          value={fmtMXN(r.contraEntrega, { compact: true })}
          sub={`${fmtPct(inputs.entregaPct, 1)} del precio · al recibir`}
        />
      </div>

      {/* Distribución */}
      <div className="dist">
        <div className="dist__title">Distribución del precio</div>
        <DistributionDonut
          enganche={r.enganche}
          mensualidades={r.totalMensualidades}
          entrega={r.contraEntrega}
          precio={r.precio}
        />
      </div>

      {/* Desglose detallado */}
      <div className="report">
        <div className="report__title">Desglose completo</div>
        <table className="report__table">
          <tbody>
            <tr className="report__group">
              <td colSpan="3">Pagos del inmueble</td>
            </tr>
            <tr>
              <td>Enganche</td>
              <td className="num">{fmtPct(inputs.engPct, 1)}</td>
              <td className="num num--strong">{fmtMXN(r.enganche)}</td>
            </tr>
            <tr>
              <td>
                Mensualidades
                <span className="report__detail"> · {r.numMensualidades} pagos de {fmtMXN(r.mensualidad)}</span>
              </td>
              <td className="num">{fmtPct(inputs.mensPct, 1)}</td>
              <td className="num num--strong">{fmtMXN(r.totalMensualidades)}</td>
            </tr>
            <tr>
              <td>Saldo contra entrega</td>
              <td className="num">{fmtPct(inputs.entregaPct, 1)}</td>
              <td className="num num--strong">{fmtMXN(r.contraEntrega)}</td>
            </tr>
            <tr className="report__subtotal">
              <td>Subtotal precio</td>
              <td className="num">{fmtPct(inputs.engPct + inputs.mensPct + inputs.entregaPct, 1)}</td>
              <td className="num num--strong">{fmtMXN(r.totalSinEscritura)}</td>
            </tr>
            <tr className="report__group">
              <td colSpan="3">Gastos adicionales</td>
            </tr>
            <tr>
              <td>Escrituración</td>
              <td className="num">{fmtPct(inputs.escrituraPct, 1)}</td>
              <td className="num num--strong">{fmtMXN(r.escrituracion)}</td>
            </tr>
            <tr className="report__total">
              <td>Total a desembolsar</td>
              <td></td>
              <td className="num num--strong">{fmtMXN(r.totalAPagar)}</td>
            </tr>
          </tbody>
        </table>
      </div>

      {/* Cronograma */}
      <div className="schedule">
        <div className="schedule__title">Cronograma de pagos</div>
        <div className="schedule__scroll">
          <table className="schedule__table">
            <thead>
              <tr>
                <th>Mes</th>
                <th>Concepto</th>
                <th className="num">% del precio</th>
                <th className="num">Pago</th>
                <th className="num">Acumulado</th>
                <th className="num">% Acum.</th>
              </tr>
            </thead>
            <tbody>
              {r.cronograma.map((p, i) => (
                <tr key={i} className={p.extra ? "is-extra" : (p.mes === 0 || p.mes === r.numMensualidades + 1 ? "is-key" : "")}>
                  <td className="num--mono">{p.mes === 0 ? "Firma" : `M${p.mes}`}</td>
                  <td>
                    <div className="schedule__concept">{p.concepto}</div>
                    <div className="schedule__sub">{p.detalle}</div>
                  </td>
                  <td className="num">{fmtPct(p.porcentaje, 2)}</td>
                  <td className="num num--strong">{fmtMXN(p.pago)}</td>
                  <td className="num">{fmtMXN(p.acumulado)}</td>
                  <td className="num num--muted">{fmtPct(p.porcentajeAcum, 1)}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
}

function PrintFooter({ inputs }) {
  const today = new Date().toLocaleDateString("es-MX", { day: "numeric", month: "long", year: "numeric" });
  return (
    <footer className="print-only print-footer">
      <div>{inputs.nombre} · {inputs.ubicacion}</div>
      <div>Generado el {today} · Calculadora Inmobiliaria</div>
    </footer>
  );
}

function ROIInputs({ inputs, set, setNum }) {
  const { fmtMXN } = window.CalcLogic;
  return (
    <div className="roi-inputs">
      <div className="roi-inputs__head">
        <div>
          <div className="eyebrow">Después de la entrega</div>
          <h2 className="roi-inputs__title">Rentabilidad y plusvalía</h2>
          <p className="roi-inputs__sub">Configura los supuestos de renta vacacional para proyectar el ROI</p>
        </div>
        <label className="toggle">
          <input
            type="checkbox"
            checked={!!inputs.usarCredito}
            onChange={(e) => set("usarCredito")(e.target.checked)}
          />
          <span>Financiar saldo contra entrega</span>
        </label>
      </div>

      <div className="roi-inputs__grid">
        <div className="roi-inputs__col">
          <div className="roi-inputs__col-title">Renta vacacional</div>
          <NumberField label="Tarifa promedio por noche" prefix="$" value={inputs.tarifaProm} onChange={setNum("tarifaProm")} step={100} hint="Promedio entre $1,800 y $3,000 según temporada" />
          <NumberField label="Ocupación" suffix="%" value={inputs.ocupacion} onChange={setNum("ocupacion")} step={1} hint="Promedio CDMX renta corta: 70%" />
          <NumberField label="Comisión plataforma" suffix="% renta" value={inputs.comisionPct} onChange={setNum("comisionPct")} step={1} hint="Airbnb / Booking" />
          <NumberField label="Administración" suffix="% renta" value={inputs.adminPct} onChange={setNum("adminPct")} step={1} hint="Limpieza, blancos, gestión" />
          <NumberField label="Gastos fijos" prefix="$" suffix="/ mes" value={inputs.gastosFijos} onChange={setNum("gastosFijos")} step={100} hint="Mantenimiento, predial, internet" />
        </div>

        <div className="roi-inputs__col">
          <div className="roi-inputs__col-title">Proyección</div>
          <NumberField label="Plusvalía anual" suffix="%" value={inputs.plusvalia} onChange={setNum("plusvalia")} step={0.5} hint="Promedio CDMX: 10%" />
          <NumberField label="Inflación de la renta" suffix="%" value={inputs.inflacionRenta} onChange={setNum("inflacionRenta")} step={0.5} />
          <NumberField label="Horizonte de proyección" suffix="años" value={inputs.horizonte} onChange={setNum("horizonte")} step={1} min={1} />
        </div>

        {inputs.usarCredito && (
          <div className="roi-inputs__col">
            <div className="roi-inputs__col-title">Crédito hipotecario</div>
            <NumberField label="Tasa anual" suffix="%" value={inputs.tasaCredito} onChange={setNum("tasaCredito")} step={0.1} />
            <NumberField label="Plazo" suffix="años" value={inputs.plazoCredito} onChange={setNum("plazoCredito")} step={1} min={1} />
            <p className="form__note">El crédito se calcula sobre el saldo contra entrega ({fmtMXN(inputs.precio * (inputs.entregaPct / 100))}).</p>
          </div>
        )}
      </div>
    </div>
  );
}

function ROIResults({ roi, r, inputs }) {
  const { fmtMXN, fmtPct } = window.CalcLogic;
  const flujoTone = roi.flujoNetoMensual >= 0 ? "positive" : "negative";

  // Cobertura de la hipoteca
  let coberturaCopy = "";
  let coberturaTone = "neutral";
  if (roi.usarCredito) {
    if (roi.cubrePctHip === null) coberturaCopy = "—";
    else if (roi.cubrePctHip >= 100) {
      coberturaCopy = `Tu renta cubre el ${fmtPct(roi.cubrePctHip, 0)} de la hipoteca`;
      coberturaTone = "positive";
    } else {
      coberturaCopy = `Tu renta cubre el ${fmtPct(roi.cubrePctHip, 0)} de la hipoteca`;
      coberturaTone = "warn";
    }
  }

  return (
    <div className="roi-results">
      <div className="roi-results__headline">
        <div className="eyebrow">Proyección a {roi.horizonte} años</div>
        <h2 className="roi-results__title">
          <span className="serif">Tu inversión generaría </span>
          <span className="serif accent">{fmtMXN(roi.gananciaTotal, { compact: true })}</span>
          <span className="serif"> de ganancia total</span>
        </h2>
        <p className="results__lead">
          Con tarifa promedio de <strong>{fmtMXN(roi.tarifaProm)}</strong> por noche al{" "}
          <strong>{fmtPct(roi.ocupacion, 0)}</strong> de ocupación, plusvalía anual de{" "}
          <strong>{fmtPct(roi.plusvalia, 1)}</strong>
          {roi.usarCredito && (<>{" "}y crédito a <strong>{fmtPct(roi.tasaCredito, 1)}</strong> por <strong>{roi.plazoCredito} años</strong></>)}.
        </p>
      </div>

      <div className="kpis kpis--4">
        <KPI big tone={flujoTone}
          label="Lo que te deposita el depa cada mes"
          sublabel="Después de hipoteca, comisiones y gastos"
          value={fmtMXN(roi.flujoNetoMensual)}
          sub={`Anual: ${fmtMXN(roi.flujoNetoAnual)}`}
        />
        <KPI big tone="accent"
          label="Cuánto multiplicas tu dinero usando crédito"
          sublabel="Tu ganancia total en 10 años sobre lo que pusiste tú"
          value={fmtPct(roi.roiTotal, 1)}
          sub={`${fmtPct(roi.roiAnualizado, 1)} anualizado · sobre ${fmtMXN(roi.inversionPropia, { compact: true })}`}
        />
        <KPI big
          label="Cuánto multiplicas tu dinero pagando de contado"
          sublabel="Si no usas crédito del banco"
          value={fmtPct(roi.roiSinApal, 1)}
          sub={`${fmtPct(roi.roiAnualSinApal, 1)} anualizado · sobre ${fmtMXN(roi.inversionSinApal, { compact: true })}`}
        />
        <KPI
          label="En cuánto sube el valor de tu departamento"
          sublabel="Diferencia entre lo que pagas hoy y lo que valdría en 10 años"
          value={fmtMXN(roi.plusvaliaTotal, { compact: true })}
          sub={`Valor del depa: ${fmtMXN(roi.proyeccion[roi.proyeccion.length - 1].valor, { compact: true })}`}
        />
        <KPI
          label={"Lo que es completamente tuyo al año " + roi.horizonte}
          sublabel="Valor del depa menos lo que aún debes al banco"
          value={fmtMXN(roi.equityFinal, { compact: true })}
          sub={`Saldo del crédito: ${fmtMXN(roi.proyeccion[roi.proyeccion.length - 1].saldo, { compact: true })}`}
        />
        <KPI
          label="Qué tan rentable es la propiedad por sí sola"
          sublabel="Comparado con el mercado tradicional (4–6% CDMX)"
          value={fmtPct(roi.capRate, 1)}
          sub="NOI / precio"
        />
        <KPI
          label="Cuánto recuperas en efectivo cada año"
          sublabel="Sobre el dinero que pusiste de tu bolsa"
          value={fmtPct(roi.cashOnCash, 1)}
          sub="Flujo / inversión propia"
        />
      </div>

      {/* Comparativo apalancamiento */}
      <div className="compare">
        <div className="compare__title">Apalancamiento: con crédito vs. sin crédito</div>
        <div className="compare__grid">
          <div className="compare__col compare__col--apal">
            <div className="compare__head">
              <div className="eyebrow">Con crédito (apalancado)</div>
              <div className="compare__roi">{fmtPct(roi.roiTotal, 1)}</div>
              <div className="compare__sub">{fmtPct(roi.roiAnualizado, 1)} anualizado</div>
            </div>
            <dl className="compare__list">
              <div><dt>Pones de tu bolsa</dt><dd>{fmtMXN(roi.inversionPropia)}</dd></div>
              <div><dt>Flujo mensual</dt><dd className={roi.flujoNetoMensual >= 0 ? "is-pos" : "is-neg"}>{fmtMXN(roi.flujoNetoMensual)}</dd></div>
              <div><dt>Ganancia total a {roi.horizonte} años</dt><dd>{fmtMXN(roi.gananciaTotal)}</dd></div>
            </dl>
            <p className="compare__note">El banco aporta el saldo contra entrega. Tu rendimiento se dispara porque controlas un activo grande con poco capital propio — pero el flujo mensual puede ser negativo.</p>
          </div>
          <div className="compare__col">
            <div className="compare__head">
              <div className="eyebrow">Sin crédito (de contado)</div>
              <div className="compare__roi">{fmtPct(roi.roiSinApal, 1)}</div>
              <div className="compare__sub">{fmtPct(roi.roiAnualSinApal, 1)} anualizado</div>
            </div>
            <dl className="compare__list">
              <div><dt>Pones de tu bolsa</dt><dd>{fmtMXN(roi.inversionSinApal)}</dd></div>
              <div><dt>Flujo mensual</dt><dd className="is-pos">{fmtMXN(roi.flujoMensualSinApal)}</dd></div>
              <div><dt>Ganancia total a {roi.horizonte} años</dt><dd>{fmtMXN((roi.proyeccion[roi.proyeccion.length - 1].valor - r.precio) + (roi.flujoMensualSinApal * 12 * roi.horizonte))}</dd></div>
            </dl>
            <p className="compare__note">Pagas todo de contado. El flujo es positivo desde el día 1, pero el ROI es menor porque tu capital invertido es mucho mayor.</p>
          </div>
        </div>
      </div>

      {/* Se paga solo */}
      {roi.usarCredito && (
        <div className={"selfpay selfpay--" + coberturaTone}>
          <div className="selfpay__lead">
            <div className="eyebrow">Tu crédito se paga solo</div>
            <div className="selfpay__title">{coberturaCopy}</div>
          </div>
          <div className="selfpay__bars">
            <div className="bar">
              <div className="bar__label">Renta neta</div>
              <div className="bar__track">
                <div className="bar__fill bar__fill--rent" style={{ width: Math.min(100, (roi.ingresoNetoOp / Math.max(roi.ingresoNetoOp, roi.pagoMensualHip)) * 100) + "%" }}></div>
              </div>
              <div className="bar__amount">{fmtMXN(roi.ingresoNetoOp)}</div>
            </div>
            <div className="bar">
              <div className="bar__label">Pago hipoteca</div>
              <div className="bar__track">
                <div className="bar__fill bar__fill--hip" style={{ width: Math.min(100, (roi.pagoMensualHip / Math.max(roi.ingresoNetoOp, roi.pagoMensualHip)) * 100) + "%" }}></div>
              </div>
              <div className="bar__amount">{fmtMXN(roi.pagoMensualHip)}</div>
            </div>
          </div>
        </div>
      )}

      {/* Desglose mensual operativo */}
      <div className="report">
        <div className="report__title">Flujo mensual de operación</div>
        <table className="report__table">
          <tbody>
            <tr>
              <td>Ingreso bruto · {fmtNum(roi.noches, 1)} noches × {fmtMXN(roi.tarifaProm)}</td>
              <td className="num">100%</td>
              <td className="num num--strong">{fmtMXN(roi.ingresoBruto)}</td>
            </tr>
            <tr>
              <td>Comisión plataforma</td>
              <td className="num">−{fmtPct(inputs.comisionPct, 0)}</td>
              <td className="num num--muted">−{fmtMXN(roi.comision)}</td>
            </tr>
            <tr>
              <td>Administración</td>
              <td className="num">−{fmtPct(inputs.adminPct, 0)}</td>
              <td className="num num--muted">−{fmtMXN(roi.admin)}</td>
            </tr>
            <tr>
              <td>Gastos fijos</td>
              <td className="num"></td>
              <td className="num num--muted">−{fmtMXN(roi.gastosFijos)}</td>
            </tr>
            <tr className="report__subtotal">
              <td>Renta neta operativa</td>
              <td className="num"></td>
              <td className="num num--strong">{fmtMXN(roi.ingresoNetoOp)}</td>
            </tr>
            {roi.usarCredito && (
              <tr>
                <td>Pago hipoteca · {fmtPct(roi.tasaCredito, 1)} × {roi.plazoCredito} años</td>
                <td className="num"></td>
                <td className="num num--muted">−{fmtMXN(roi.pagoMensualHip)}</td>
              </tr>
            )}
            <tr className="report__total">
              <td>Flujo neto al inversionista</td>
              <td></td>
              <td className="num num--strong">{fmtMXN(roi.flujoNetoMensual)}</td>
            </tr>
          </tbody>
        </table>
      </div>

      {/* Gráfica de proyección */}
      <ROIChart proyeccion={roi.proyeccion} precio={r.precio} inversion={roi.inversionPropia} />

      {/* Tabla año a año */}
      <div className="schedule">
        <div className="schedule__title">Proyección año a año</div>
        <div className="schedule__scroll">
          <table className="schedule__table">
            <thead>
              <tr>
                <th>Año</th>
                <th className="num">Ingreso operativo</th>
                {roi.usarCredito && <th className="num">Pago hipoteca</th>}
                <th className="num">Flujo del año</th>
                <th className="num">Flujo acumulado</th>
                <th className="num">Valor del depa</th>
                {roi.usarCredito && <th className="num">Saldo crédito</th>}
                <th className="num">Equity</th>
              </tr>
            </thead>
            <tbody>
              {roi.proyeccion.map((p) => (
                <tr key={p.anio}>
                  <td className="num--mono">Año {p.anio}</td>
                  <td className="num">{fmtMXN(p.ingresoOp)}</td>
                  {roi.usarCredito && <td className="num num--muted">−{fmtMXN(p.pagoHip)}</td>}
                  <td className={"num " + (p.flujoNeto >= 0 ? "num--strong" : "num--neg")}>{fmtMXN(p.flujoNeto)}</td>
                  <td className="num num--muted">{fmtMXN(p.flujoAcumulado)}</td>
                  <td className="num">{fmtMXN(p.valor)}</td>
                  {roi.usarCredito && <td className="num num--muted">{fmtMXN(p.saldo)}</td>}
                  <td className="num num--strong">{fmtMXN(p.equity)}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
}

function ROIChart({ proyeccion, precio, inversion }) {
  const { fmtMXN } = window.CalcLogic;
  const w = 900, h = 320, padL = 80, padR = 16, padT = 24, padB = 36;
  const data = [{ anio: 0, valor: precio, equity: precio - (proyeccion[0]?.saldo > 0 ? (precio * 0.6) : 0), flujoAcumulado: -inversion }, ...proyeccion];
  // Simplificar: usar proyeccion sin el punto 0 sintético
  const d = proyeccion;
  const allVals = d.flatMap(p => [p.valor, p.equity, p.flujoAcumulado]);
  const min = Math.min(0, ...allVals);
  const max = Math.max(...allVals);
  const range = max - min || 1;

  const xFor = (i) => padL + (i / Math.max(1, d.length - 1)) * (w - padL - padR);
  const yFor = (v) => padT + (1 - (v - min) / range) * (h - padT - padB);
  const pathFor = (key) => d.map((p, i) => `${i === 0 ? "M" : "L"} ${xFor(i)} ${yFor(p[key])}`).join(" ");

  const ticks = 5;
  const tickValues = Array.from({ length: ticks + 1 }, (_, i) => min + (range * i) / ticks);

  return (
    <div className="chart">
      <div className="chart__head">
        <div>
          <div className="chart__title">Cómo crece tu inversión</div>
          <div className="chart__sub">Valor del depa, equity y flujo acumulado</div>
        </div>
        <div className="chart__legend">
          <span className="lg lg--value"><i></i>Valor del depa</span>
          <span className="lg" style={{ color: 'var(--color-enganche)' }}>
            <i style={{ background: 'var(--color-enganche)' }}></i>Equity
          </span>
          <span className="lg" style={{ color: 'var(--color-mensual)' }}>
            <i style={{ background: 'var(--color-mensual)' }}></i>Flujo acumulado
          </span>
        </div>
      </div>
      <svg viewBox={`0 0 ${w} ${h}`} className="chart__svg">
        {tickValues.map((v, i) => (
          <g key={i}>
            <line x1={padL} x2={w - padR} y1={yFor(v)} y2={yFor(v)} className="chart__grid" />
            <text x={padL - 8} y={yFor(v) + 4} className="chart__tick" textAnchor="end">
              {fmtMXN(v, { compact: true })}
            </text>
          </g>
        ))}
        {min < 0 && <line x1={padL} x2={w - padR} y1={yFor(0)} y2={yFor(0)} className="chart__zero" />}
        {d.map((p, i) => (
          (i === 0 || i === d.length - 1 || i % Math.ceil(d.length / 6) === 0) && (
            <text key={i} x={xFor(i)} y={h - padB + 18} className="chart__tick" textAnchor="middle">Año {p.anio}</text>
          )
        ))}
        <path d={pathFor("valor")} className="chart__line chart__line--value" />
        <path d={pathFor("equity")} className="chart__line chart__line--equity" />
        <path d={pathFor("flujoAcumulado")} className="chart__line chart__line--flow" />
      </svg>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);

