/* GoldYeld — interactive Position Simulator.
   Two axes: allocation amount (slider) + entry date (draggable marker on the chart).
   Entry price follows a synthetic-but-realistic gold price history; from entry→today we
   compound yield every 36 days (in gold); right of today is a dashed "future unknown" zone.
   Exports window.PositionSimulator. Reads window.GC for colors/fonts. */

const SPOT = 2016;                 // gold price "today"
const HIST_DAYS = 365;             // 12 months of history, day 0 = 12mo ago, 365 = today
const PROJ_DAYS = 108;             // ~3 cycles of future projection
const TOTAL_DAYS = HIST_DAYS + PROJ_DAYS;
const CYCLE_LEN = 36;              // days per yield cycle
const APR = 0.20;
const CYCLE_RATE = APR * CYCLE_LEN / 365;   // simple (non-compounding) yield per cycle, in gold
const TODAY = new Date(2026, 5, 2);          // Jun 2, 2026

// monthly anchor prices, oldest → today (13 values @ day 0,30,…,360, last≈365)
const ANCHORS = [1812, 1798, 1845, 1888, 1864, 1902, 1955, 1928, 1972, 1949, 2004, 1988, SPOT];
function priceAt(day) {
  if (day >= HIST_DAYS) return SPOT;
  if (day <= 0) day = 0;
  const seg = day / 30, i = Math.floor(seg), f = seg - i;
  const a = ANCHORS[i], b = ANCHORS[Math.min(i + 1, ANCHORS.length - 1)];
  let p = a + (b - a) * f;
  p += 6 * Math.sin(day * 0.13) + 3.5 * Math.sin(day * 0.41 + 1.2); // texture
  return p;
}
function dateForDay(day) { const d = new Date(TODAY); d.setDate(d.getDate() - (HIST_DAYS - day)); return d; }
function fmtDate(d) { return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }); }
function fmtUSD(n) { return '$' + Math.round(n).toLocaleString('en-US'); }

