/* global React */
// §5.3 WACCPhaseTimeline — Lab principal de M02.E03 y M04.E07
// Construye WACC dinámico por 3 fases + comparación contra constante

const { useState, useMemo } = React;

const ARCHETYPES = {
  stable_quality: {
    id: "stable_quality",
    label: "Coca_Cola_sim",
    sublabel: "stable_quality",
    is_bank: false,
    phases: [
      { name: "growth",     years: [1, 5],   beta: 1.05, de_ratio: 0.20, kd: 4.2, tax: 0.22 },
      { name: "maturation", years: [6, 10],  beta: 1.00, de_ratio: 0.22, kd: 4.0, tax: 0.22 },
      { name: "terminal",   years: [11, 30], beta: 1.00, de_ratio: 0.22, kd: 4.0, tax: 0.22 },
    ],
    constant_wacc: 7.0,
    ev_constant: 280,
  },
  growth_high_beta: {
    id: "growth_high_beta",
    label: "Tesla_sim",
    sublabel: "growth_high_beta",
    is_bank: false,
    phases: [
      { name: "growth",     years: [1, 5],   beta: 1.85, de_ratio: 0.10, kd: 5.5, tax: 0.22 },
      { name: "maturation", years: [6, 10],  beta: 1.30, de_ratio: 0.18, kd: 4.8, tax: 0.22 },
      { name: "terminal",   years: [11, 30], beta: 1.00, de_ratio: 0.25, kd: 4.2, tax: 0.22 },
    ],
    constant_wacc: 11.4,
    ev_constant: 540,
  },
  utility_regulated: {
    id: "utility_regulated",
    label: "Iberdrola_sim",
    sublabel: "utility_regulated",
    is_bank: false,
    phases: [
      { name: "growth",     years: [1, 5],   beta: 0.80, de_ratio: 0.55, kd: 3.6, tax: 0.25 },
      { name: "maturation", years: [6, 10],  beta: 0.90, de_ratio: 0.50, kd: 3.8, tax: 0.25 },
      { name: "terminal",   years: [11, 30], beta: 1.00, de_ratio: 0.45, kd: 4.0, tax: 0.25 },
    ],
    constant_wacc: 5.8,
    ev_constant: 410,
  },
  bank_special: {
    id: "bank_special",
    label: "BBVA_sim",
    sublabel: "bank_special",
    is_bank: true,
    phases: [
      { name: "growth",     years: [1, 5],   beta: 1.35, de_ratio: null, kd: null, tax: 0.30 },
      { name: "maturation", years: [6, 10],  beta: 1.20, de_ratio: null, kd: null, tax: 0.30 },
      { name: "terminal",   years: [11, 30], beta: 1.00, de_ratio: null, kd: null, tax: 0.30 },
    ],
    constant_wacc: null,
    ev_constant: null,
  },
  growth_tech_premium: {
    id: "growth_tech_premium",
    label: "ASML_sim",
    sublabel: "growth_tech_premium",
    is_bank: false,
    phases: [
      { name: "growth",     years: [1, 5],   beta: 1.45, de_ratio: 0.08, kd: 4.8, tax: 0.22 },
      { name: "maturation", years: [6, 10],  beta: 1.20, de_ratio: 0.15, kd: 4.4, tax: 0.22 },
      { name: "terminal",   years: [11, 30], beta: 1.00, de_ratio: 0.22, kd: 4.2, tax: 0.22 },
    ],
    constant_wacc: 9.1,
    ev_constant: 320,
  },
};

const RF = 4.0;
const ERP = 5.5;

function computeKeBeta(beta) {
  return RF + beta * ERP;
}

function computeWACCPhase(phase, betaOverride) {
  if (phase.kd == null) return null; // bank
  const beta = betaOverride ?? phase.beta;
  const ke = computeKeBeta(beta);
  const de = phase.de_ratio;
  const we = 1 / (1 + de);
  const wd = de / (1 + de);
  return ke * we + phase.kd * (1 - phase.tax) * wd;
}

