// Regret Simulator · the differentiator.
// Visualizes the round-trip damage of riding peaks all the way back down.

function Regret() {
  const { state, prices } = useStore();
  const cur = state.settings.currency;
  const portfolio = React.useMemo(() => computePortfolio(state, prices), [state, prices]);
  const peak = React.useMemo(() => peakValuation(state), [state]);

  const [crashPct, setCrashPct] = React.useState(70);
  const [exitedPct, setExitedPct] = React.useState(0); // how much was sold at peak

  // The number that hurts: peak portfolio if you'd held everything to the top,
  // and what's left after a crash, vs what you actually have today.
  const crashedValue = peak * (1 - crashPct / 100);
  const lostFromPeak = peak - crashedValue;

  // Mixed strategy: what if you'd sold `exitedPct` at peak (taxed) and rode the rest down
  const sold = peak * (exitedPct / 100);
  const taxedNet = sold * (1 - state.settings.taxRate);
  const rideValue = (peak - sold) * (1 - crashPct / 100);
  const planTotal = taxedNet + rideValue;

  if (portfolio.rows.length === 0) {
    return (
      <div className="exos-page">
        <PageHeadRegret />
        <Card><EmptyState title="Nothing to simulate yet" sub="Add holdings to see the regret math." /></Card>
      </div>
    );
  }

  return (
    <div className="exos-page">
      <PageHeadRegret />

      {/* Cinematic chart */}
      <Card className="exos-regret-hero" padding="p-none">
        <div className="exos-regret-hero-pad">
          <div className="exos-regret-kicker">
            <Pill tone="loss" dot>SIMULATION</Pill>
            <span className="serif">The round trip nobody plans for.</span>
          </div>
          <h2 className="exos-regret-title">
            Imagine your portfolio peaks at <span className="mono accent">{fmtCurrency(peak, cur, { compact: true })}</span>.
            <br/>You hold. Then markets correct {crashPct}%.
          </h2>
        </div>

        <CrashChart peak={peak} crashPct={crashPct} currency={cur} taxRate={state.settings.taxRate} exitedPct={exitedPct} />

        <div className="exos-regret-figures">
          <div className="exos-regret-figure">
            <div className="exos-label">Peak portfolio</div>
            <div className="mono" style={{ fontSize: 26, fontWeight: 500 }}>{fmtCurrency(peak, cur, { compact: true })}</div>
          </div>
          <div className="exos-regret-arrow">→</div>
          <div className="exos-regret-figure">
            <div className="exos-label">After {crashPct}% crash</div>
            <div className="mono" style={{ fontSize: 26, fontWeight: 500, color: "var(--loss)" }}>{fmtCurrency(crashedValue, cur, { compact: true })}</div>
          </div>
          <div className="exos-regret-arrow loss">−</div>
          <div className="exos-regret-figure highlight">
            <div className="exos-label" style={{ color: "var(--loss)" }}>Unrealized wealth lost</div>
            <div className="mono" style={{ fontSize: 32, fontWeight: 500, color: "var(--loss)", letterSpacing: "-0.02em" }}>{fmtCurrency(lostFromPeak, cur, { compact: true })}</div>
          </div>
        </div>
      </Card>

      {/* Controls */}
      <div className="exos-grid cols-2" style={{ marginBottom: 14 }}>
        <Card>
          <div className="exos-label">Crash severity</div>
          <div style={{ display: "flex", alignItems: "baseline", gap: 8, margin: "8px 0 14px" }}>
            <span className="mono" style={{ fontSize: 32, fontWeight: 500, color: "var(--loss)", letterSpacing: "-0.02em" }}>−{crashPct}%</span>
            <span style={{ color: "var(--text-mute)", fontSize: 13 }}>from peak</span>
          </div>
          <Slider value={crashPct} onChange={setCrashPct} min={10} max={90} format={v => `−${v}%`} />
          <div style={{ display: "flex", gap: 6, marginTop: 12, flexWrap: "wrap" }}>
            {[30, 50, 70, 85].map(c => (
              <Button key={c} size="sm" variant={crashPct === c ? "primary" : "secondary"} onClick={() => setCrashPct(c)}>{c}%</Button>
            ))}
          </div>
          <div style={{ marginTop: 14, fontSize: 12, color: "var(--text-mute)" }}>
            {crashPct >= 80 && "Full cycle reversal. Brutal but historically common in crypto."}
            {crashPct >= 50 && crashPct < 80 && "A typical bear-market drawdown. Hurts. Recoverable."}
            {crashPct < 50 && "A healthy correction. Routine in any cycle."}
          </div>
        </Card>

        <Card>
          <div className="exos-label">What if you'd sold some at peak?</div>
          <div style={{ display: "flex", alignItems: "baseline", gap: 8, margin: "8px 0 14px" }}>
            <span className="mono" style={{ fontSize: 32, fontWeight: 500, color: "var(--accent)", letterSpacing: "-0.02em" }}>{exitedPct}%</span>
            <span style={{ color: "var(--text-mute)", fontSize: 13 }}>locked in at peak</span>
          </div>
          <Slider value={exitedPct} onChange={setExitedPct} min={0} max={100} format={v => v + "%"} />
          <div style={{ marginTop: 14 }} className="exos-mix-summary">
            <div className="exos-mix-row">
              <span className="exos-label">Cash locked (net of tax)</span>
              <span className="mono">{fmtCurrency(taxedNet, cur, { compact: true })}</span>
            </div>
            <div className="exos-mix-row">
              <span className="exos-label">Remainder after crash</span>
              <span className="mono">{fmtCurrency(rideValue, cur, { compact: true })}</span>
            </div>
            <div className="exos-mix-row total">
              <span>Total after crash</span>
              <span className="mono" style={{ color: planTotal >= portfolio.total ? "var(--gain)" : "var(--loss)" }}>{fmtCurrency(planTotal, cur, { compact: true })}</span>
            </div>
          </div>
        </Card>
      </div>

      {/* Per-coin breakdown */}
      <Card>
        <SectionHeader kicker="PER COIN" title="Where the damage lands" />
        <div className="exos-table-wrap">
          <table className="exos-table">
            <thead>
              <tr>
                <th>Coin</th>
                <th className="right">Peak value</th>
                <th className="right">After {crashPct}% crash</th>
                <th className="right">Wealth lost</th>
                <th className="right">Plan covers</th>
              </tr>
            </thead>
            <tbody>
              {portfolio.rows.map(r => {
                const peakP = state.scenarios.bullPeaks[r.coinId] ?? r.price * 2;
                const peakV = r.amount * peakP;
                const after = peakV * (1 - crashPct / 100);
                const lost = peakV - after;
                const ladder = state.ladders[r.coinId];
                const sumPct = ladder?.targets?.reduce((a,t)=>a+t.sellPercent,0) ?? 0;
                return (
                  <tr key={r.id}>
                    <td>
                      <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                        <CoinIcon coinId={r.coinId} size={26} />
                        <span style={{ fontWeight: 500 }}>{r.meta.symbol}</span>
                      </div>
                    </td>
                    <td className="right mono">{fmtCurrency(peakV, cur, { compact: true })}</td>
                    <td className="right mono" style={{ color: "var(--loss)" }}>{fmtCurrency(after, cur, { compact: true })}</td>
                    <td className="right mono" style={{ color: "var(--loss)" }}>−{fmtCurrency(lost, cur, { compact: true })}</td>
                    <td className="right">
                      <div style={{ display: "flex", alignItems: "center", gap: 8, justifyContent: "flex-end" }}>
                        <div style={{ width: 60, height: 4, background: "var(--line)", borderRadius: 2, overflow: "hidden" }}>
                          <div style={{ height: "100%", width: `${Math.min(100, sumPct)}%`, background: sumPct >= 50 ? "var(--gain)" : sumPct >= 25 ? "var(--warn)" : "var(--loss)" }} />
                        </div>
                        <span className="mono" style={{ minWidth: 36 }}>{sumPct}%</span>
                      </div>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
        <div className="exos-regret-quote serif">
          “The pain of giving back gains is more than twice the joy of making them. Plan for the exit before you need it.”
        </div>
      </Card>
    </div>
  );
}

function PageHeadRegret() {
  return (
    <div className="exos-page-head">
      <div>
        <div className="exos-kicker mono">REGRET SIMULATOR</div>
        <h1 className="exos-h1">The honest mirror.</h1>
        <div className="exos-page-head-sub">
          Bull markets feel infinite. They aren't. This is what happens if you ride the peak all the way back down · and what an exit plan would have saved you.
        </div>
      </div>
    </div>
  );
}

// ---------- Crash chart
function CrashChart({ peak, crashPct, currency, taxRate, exitedPct }) {
  // Build a stylized timeline: accumulate → run-up → peak → crash → recover
  // Reactive to crashPct and peak.
  const W = 920, H = 280;
  const pad = { l: 50, r: 30, t: 30, b: 36 };
  const start = peak * 0.18; // initial value
  const trough = peak * (1 - crashPct / 100);
  const recovery = peak * (1 - crashPct / 100) * 1.4; // some recovery

  const path = [
    { x: 0,    y: start },
    { x: 0.15, y: peak * 0.32 },
    { x: 0.32, y: peak * 0.55 },
    { x: 0.46, y: peak * 0.78 },
    { x: 0.55, y: peak * 0.92 },
    { x: 0.62, y: peak },          // peak
    { x: 0.68, y: peak * 0.88 },
    { x: 0.76, y: peak * 0.6 },
    { x: 0.86, y: trough * 1.1 },
    { x: 0.92, y: trough },
    { x: 1,    y: recovery },
  ];

  const yMin = 0;
  const yMax = peak * 1.05;
  const innerW = W - pad.l - pad.r;
  const innerH = H - pad.t - pad.b;
  const xToPx = x => pad.l + x * innerW;
  const yToPx = y => pad.t + (1 - (y - yMin) / (yMax - yMin)) * innerH;

  const linePath = path.map((p, i) => `${i === 0 ? "M" : "L"} ${xToPx(p.x)} ${yToPx(p.y)}`).join(" ");
  const fillPath = linePath + ` L ${xToPx(1)} ${yToPx(0)} L ${xToPx(0)} ${yToPx(0)} Z`;

  // The exit-plan alternate: a flat line from peak onward at exitedPct * peak (locked in)
  const exitLockedValue = peak * (exitedPct / 100) * (1 - taxRate);
  const exitRideValue = peak * (1 - exitedPct / 100);
  // The alternate path peaks then declines less because some is locked
  const altPath = path.map(p => {
    if (p.x <= 0.62) return p;
    const ratio = (p.y / peak); // how much of peak this point is
    // The "locked" portion stays at locked value (treated as cash, scaled into chart);
    // the "ride" portion scales with ratio
    const newY = exitLockedValue + exitRideValue * ratio;
    return { ...p, y: newY };
  });
  const altLinePath = altPath.map((p, i) => `${i === 0 ? "M" : "L"} ${xToPx(p.x)} ${yToPx(p.y)}`).join(" ");

  // ticks
  const ticks = [0, 0.25, 0.5, 0.75, 1].map(t => peak * t);
  const labels = ["Accumulate", "Run-up", "Peak", "Crash", "Today"];

  return (
    <div className="exos-crash-chart-wrap">
      <svg viewBox={`0 0 ${W} ${H}`} width="100%" height={H} preserveAspectRatio="xMidYMid meet">
        <defs>
          <linearGradient id="crashFill" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor="var(--loss)" stopOpacity="0.18" />
            <stop offset="100%" stopColor="var(--loss)" stopOpacity="0" />
          </linearGradient>
          <linearGradient id="peakHL" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor="var(--warn)" stopOpacity="0.05" />
            <stop offset="100%" stopColor="var(--warn)" stopOpacity="0" />
          </linearGradient>
        </defs>

        {/* y grid */}
        {ticks.map((t, i) => (
          <g key={i}>
            <line x1={pad.l} x2={W - pad.r} y1={yToPx(t)} y2={yToPx(t)} stroke="var(--line)" strokeDasharray="2 4" opacity="0.7" />
            <text x={pad.l - 8} y={yToPx(t) + 4} fontSize="10" fontFamily="Geist Mono" textAnchor="end" fill="var(--text-mute)">{compact(t)}</text>
          </g>
        ))}

        {/* peak vertical line */}
        <line x1={xToPx(0.62)} x2={xToPx(0.62)} y1={pad.t} y2={H - pad.b} stroke="var(--warn)" strokeDasharray="3 3" opacity="0.6" />
        <text x={xToPx(0.62) + 6} y={pad.t + 12} fontSize="10" fontFamily="Geist Mono" fill="var(--warn)" textTransform="uppercase" letterSpacing="0.08em">PEAK</text>

        {/* held-everything path */}
        <path d={fillPath} fill="url(#crashFill)" />
        <path d={linePath} stroke="var(--loss)" strokeWidth="2" fill="none" strokeLinejoin="round" strokeLinecap="round" />

        {/* with-exit-plan path */}
        {exitedPct > 0 && (
          <path d={altLinePath} stroke="var(--accent)" strokeWidth="2" fill="none" strokeDasharray="4 3" strokeLinejoin="round" strokeLinecap="round" />
        )}

        {/* peak dot */}
        <circle cx={xToPx(0.62)} cy={yToPx(peak)} r="5" fill="var(--warn)" />
        <circle cx={xToPx(0.62)} cy={yToPx(peak)} r="10" fill="var(--warn)" opacity="0.18" />

        {/* trough dot */}
        <circle cx={xToPx(0.92)} cy={yToPx(trough)} r="5" fill="var(--loss)" />

        {/* x labels */}
        {labels.map((l, i) => (
          <text key={i} x={pad.l + i * (innerW / (labels.length - 1))} y={H - 10} fontSize="10" textAnchor={i === 0 ? "start" : i === labels.length - 1 ? "end" : "middle"}
            fontFamily="Geist Mono" fill="var(--text-mute)" letterSpacing="0.04em">{l.toUpperCase()}</text>
        ))}

        {/* legend */}
        <g transform={`translate(${W - pad.r - 220}, ${pad.t + 4})`}>
          <rect x="0" y="0" width="220" height={exitedPct > 0 ? 42 : 22} rx="6" fill="var(--bg-elev-2)" stroke="var(--line)" />
          <line x1="10" x2="26" y1="13" y2="13" stroke="var(--loss)" strokeWidth="2" />
          <text x="32" y="16" fontSize="10" fontFamily="Geist Mono" fill="var(--text)">HOLD EVERYTHING</text>
          {exitedPct > 0 && (
            <>
              <line x1="10" x2="26" y1="33" y2="33" stroke="var(--accent)" strokeWidth="2" strokeDasharray="4 3" />
              <text x="32" y="36" fontSize="10" fontFamily="Geist Mono" fill="var(--text)">WITH {exitedPct}% EXIT</text>
            </>
          )}
        </g>
      </svg>
    </div>
  );
}

const REGRET_STYLES = `
.exos-regret-hero { background: linear-gradient(180deg, var(--bg-elev) 0%, var(--bg-elev-2) 100%); overflow: hidden; }
.exos-regret-hero-pad { padding: 28px 28px 14px; }
.exos-regret-kicker { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.exos-regret-kicker .serif { font-size: 16px; color: var(--text-mute); }
.exos-regret-title { margin: 0; font-size: 26px; font-weight: 400; letter-spacing: -0.02em; line-height: 1.25; max-width: 880px; }
.exos-regret-title .accent { color: var(--warn); font-weight: 500; }
.exos-crash-chart-wrap { padding: 6px 18px 0; }

.exos-regret-figures {
  display: grid; grid-template-columns: 1fr auto 1fr auto 1.4fr;
  align-items: center; gap: 16px; padding: 22px 28px 28px;
  border-top: 1px solid var(--line); margin-top: 6px;
}
.exos-regret-figure.highlight { background: linear-gradient(90deg, var(--loss-soft) 0%, transparent 100%); padding: 14px 16px; border-radius: 10px; }
.exos-regret-arrow { font-family: "Geist Mono", monospace; font-size: 20px; color: var(--text-dim); text-align: center; }
.exos-regret-arrow.loss { color: var(--loss); }
@media (max-width: 760px) {
  .exos-regret-figures { grid-template-columns: 1fr; }
  .exos-regret-arrow { transform: rotate(90deg); }
}

.exos-mix-summary { display: flex; flex-direction: column; gap: 6px; padding-top: 12px; border-top: 1px solid var(--line); }
.exos-mix-row { display: flex; justify-content: space-between; font-size: 13px; }
.exos-mix-row.total { padding-top: 8px; border-top: 1px solid var(--line); margin-top: 4px; font-weight: 500; font-size: 15px; }

.exos-regret-quote {
  margin-top: 18px; padding: 22px 24px;
  background: var(--bg-elev-2); border-radius: 12px;
  color: var(--text-mute); font-size: 18px; line-height: 1.4;
  border-left: 2px solid var(--accent);
}
`;
(function(){ if(document.getElementById("exos-regret-styles")) return; const t=document.createElement("style"); t.id="exos-regret-styles"; t.textContent=REGRET_STYLES; document.head.appendChild(t); })();

window.Regret = Regret;