function PositionSimulator({ c }) {
  const F = (window.GC && window.GC.fonts) || { d: 'Georgia,serif', b: 'system-ui,sans-serif', m: 'monospace' };
  const [amount, setAmount] = React.useState(1000000);
  const [entry, setEntry] = React.useState(0); // 12 months ago
  const [hoverDay, setHoverDay] = React.useState(null);
  const svgRef = React.useRef(null);

  // ---- derived figures ----
  const entryPrice = priceAt(entry);
  const oz0 = amount / entryPrice;
  const daysHeld = Math.max(0, HIST_DAYS - entry);
  const cycles = Math.floor(daysHeld / CYCLE_LEN);
  const ozNow = oz0 * (1 + CYCLE_RATE * cycles);   // simple yield, not compounded
  const value = ozNow * SPOT;
  const yieldUSD = (ozNow - oz0) * SPOT;
  const totalRet = (value - amount) / amount;
  const isToday = entry >= HIST_DAYS - 1;
  // combined APR = yield APR + simple annualized gold-price move over the holding period (no compounding)
  const goldAPR = (!isToday && daysHeld >= 14) ? ((SPOT / entryPrice - 1) * (365 / daysHeld)) : 0;
  const combinedAPR = APR + goldAPR;
  const [tip, setTip] = React.useState(false);

  // ---- chart geometry (dynamic window: entry → today → short projection) ----
  const W = 660, H = 226, PROJ = 72;
  const xMin = entry, xMax = HIST_DAYS + PROJ;
  const xFor = (day) => ((day - xMin) / (xMax - xMin)) * W;
  const valsAt = (day) => {
    const price = day <= HIST_DAYS ? priceAt(day) : SPOT;
    const cyc = Math.max(0, Math.floor((day - entry) / CYCLE_LEN));
    const oz = oz0 * (1 + CYCLE_RATE * cyc);   // simple yield, not compounded
    return { wy: oz * price, go: oz0 * price };
  };
  // sample realized (entry→today) and projection (today→end)
  const step = 3;
  const realized = [], proj = [];
  for (let d = entry; d <= HIST_DAYS; d += step) realized.push([d, valsAt(d)]);
  if (realized.length === 0 || realized[realized.length - 1][0] !== HIST_DAYS) realized.push([HIST_DAYS, valsAt(HIST_DAYS)]);
  for (let d = HIST_DAYS; d <= xMax; d += step) proj.push([d, valsAt(d)]);

  const allY = [amount, ...realized.map(p => p[1].wy), ...proj.map(p => p[1].wy), ...realized.map(p => p[1].go)];
  const yMax = Math.max(...allY) * 1.04, yMin = Math.min(...allY) * 0.97;
  const yFor = (v) => H - ((v - yMin) / (yMax - yMin)) * H;
  const poly = (pts, key) => pts.map(([d, v]) => `${xFor(d)},${yFor(v[key])}`).join(' ');
  const areaPts = `${xFor(entry)},${H} ${poly(realized, 'wy')} ${xFor(HIST_DAYS)},${H}`;

  const monthsAgo = Math.round(daysHeld / 30);
  const entryLabel = isToday ? 'Today' : (monthsAgo <= 1 ? '~1 month ago' : `~${monthsAgo} months ago`);
  const presets = [['Today', HIST_DAYS], ['1M', HIST_DAYS - 30], ['3M', HIST_DAYS - 90], ['6M', HIST_DAYS - 182], ['12M ago', 0]];
  const amtChips = [100000, 250000, 500000, 1000000];

  const kpis = [
    ['Entry price', `$${entryPrice.toFixed(0)} / oz`, false, fmtDate(dateForDay(entry))],
    ['Gold held', `${ozNow.toFixed(2)} oz`, false, `${(ozNow * 31.1035 / 1000).toFixed(2)} kg`],
    ['Cycles paid', isToday ? '—' : String(cycles), false, isToday ? 'not started' : `every ${CYCLE_LEN} days`],
    ['Yield earned', isToday ? '$0' : `+${fmtUSD(yieldUSD)}`, true, isToday ? 'accrues over time' : `${(APR * 100).toFixed(1)}% APR`],
  ];

  return (
    <div style={{ background: c.panel, border: `1px solid ${c.line}`, borderRadius: GC.r + 4, boxShadow: c.shadow, overflow: 'hidden' }}>
      <style>{`.gy-range{-webkit-appearance:none;appearance:none;height:6px;border-radius:999px;outline:none;cursor:pointer}
.gy-range::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:22px;height:22px;border-radius:50%;background:${c.gold};border:3px solid #fff;box-shadow:0 2px 8px rgba(169,120,31,.4);cursor:grab}
.gy-range::-moz-range-thumb{width:22px;height:22px;border-radius:50%;background:${c.gold};border:3px solid #fff;box-shadow:0 2px 8px rgba(169,120,31,.4);cursor:grab}
.gy-chip{transition:all .15s ease}
@media (max-width: 720px) {
  .ps-controls { grid-template-columns: minmax(0,1fr) !important; gap: 22px !important; padding: 18px 20px 6px !important; }
  .ps-grid { grid-template-columns: minmax(0,1fr) !important; }
  .ps-left { border-right: none !important; border-bottom: 1px solid ${c.line}; padding: 22px 20px !important; }
  .ps-chart { padding: 18px 20px 14px !important; }
  .ps-value { font-size: 38px !important; }
}`}</style>

      {/* header */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '15px 26px', borderBottom: `1px solid ${c.line}`, flexWrap: 'wrap', gap: 10 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
          <span style={{ fontFamily: F.m, fontSize: 10.5, letterSpacing: '0.1em', color: c.gold, border: `1px solid ${c.goldHair}`, borderRadius: 999, padding: '4px 11px' }}>EXAMPLE · SIMULATION</span>
          <span style={{ fontFamily: F.b, fontSize: 13, color: c.sub }}>Adjust the amount and your entry date</span>
        </div>
        <div style={{ position: 'relative' }} onMouseEnter={() => setTip(true)} onMouseLeave={() => setTip(false)}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, background: combinedAPR >= 0 ? c.up : '#b4543a', borderRadius: 12, padding: '8px 16px', boxShadow: combinedAPR >= 0 ? '0 6px 16px rgba(74,125,87,0.28)' : '0 6px 16px rgba(180,84,58,0.28)', cursor: 'help' }}>
            <span style={{ fontFamily: F.m, fontSize: 10, letterSpacing: '0.12em', color: 'rgba(255,255,255,0.82)', display: 'inline-flex', alignItems: 'center', gap: 5 }}>
              COMBINED APR
              <span style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: 13, height: 13, borderRadius: '50%', border: '1px solid rgba(255,255,255,0.6)', fontSize: 8.5, fontStyle: 'italic', fontFamily: F.d }}>i</span>
            </span>
            <span style={{ fontFamily: F.d, fontSize: 26, fontWeight: 600, color: '#fff', lineHeight: 1, letterSpacing: '-0.01em' }}>
              {combinedAPR >= 0 ? '+' : ''}{(combinedAPR * 100).toFixed(1)}%
            </span>
          </div>
          {tip && (
            <div style={{ position: 'absolute', top: 'calc(100% + 10px)', right: 0, width: 290, zIndex: 20, background: c.panel, border: `1px solid ${c.line}`, borderRadius: 12, boxShadow: c.shadow, padding: '16px 18px', textAlign: 'left' }}>
              <div style={{ fontFamily: F.d, fontSize: 15, fontWeight: 600, color: c.ink, marginBottom: 4 }}>How Combined APR is built</div>
              <p style={{ fontFamily: F.b, fontSize: 11.5, color: c.sub, lineHeight: 1.5, margin: '0 0 12px' }}>Two stacked engines on the same gold, annualized over your holding period:</p>
              {[
                ['Yield', `+${(APR * 100).toFixed(1)}%`, 'Paid in gold every 36 days · simple, not compounded', c.gold],
                ['Gold price', isToday ? '—' : `${goldAPR >= 0 ? '+' : ''}${(goldAPR * 100).toFixed(1)}%`, isToday ? 'No holding period yet' : `$${entryPrice.toFixed(0)} → $${SPOT.toLocaleString('en-US')}, annualized`, c.faint],
              ].map(([l, v, sub, dot]) => (
                <div key={l} style={{ display: 'flex', alignItems: 'flex-start', gap: 10, padding: '7px 0', borderTop: `1px solid ${c.lineSoft}` }}>
                  <span style={{ width: 8, height: 8, borderRadius: '50%', background: dot, marginTop: 5, flexShrink: 0 }} />
                  <div style={{ flex: 1 }}>
                    <div style={{ display: 'flex', justifyContent: 'space-between' }}>
                      <span style={{ fontFamily: F.b, fontSize: 12.5, color: c.ink, fontWeight: 600 }}>{l}</span>
                      <span style={{ fontFamily: F.m, fontSize: 12.5, color: c.ink }}>{v}</span>
                    </div>
                    <div style={{ fontFamily: F.m, fontSize: 10, color: c.faint, marginTop: 2 }}>{sub}</div>
                  </div>
                </div>
              ))}
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 10, paddingTop: 10, borderTop: `1px solid ${c.line}` }}>
                <span style={{ fontFamily: F.b, fontSize: 12.5, color: c.ink, fontWeight: 700 }}>Combined APR</span>
                <span style={{ fontFamily: F.d, fontSize: 18, fontWeight: 600, color: c.up }}>{combinedAPR >= 0 ? '+' : ''}{(combinedAPR * 100).toFixed(1)}%</span>
              </div>
              <p style={{ fontFamily: F.b, fontSize: 10, color: c.faint, lineHeight: 1.45, margin: '10px 0 0' }}>Illustrative. Gold-price component reflects past movement; future prices are unknown. Yield is GoldYeld’s {(APR * 100).toFixed(0)}% target APR, paid in gold and not compounded.</p>
            </div>
          )}
        </div>
      </div>

      {/* controls */}
      <div className="ps-controls" style={{ padding: '22px 26px 6px', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 30 }}>
        <div>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
            <span style={{ fontFamily: F.b, fontSize: 13, color: c.sub }}>I allocate</span>
            <span style={{ fontFamily: F.d, fontSize: 24, fontWeight: 600, color: c.ink, letterSpacing: '-0.01em' }}>{fmtUSD(amount)}</span>
          </div>
          <input className="gy-range" type="range" min="10000" max="2000000" step="10000" value={amount}
            onChange={(e) => setAmount(+e.target.value)}
            style={{ width: '100%', marginTop: 12, background: `linear-gradient(90deg, ${c.gold} ${(amount - 10000) / (2000000 - 10000) * 100}%, ${c.line} ${(amount - 10000) / (2000000 - 10000) * 100}%)` }} />
          <div style={{ display: 'flex', gap: 6, marginTop: 12 }}>
            {amtChips.map(a => (
              <span key={a} className="gy-chip gy-btn" onClick={() => setAmount(a)} style={{ fontFamily: F.m, fontSize: 11, padding: '5px 11px', borderRadius: 999, cursor: 'pointer', border: `1px solid ${amount === a ? c.gold : c.line}`, color: amount === a ? c.gold : c.sub, background: amount === a ? c.goldWash || '#f6efdf' : 'transparent' }}>{a >= 1000000 ? `$${a / 1000000}M` : `$${a / 1000}k`}</span>
            ))}
          </div>
        </div>
        <div>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
            <span style={{ fontFamily: F.b, fontSize: 13, color: c.sub }}>I entered</span>
            <span style={{ fontFamily: F.d, fontSize: 24, fontWeight: 600, color: c.ink, letterSpacing: '-0.01em' }}>{entryLabel}</span>
          </div>
          <input className="gy-range" type="range" min="0" max={HIST_DAYS} step="1" value={entry}
            onChange={(e) => setEntry(+e.target.value)}
            style={{ width: '100%', marginTop: 12, background: `linear-gradient(90deg, ${c.line} ${entry / HIST_DAYS * 100}%, ${c.gold} ${entry / HIST_DAYS * 100}%)` }} />
          <div style={{ display: 'flex', gap: 6, marginTop: 12, flexWrap: 'wrap' }}>
            {presets.map(([lab, d]) => {
              const on = Math.abs(entry - d) < 3;
              return <span key={lab} className="gy-chip gy-btn" onClick={() => setEntry(d)} style={{ fontFamily: F.m, fontSize: 11, padding: '5px 11px', borderRadius: 999, cursor: 'pointer', border: `1px solid ${on ? c.gold : c.line}`, color: on ? c.gold : c.sub, background: on ? c.goldWash || '#f6efdf' : 'transparent' }}>{lab}</span>;
            })}
          </div>
        </div>
      </div>

      {/* value + chart */}
      <div className="ps-grid" style={{ display: 'grid', gridTemplateColumns: '0.74fr 1.26fr', borderTop: `1px solid ${c.line}`, marginTop: 16 }}>
        <div className="ps-left" style={{ padding: 28, borderRight: `1px solid ${c.line}` }}>
          <div style={{ fontFamily: F.b, fontSize: 13, color: c.sub }}>{isToday ? 'Starting value' : 'Value today'}</div>
          <div className="ps-value" style={{ fontFamily: F.d, fontSize: 46, fontWeight: 500, letterSpacing: '-0.02em', marginTop: 6, color: c.ink, lineHeight: 1 }}>{fmtUSD(value)}</div>
          <div style={{ fontFamily: F.m, fontSize: 11.5, color: c.faint, marginTop: 8 }}>{fmtUSD(amount)} allocated{isToday ? '' : ` · +${fmtUSD(value - amount)}`}</div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '18px 14px', marginTop: 26 }}>
            {kpis.map(([l, v, g, sub]) => (
              <div key={l}>
                <div style={{ fontFamily: F.b, fontSize: 11.5, color: c.sub }}>{l}</div>
                <div style={{ fontFamily: F.m, fontSize: 15, color: g ? c.gold : c.ink, marginTop: 4 }}>{v}</div>
                {sub && <div style={{ fontFamily: F.m, fontSize: 9.5, color: c.faint, marginTop: 2 }}>{sub}</div>}
              </div>
            ))}
          </div>
        </div>

        <div className="ps-chart" style={{ padding: '22px 26px 18px' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', fontFamily: F.m, fontSize: 10, color: c.sub, letterSpacing: '0.06em', marginBottom: 8, flexWrap: 'wrap', gap: 6 }}>
            <span>POSITION VALUE OVER TIME</span>
            <span style={{ display: 'inline-flex', gap: 12 }}>
              <span style={{ display: 'inline-flex', gap: 5, alignItems: 'center' }}><span style={{ width: 14, height: 2.5, background: c.gold, display: 'inline-block' }} />with yield</span>
              <span style={{ display: 'inline-flex', gap: 5, alignItems: 'center' }}><span style={{ width: 14, height: 1.5, background: c.faint, display: 'inline-block' }} />price only</span>
            </span>
          </div>
          <div style={{ position: 'relative' }}>
          <svg ref={svgRef} viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="none"
            onPointerMove={(e) => { const r = svgRef.current.getBoundingClientRect(); const frac = (e.clientX - r.left) / r.width; setHoverDay(Math.max(entry, Math.min(xMax, Math.round(xMin + frac * (xMax - xMin))))); }}
            onPointerLeave={() => setHoverDay(null)}
            style={{ width: '100%', height: 226, display: 'block', overflow: 'visible', cursor: 'crosshair' }}>
            {/* future zone shading */}
            <rect x={xFor(HIST_DAYS)} y="0" width={W - xFor(HIST_DAYS)} height={H} fill={c.bg2} opacity="0.5" />
            {/* area under realized */}
            <polygon points={areaPts} fill={c.gold} opacity="0.08" />
            {/* price-only baseline */}
            <polyline points={poly(realized, 'go')} fill="none" stroke={c.faint} strokeWidth="1.5" strokeDasharray="4 4" vectorEffect="non-scaling-stroke" />
            {/* realized with-yield */}
            <polyline points={poly(realized, 'wy')} fill="none" stroke={c.gold} strokeWidth="2.6" vectorEffect="non-scaling-stroke" strokeLinejoin="round" />
            {/* projection dashed */}
            <polyline points={poly(proj, 'wy')} fill="none" stroke={c.goldSoft} strokeWidth="2.2" strokeDasharray="2 5" vectorEffect="non-scaling-stroke" />
            {/* today divider */}
            <line x1={xFor(HIST_DAYS)} y1="0" x2={xFor(HIST_DAYS)} y2={H} stroke={c.ink} strokeWidth="1" strokeDasharray="3 4" opacity="0.3" />
            <text x={xFor(HIST_DAYS) - 6} y="14" textAnchor="end" fontFamily={F.m} fontSize="9.5" fill={c.sub} letterSpacing="0.08em">TODAY</text>
            <text x={(xFor(HIST_DAYS) + W) / 2} y="14" textAnchor="middle" fontFamily={F.m} fontSize="9" fill={c.faint}>FUTURE · price unknown</text>
            {/* hover crosshair */}
            {hoverDay != null && (() => { const hv = valsAt(hoverDay); return (
              <g>
                <line x1={xFor(hoverDay)} y1="0" x2={xFor(hoverDay)} y2={H} stroke={c.ink} strokeWidth="1" opacity="0.25" />
                <circle cx={xFor(hoverDay)} cy={yFor(hv.wy)} r="5" fill={hoverDay > HIST_DAYS ? c.goldSoft : c.gold} stroke="#fff" strokeWidth="2" />
              </g>
            ); })()}
            {/* entry marker */}
            <circle cx={xFor(entry)} cy={yFor(amount)} r="6" fill={c.gold} stroke="#fff" strokeWidth="2.5" />
            <text x={xFor(entry) + 8} y={yFor(amount) - 9} fontFamily={F.m} fontSize="9.5" fill={c.gold}>ENTRY</text>
          </svg>
          {hoverDay != null && (() => {
            const hv = valsAt(hoverDay);
            const cyc = Math.max(0, Math.floor((hoverDay - entry) / CYCLE_LEN));
            const isFut = hoverDay > HIST_DAYS;
            const frac = (hoverDay - xMin) / (xMax - xMin);
            const yieldNow = hv.wy - hv.go;
            return (
              <div style={{ position: 'absolute', top: 0, left: `${Math.max(16, Math.min(84, frac * 100))}%`, transform: 'translateX(-50%)', background: c.ink, color: '#fff', borderRadius: 9, padding: '9px 12px', minWidth: 150, pointerEvents: 'none', boxShadow: c.shadow, zIndex: 5 }}>
                <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10, marginBottom: 6 }}>
                  <span style={{ fontFamily: F.m, fontSize: 10.5, color: '#fff' }}>{fmtDate(dateForDay(hoverDay))}</span>
                  <span style={{ fontFamily: F.m, fontSize: 8.5, letterSpacing: '0.06em', color: isFut ? c.goldSoft : c.up, border: `1px solid ${isFut ? c.goldSoft : c.up}`, borderRadius: 4, padding: '1px 5px' }}>{isFut ? 'PROJECTED' : 'REALIZED'}</span>
                </div>
                <div style={{ fontFamily: F.d, fontSize: 19, fontWeight: 600, lineHeight: 1, color: '#fff' }}>{fmtUSD(hv.wy)}</div>
                {[
                  ['Gold price', isFut ? `$${SPOT.toLocaleString('en-US')} (assumed)` : `$${(hoverDay <= HIST_DAYS ? priceAt(hoverDay) : SPOT).toFixed(0)} / oz`],
                  ['Yield to date', `+${fmtUSD(yieldNow)}`],
                  ['Cycles paid', `${cyc} · batch ${String(24 - Math.floor((HIST_DAYS - hoverDay) / CYCLE_LEN)).padStart(3, '0')}`],
                ].map(([l, v]) => (
                  <div key={l} style={{ display: 'flex', justifyContent: 'space-between', gap: 12, marginTop: 5, fontFamily: F.m, fontSize: 10 }}>
                    <span style={{ color: 'rgba(255,255,255,0.55)' }}>{l}</span><span style={{ color: '#fff' }}>{v}</span>
                  </div>
                ))}
              </div>
            );
          })()}
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between', fontFamily: F.m, fontSize: 10, color: c.faint, marginTop: 14 }}>
            <span>ENTRY <span style={{ color: c.ink }}>{fmtDate(dateForDay(entry))}</span> @ ${entryPrice.toFixed(0)}</span>
            <span>SPOT TODAY <span style={{ color: c.ink }}>${SPOT.toLocaleString('en-US')}</span></span>
          </div>
        </div>
      </div>

      {/* footnote */}
      <div style={{ padding: '14px 26px', borderTop: `1px solid ${c.line}`, background: c.bg2, fontFamily: F.b, fontSize: 12, color: c.sub, lineHeight: 1.5 }}>
        {isToday
          ? 'Enter today and nothing is realized yet — tomorrow’s gold price is unknown, but yield still accrues in gold every 36 days (dashed). Drag the marker into the past to see a real entry play out.'
          : `Entered ${entryLabel.toLowerCase()} at $${entryPrice.toFixed(0)}/oz: gold moved to $${SPOT.toLocaleString('en-US')} and ${cycles} yield ${cycles === 1 ? 'cycle has' : 'cycles have'} paid in gold. Illustrative — based on GoldYeld’s ${(APR * 100).toFixed(1)}% target APR (simple, not compounded), not a guarantee.`}
      </div>
    </div>
  );
}

Object.assign(window, { PositionSimulator });