// Quick mock DCF using flat CF growing 3%/y, terminal growth 2%
function valuationEV(phases, betaTerminalOverride) {
  if (phases[0].kd == null) return null;
  const cf0 = 100; // arbitrary scale
  let pv = 0;
  let discount = 1;
  for (let year = 1; year <= 30; year++) {
    const phase = phases.find(p => year >= p.years[0] && year <= p.years[1]);
    const betaThisYear = (phase.name === "terminal" && betaTerminalOverride != null) ? betaTerminalOverride : phase.beta;
    const wacc = computeWACCPhase({ ...phase, beta: betaThisYear }) / 100;
    discount *= 1 + wacc;
    const cf = cf0 * Math.pow(1.03, Math.min(year - 1, 9)) * Math.pow(1.02, Math.max(0, year - 10));
    pv += cf / discount;
  }
  // Terminal value beyond year 30
  const terminalPhase = phases[2];
  const finalBeta = betaTerminalOverride ?? terminalPhase.beta;
  const terminalWacc = computeWACCPhase({ ...terminalPhase, beta: finalBeta }) / 100;
  const cf30 = cf0 * Math.pow(1.03, 9) * Math.pow(1.02, 20);
  const tv = cf30 * 1.02 / (terminalWacc - 0.02);
  pv += tv / discount;
  return pv;
}

function valuationEVConstant(wacc) {
  if (wacc == null) return null;
  const cf0 = 100;
  let pv = 0;
  let discount = 1;
  const w = wacc / 100;
  for (let year = 1; year <= 30; year++) {
    discount *= 1 + w;
    const cf = cf0 * Math.pow(1.03, Math.min(year - 1, 9)) * Math.pow(1.02, Math.max(0, year - 10));
    pv += cf / discount;
  }
  const cf30 = cf0 * Math.pow(1.03, 9) * Math.pow(1.02, 20);
  const tv = cf30 * 1.02 / (w - 0.02);
  pv += tv / discount;
  return pv;
}

// Beta convergence curve to plot
function betaAtYear(phases, year, betaTerminalOverride) {
  // smooth between phase midpoints
  const p1 = phases[0]; // growth
  const p2 = phases[1]; // maturation
  const p3 = phases[2]; // terminal
  const b3 = betaTerminalOverride ?? p3.beta;
  if (year <= 3) return p1.beta;
  if (year <= 7) {
    const t = (year - 3) / 4;
    return p1.beta + (p2.beta - p1.beta) * t;
  }
  if (year <= 11) {
    const t = (year - 7) / 4;
    return p2.beta + (b3 - p2.beta) * t;
  }
  return b3;
}

function WACCPhaseTimeline() {
  const [activeId, setActiveId] = useState("stable_quality");
  const [betaTerminal, setBetaTerminal] = useState(null); // null => use archetype default
  const [showConstant, setShowConstant] = useState(true);
  const archetype = ARCHETYPES[activeId];
  const isBank = archetype.is_bank;

  const betaT = betaTerminal ?? archetype.phases[2].beta;

  const phases = archetype.phases;

  const ev_dynamic = isBank ? null : valuationEV(phases, betaT);
  const ev_constant = isBank ? null : valuationEVConstant(archetype.constant_wacc);
  const delta_ev = (ev_dynamic && ev_constant) ? ev_dynamic - ev_constant : null;
  const delta_ev_pct = (delta_ev != null && ev_constant) ? (delta_ev / ev_constant) * 100 : null;
  const immaterial = delta_ev_pct != null && Math.abs(delta_ev_pct) < 5;

  // SVG dimensions
  const W = 700, H = 200;
  const yearToX = y => 20 + ((y - 1) / 29) * (W - 40);
  const betaToY = b => H - 20 - ((b - 0.7) / (2.0 - 0.7)) * (H - 50);

  return (
    <div className="fz-slot">
      <div className="fz-slot-header">
        <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
          <span className="fz-eyebrow">S3 · LAB · CALC+CASE</span>
          <span style={{ color: "var(--border-strong)" }}>·</span>
          <h2>WACC Phase Timeline</h2>
        </div>
        <div style={{ display: "flex", gap: 8 }}>
          <span className="fz-chip">M02 · E03</span>
          <span className="fz-chip">3 fases · 30 años</span>
        </div>
      </div>

      <div className="fz-scroll" style={{ flex: 1, overflow: "auto", padding: 24, display: "flex", flexDirection: "column", gap: 18 }}>
        {/* Archetype selector */}
        <div>
          <div className="fz-label" style={{ marginBottom: 8 }}>5 arquetipos · dataset_wacc_5_companies</div>
          <div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
            {Object.values(ARCHETYPES).map(a => (
              <button
                key={a.id}
                onClick={() => { setActiveId(a.id); setBetaTerminal(null); }}
                style={{
                  padding: "8px 12px",
                  background: activeId === a.id ? "var(--surface-3)" : "var(--surface-1)",
                  border: `1px solid ${activeId === a.id ? "var(--signal-driver)" : "var(--border)"}`,
                  borderRadius: 8,
                  color: activeId === a.id ? "var(--fg)" : "var(--fg-muted)",
                  cursor: "pointer",
                  fontSize: 12,
                  fontFamily: "var(--font-mono)",
                  textAlign: "left",
                  minWidth: 130,
                }}
              >
                <div style={{ color: activeId === a.id ? "var(--signal-driver)" : "var(--fg)", fontWeight: 500 }}>{a.label}</div>
                <div style={{ fontSize: 10, color: "var(--fg-faint)", marginTop: 2 }}>{a.sublabel}</div>
              </button>
            ))}
          </div>
        </div>

        {/* Bank special case */}
        {isBank && (
          <div className="fz-banner fz-banner-amber">
            <span style={{ flexShrink: 0, marginTop: 2 }}>●</span>
            <div>
              <div style={{ fontWeight: 500, color: "var(--fg)", marginBottom: 4 }}>Bank-special · WACC clásico no aplica</div>
              Bancos no usan estructura D/E como concepto de financiación (D es producto regulado).
              Mostramos <span className="fz-mono">Ke directo</span> en lugar de WACC. La curva β sigue informando coste de capital del equity.
            </div>
          </div>
        )}

        {/* Timeline chart */}
        <div className="fz-card fz-card-pad">
          <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 10 }}>
            <div className="fz-label">Curva de convergencia β · 30 años</div>
            <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
              <div style={{ display: "flex", gap: 12, fontSize: 11, color: "var(--fg-muted)" }}>
                <span><span style={{ display: "inline-block", width: 8, height: 2, background: "var(--signal-loading)", verticalAlign: "middle", marginRight: 4 }}></span>β dinámico</span>
                <span style={{ width: 1, background: "var(--border)" }}></span>
                {!isBank && (
                  <label style={{ display: "inline-flex", alignItems: "center", gap: 6, cursor: "pointer" }}>
                    <input type="checkbox" checked={showConstant} onChange={e => setShowConstant(e.target.checked)} style={{ accentColor: "var(--signal-hypothesis)" }} />
                    Comparar con WACC constante
                  </label>
                )}
              </div>
            </div>
          </div>

          <svg viewBox={`0 0 ${W} ${H}`} width="100%" preserveAspectRatio="xMidYMid meet" style={{ display: "block" }}>
            {/* Phase bands */}
            {phases.map((p, i) => {
              const x1 = yearToX(p.years[0]);
              const x2 = yearToX(p.years[1]);
              const bandColors = ["rgba(107,163,255,0.08)", "rgba(156,180,216,0.06)", "rgba(91,198,143,0.05)"];
              return (
                <g key={p.name}>
                  <rect x={x1} y={10} width={x2 - x1} height={H - 30} fill={bandColors[i]} />
                  <text x={x1 + 6} y={26} fill="var(--fg-faint)" fontSize="10" fontFamily="var(--font-mono)" style={{ textTransform: "uppercase", letterSpacing: "0.05em" }}>
                    {p.name} · y{p.years[0]}–{p.years[1] === 30 ? "30+" : p.years[1]}
                  </text>
                </g>
              );
            })}

            {/* Horizontal gridlines */}
            {[0.8, 1.0, 1.2, 1.5, 1.8].map(b => (
              <g key={b}>
                <line x1={20} x2={W - 20} y1={betaToY(b)} y2={betaToY(b)} stroke="var(--border)" strokeDasharray="2,3" />
                <text x={10} y={betaToY(b) + 3} fill="var(--fg-faint)" fontSize="9" fontFamily="var(--font-mono)">{b.toFixed(1)}</text>
              </g>
            ))}

            {/* Beta curve */}
            <path
              d={Array.from({ length: 30 }, (_, i) => i + 1).map((y, i) => {
                const x = yearToX(y);
                const b = betaToY(betaAtYear(phases, y, betaT));
                return `${i === 0 ? "M" : "L"}${x.toFixed(1)},${b.toFixed(1)}`;
              }).join(" ")}
              stroke="var(--signal-loading)"
              strokeWidth="2"
              fill="none"
            />
            {/* Asymptote target */}
            <line
              x1={yearToX(11)} x2={W - 20}
              y1={betaToY(betaT)} y2={betaToY(betaT)}
              stroke="var(--signal-mastery)"
              strokeWidth="1"
              strokeDasharray="3,4"
              opacity="0.6"
            />
            <text x={W - 22} y={betaToY(betaT) - 6} fill="var(--signal-mastery)" fontSize="10" fontFamily="var(--font-mono)" textAnchor="end">
              β terminal = {betaT.toFixed(2)}
            </text>
          </svg>
        </div>

        {/* Phase cards */}
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 12 }}>
          {phases.map((p, i) => {
            const isTerminal = p.name === "terminal";
            const b = isTerminal ? betaT : p.beta;
            const ke = computeKeBeta(b);
            const wacc = computeWACCPhase({ ...p, beta: b });
            return (
              <div key={p.name} className="fz-card fz-card-pad" style={{
                borderColor: isTerminal ? "rgba(91,198,143,0.3)" : "var(--border)",
              }}>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 8 }}>
                  <span style={{ fontSize: 11, color: "var(--fg-faint)", textTransform: "uppercase", letterSpacing: "0.05em" }}>
                    Fase {i + 1}
                  </span>
                  <span className="fz-mono" style={{ fontSize: 10, color: "var(--fg-faint)" }}>
                    y{p.years[0]}–{p.years[1] === 30 ? "∞" : p.years[1]}
                  </span>
                </div>
                <div style={{ fontSize: 14, color: "var(--fg)", textTransform: "capitalize", marginBottom: 12 }}>
                  {p.name}
                </div>
                <div style={{ display: "grid", gridTemplateColumns: "1fr auto", gap: "4px 12px", fontFamily: "var(--font-mono)", fontSize: 11 }}>
                  <span style={{ color: "var(--fg-faint)" }}>β</span>
                  <span style={{ color: "var(--signal-loading)" }}>{b.toFixed(2)}</span>
                  {!isBank && <>
                    <span style={{ color: "var(--fg-faint)" }}>D/(D+E)</span>
                    <span style={{ color: "var(--signal-driver)" }}>{(p.de_ratio / (1 + p.de_ratio) * 100).toFixed(0)}%</span>
                    <span style={{ color: "var(--fg-faint)" }}>K_d</span>
                    <span style={{ color: "var(--signal-driver)" }}>{p.kd.toFixed(1)}%</span>
                  </>}
                  <span style={{ color: "var(--fg-faint)" }}>tax</span>
                  <span style={{ color: "var(--signal-driver)" }}>{(p.tax * 100).toFixed(0)}%</span>
                  <span style={{ color: "var(--fg-faint)" }}>Ke</span>
                  <span style={{ color: "var(--signal-loading)" }}>{ke.toFixed(1)}%</span>
                </div>
                <div style={{ marginTop: 12, paddingTop: 12, borderTop: "1px solid var(--border)" }}>
                  <div className="fz-label" style={{ marginBottom: 4 }}>{isBank ? "Ke" : "WACC"}</div>
                  <div className="fz-num" style={{ fontSize: 22, color: "var(--signal-loading)", fontWeight: 500 }}>
                    {wacc != null ? wacc.toFixed(2) : ke.toFixed(2)}%
                  </div>
                </div>
              </div>
            );
          })}
        </div>

        {/* Sensitivity slider */}
        {!isBank && (
          <div className="fz-card fz-card-pad">
            <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 8 }}>
              <div className="fz-label">Sensibilidad · β terminal</div>
              <span className="fz-mono" style={{ fontSize: 11, color: "var(--signal-loading)" }}>
                β = {betaT.toFixed(2)}
              </span>
            </div>
            <input
              type="range"
              min={0.8}
              max={1.2}
              step={0.01}
              value={betaT}
              onChange={e => setBetaTerminal(parseFloat(e.target.value))}
              style={{ width: "100%", accentColor: "var(--signal-loading)" }}
            />
            <div style={{ display: "flex", justifyContent: "space-between", marginTop: 2, fontSize: 10, fontFamily: "var(--font-mono)", color: "var(--fg-faint)" }}>
              <span>0.80</span><span>1.00</span><span>1.20</span>
            </div>
          </div>
        )}

        {/* Δ EV card */}
        {!isBank && showConstant && (
          <div className="fz-card fz-card-pad" style={{ background: immaterial ? "rgba(229,184,115,0.04)" : "var(--surface-1)" }}>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 20 }}>
              <div>
                <div className="fz-label" style={{ marginBottom: 6 }}>EV · WACC dinámico</div>
                <div className="fz-num fz-num-big fz-num-loading">€{ev_dynamic.toFixed(0)}m</div>
              </div>
              <div>
                <div className="fz-label" style={{ marginBottom: 6 }}>EV · WACC constante</div>
                <div className="fz-num fz-num-big" style={{ color: "var(--fg-muted)" }}>€{ev_constant.toFixed(0)}m</div>
                <div style={{ fontSize: 10, color: "var(--fg-faint)", fontFamily: "var(--font-mono)", marginTop: 2 }}>
                  WACC = {archetype.constant_wacc}%
                </div>
              </div>
              <div>
                <div className="fz-label" style={{ marginBottom: 6 }}>Δ EV</div>
                <div className="fz-num fz-num-big" style={{ color: immaterial ? "var(--signal-hypothesis)" : "var(--signal-mastery)" }}>
                  {delta_ev_pct >= 0 ? "+" : ""}{delta_ev_pct.toFixed(1)}%
                </div>
                <div style={{ fontSize: 10, color: "var(--fg-faint)", fontFamily: "var(--font-mono)", marginTop: 2 }}>
                  €{delta_ev >= 0 ? "+" : ""}{delta_ev.toFixed(0)}m
                </div>
              </div>
            </div>
            {immaterial && (
              <div className="fz-banner fz-banner-amber" style={{ marginTop: 14 }}>
                <span style={{ flexShrink: 0, marginTop: 2 }}>●</span>
                <div>
                  <div style={{ fontWeight: 500, color: "var(--fg)", marginBottom: 2 }}>
                    Diferencia inmaterial ({Math.abs(delta_ev_pct).toFixed(1)}%)
                  </div>
                  Podrías justificar WACC constante para este caso. La complejidad adicional del modelo dinámico no se traduce en información de valoración.
                </div>
              </div>
            )}
          </div>
        )}

        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", paddingTop: 8, borderTop: "1px solid var(--border)" }}>
          <div style={{ fontSize: 11, color: "var(--fg-faint)", lineHeight: 1.5, maxWidth: 540 }}>
            Regla del Tutor · M02.E03 — <em style={{ color: "var(--fg-muted)" }}>"WACC dinámico añade rigor pero también complejidad. Si Δ EV &lt; 5%, justifica WACC constante."</em>
          </div>
          <button className="fz-btn fz-btn-primary">guardar y avanzar a S4</button>
        </div>
      </div>
    </div>
  );
}

window.WACCPhaseTimeline = WACCPhaseTimeline;
