// Portfolios page — one or more agentic PMs (or humans) can run named
// portfolios tracked against an equal-weighted Nordic small-cap benchmark.
// All state lives in cortex.portfolios + cortex.portfolio_transactions;
// changes via cortex-mcp / cortex-query CLI land in this view nightly.

function _fmtPct(x, digits = 1) {
  if (x == null || isNaN(x)) return '—';
  const sign = x >= 0 ? '+' : '';
  return `${sign}${(x * 100).toFixed(digits)}%`;
}

function _fmtNum(x, digits = 0) {
  if (x == null || isNaN(x)) return '—';
  return Number(x).toLocaleString('en-GB', { maximumFractionDigits: digits, minimumFractionDigits: digits });
}

function _fmtDate(s) {
  if (!s) return '—';
  try {
    const d = new Date(s);
    return new Intl.DateTimeFormat('en-GB', { day: '2-digit', month: 'short', year: 'numeric' }).format(d);
  } catch (e) {
    return String(s).slice(0, 10);
  }
}

// ─── NAV-vs-benchmark line chart ─────────────────────────────────────────
//
// Pure SVG, no external chart lib. Both series are pre-rebased to 100 at
// inception by the kernel — we just draw lines and a 100-baseline.

function PerformanceChart({ perf, height = 220 }) {
  if (!perf || !perf.dates || perf.dates.length < 2) {
    return (
      <div style={{
        height, display: 'grid', placeItems: 'center',
        color: CX.faint, fontFamily: CX.mono, fontSize: 11, letterSpacing: '0.06em',
      }}>
        not enough history to chart yet — come back after a few trading days
      </div>
    );
  }
  const dates = perf.dates;
  const nav   = perf.nav_rebased       || [];
  const bench = perf.benchmark_rebased || [];

  // Y-axis range across both series, with a touch of padding
  const all = [];
  nav.forEach((v) => { if (v != null) all.push(v); });
  bench.forEach((v) => { if (v != null) all.push(v); });
  all.push(100);
  const lo = Math.min(...all);
  const hi = Math.max(...all);
  const pad = Math.max(2, (hi - lo) * 0.08);
  const yMin = lo - pad;
  const yMax = hi + pad;

  const W = 1000;
  const H = height;
  const PADL = 44, PADR = 12, PADT = 12, PADB = 22;
  const innerW = W - PADL - PADR;
  const innerH = H - PADT - PADB;

  const x = (i) => PADL + (i / Math.max(1, dates.length - 1)) * innerW;
  const y = (v) => PADT + (1 - (v - yMin) / (yMax - yMin)) * innerH;

  const buildPath = (series, colour) => {
    const segs = [];
    let started = false;
    series.forEach((v, i) => {
      if (v == null) { started = false; return; }
      if (!started) { segs.push(`M ${x(i).toFixed(2)} ${y(v).toFixed(2)}`); started = true; }
      else          { segs.push(`L ${x(i).toFixed(2)} ${y(v).toFixed(2)}`); }
    });
    return <path d={segs.join(' ')} fill="none" stroke={colour} strokeWidth="1.5" />;
  };

  const baseline100 = y(100);

  // Y-axis labels (~5 ticks)
  const ticks = [];
  const n = 5;
  for (let i = 0; i <= n; i++) {
    const v = yMin + (i / n) * (yMax - yMin);
    ticks.push({ v, y: y(v) });
  }

  // Date labels: 4-6 evenly spaced
  const xticks = [];
  const nx = 5;
  for (let i = 0; i <= nx; i++) {
    const idx = Math.round((i / nx) * (dates.length - 1));
    xticks.push({ idx, label: (dates[idx] || '').slice(5) });  // MM-DD
  }

  return (
    <svg viewBox={`0 0 ${W} ${H}`} style={{ width: '100%', height, display: 'block' }}>
      {/* Y-axis */}
      {ticks.map((t, i) => (
        <g key={i}>
          <line x1={PADL} x2={W - PADR} y1={t.y} y2={t.y} stroke={CX.line} strokeWidth="1" />
          <text x={PADL - 6} y={t.y + 3} fontSize="10" fill={CX.faint}
                fontFamily={CX.mono} textAnchor="end">
            {t.v.toFixed(0)}
          </text>
        </g>
      ))}

      {/* Baseline at 100 (inception value) */}
      <line x1={PADL} x2={W - PADR} y1={baseline100} y2={baseline100}
            stroke={CX.lineHi} strokeWidth="1" strokeDasharray="3 3" />

      {/* Benchmark line */}
      {buildPath(bench, CX.dim)}
      {/* Portfolio NAV — drawn last so it sits on top */}
      {buildPath(nav, CX.accent)}

      {/* X-axis labels */}
      {xticks.map((t, i) => (
        <text key={i} x={x(t.idx)} y={H - 6} fontSize="10" fill={CX.faint}
              fontFamily={CX.mono} textAnchor="middle">
          {t.label}
        </text>
      ))}

      {/* Legend */}
      <g transform={`translate(${PADL}, ${PADT + 4})`}>
        <rect x="0" y="0" width="10" height="2" fill={CX.accent} />
        <text x="14" y="4" fontSize="10" fill={CX.text} fontFamily={CX.mono}>portfolio</text>
        <rect x="80" y="0" width="10" height="2" fill={CX.dim} />
        <text x="94" y="4" fontSize="10" fill={CX.text} fontFamily={CX.mono}>benchmark</text>
      </g>
    </svg>
  );
}


// ─── Portfolio list (left side / top) ────────────────────────────────────

function PortfolioList({ portfolios, selected, onSelect }) {
  if (!portfolios.length) {
    return (
      <div style={{
        padding: '20px 22px', background: CX.panel, border: `1px solid ${CX.line}`,
        color: CX.dim, fontFamily: CX.display, fontSize: 13, lineHeight: 1.55,
      }}>
        No portfolios yet. Create one from the CLI or via Hermes:
        <pre style={{
          marginTop: 12, padding: '10px 12px', background: CX.bg,
          borderLeft: `2px solid ${CX.accent}`,
          color: CX.text, fontSize: 11, fontFamily: CX.mono, overflowX: 'auto',
        }}>
{`cortex-query portfolio create hermes-prod 1000000 --owner hermes \\
  --description "Hermes's main book"`}
        </pre>
      </div>
    );
  }
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 1, background: CX.line, border: `1px solid ${CX.line}` }}>
      {/* Header row */}
      <div style={{
        display: 'grid',
        gridTemplateColumns: '1.2fr 1fr 1.1fr 1fr 1fr 0.8fr',
        columnGap: 18,
        background: CX.bg, padding: '10px 12px',
        fontFamily: CX.mono, fontSize: 10, color: CX.faint, letterSpacing: '0.1em',
      }}>
        <span>PORTFOLIO</span>
        <span>OWNER</span>
        <span style={{ textAlign: 'right' }}>NAV</span>
        <span style={{ textAlign: 'right' }}>RETURN</span>
        <span>INCEPTION</span>
        <span style={{ textAlign: 'right' }}>POSITIONS</span>
      </div>
      {portfolios.map((p) => {
        const on = p.name === selected;
        const h = p.headline || {};
        const ret = h.total_return;
        const retColor = ret == null ? CX.dim : ret >= 0 ? CX.accent : CX.red;
        return (
          <div key={p.portfolio_id} onClick={() => onSelect(p.name)}
            style={{
              display: 'grid',
              gridTemplateColumns: '1.2fr 1fr 1.1fr 1fr 1fr 0.8fr',
        columnGap: 18,
              background: on ? CX.accentVery : CX.bg, padding: '12px',
              cursor: 'pointer', alignItems: 'center',
              borderLeft: `2px solid ${on ? CX.accent : 'transparent'}`,
              fontFamily: CX.display, fontSize: 13,
              transition: 'background .12s',
            }}>
            <span style={{ color: on ? CX.textHi : CX.text }}>
              {p.name}
              {p.description && (
                <span style={{ display: 'block', fontSize: 11, color: CX.dim, marginTop: 2 }}>
                  {p.description}
                </span>
              )}
            </span>
            <Mono style={{ fontSize: 11, color: CX.dim }}>{p.owner}</Mono>
            <Mono style={{ fontSize: 13, color: CX.text, textAlign: 'right' }}>
              {_fmtNum(h.nav, 0)} {p.base_currency}
            </Mono>
            <Mono style={{ fontSize: 13, color: retColor, textAlign: 'right' }}>
              {_fmtPct(ret, 2)}
            </Mono>
            <Mono style={{ fontSize: 11, color: CX.dim }}>{_fmtDate(p.inception_date)}</Mono>
            <Mono style={{ fontSize: 13, color: CX.dim, textAlign: 'right' }}>
              {h.n_positions ?? 0}
            </Mono>
          </div>
        );
      })}
    </div>
  );
}


// ─── Position row with expandable notes ─────────────────────────────────

function PositionRow({ p }) {
  const [open, setOpen] = React.useState(false);
  const notes = p.notes || [];
  const hasNotes = notes.length > 0;

  return (
    <div style={{ borderTop: `1px solid ${CX.line}` }}>
      {/* Main row */}
      <div style={{
        display: 'grid',
        gridTemplateColumns: '120px 1fr 0.7fr 0.6fr 0.9fr 0.9fr 0.9fr',
        columnGap: 18,
        padding: '10px 14px',
        alignItems: 'center',
        cursor: hasNotes ? 'pointer' : 'default',
      }}
      onClick={() => hasNotes && setOpen(o => !o)}>
        <Mono style={{ fontSize: 12, color: CX.text, display: 'flex', alignItems: 'center', gap: 8 }}>
          {hasNotes && (
            <span style={{
              display: 'inline-block', width: 9, textAlign: 'center',
              color: CX.accent, fontSize: 10,
              transform: open ? 'rotate(90deg)' : 'none',
              transition: 'transform .12s ease',
            }}>▸</span>
          )}
          {!hasNotes && <span style={{ display: 'inline-block', width: 9 }} />}
          {p.ticker}
        </Mono>
        <span style={{ fontFamily: CX.display, fontSize: 13, color: CX.dim }}>
          {p.company_name}
          {hasNotes && (
            <Mono style={{
              marginLeft: 10, fontSize: 9, color: CX.accent, letterSpacing: '0.12em',
              padding: '1px 6px', border: `1px solid ${CX.accent}`,
              verticalAlign: 'middle',
            }}>
              {notes.length} NOTE{notes.length === 1 ? '' : 'S'}
            </Mono>
          )}
        </span>
        <Mono style={{ fontSize: 12, color: CX.text, textAlign: 'right' }}>{_fmtNum(p.shares, 0)}</Mono>
        <Mono style={{ fontSize: 12, color: CX.accent, textAlign: 'right' }}>
          {p.weight_pct != null ? `${p.weight_pct.toFixed(1)}%` : '—'}
        </Mono>
        <Mono style={{ fontSize: 12, color: CX.text, textAlign: 'right' }}>
          {_fmtNum(p.current_value, 0)}
        </Mono>
        <Mono style={{ fontSize: 12, color: CX.dim, textAlign: 'right' }}>{_fmtNum(p.gross_cost_paid, 0)}</Mono>
        <Mono style={{ fontSize: 11, color: CX.dim, textAlign: 'right' }}>{_fmtDate(p.last_traded)}</Mono>
      </div>

      {/* Expanded notes panel */}
      {open && hasNotes && (
        <div style={{
          background: CX.panelHi,
          padding: '4px 14px 14px 38px',
          borderTop: `1px solid ${CX.line}`,
        }}>
          {notes.map((n) => {
            const kindColors = {
              thesis:    CX.accent,
              risk:      CX.red,
              next_step: CX.amber,
              log:       CX.dim,
              summary:   CX.blue,
            };
            const kindColor = kindColors[n.kind] || CX.dim;
            return (
              <div key={n.note_id} style={{
                padding: '12px 0',
                borderTop: `1px dashed ${CX.line}`,
              }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 6 }}>
                  <Mono style={{
                    fontSize: 10, color: kindColor, letterSpacing: '0.14em',
                    textTransform: 'uppercase',
                    padding: '2px 8px', border: `1px solid ${kindColor}`,
                  }}>{n.kind}</Mono>
                  <Mono style={{ fontSize: 10, color: CX.faint, letterSpacing: '0.06em' }}>
                    {_fmtDate(n.note_date)} · {n.author}
                  </Mono>
                </div>
                <div style={{
                  fontFamily: CX.display, fontSize: 13, color: CX.text,
                  lineHeight: 1.55, whiteSpace: 'pre-wrap',
                }}>
                  {n.body}
                </div>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}


// ─── Portfolio detail view ───────────────────────────────────────────────

function PortfolioDetail({ detail }) {
  if (!detail) return null;
  if (detail.error) {
    return (
      <div style={{
        padding: '14px 18px', borderLeft: `2px solid ${CX.red}`,
        background: 'rgba(240,132,106,0.08)', color: CX.red, fontFamily: CX.mono, fontSize: 12,
      }}>
        couldn't load portfolio: {detail.error}
      </div>
    );
  }
  const meta = detail.meta || {};
  const h = detail.headline || {};
  const positions = detail.positions || [];
  const perf = detail.performance || {};
  const tx = detail.transactions || [];

  const ph = perf.headline || {};

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 28, marginTop: 28 }}>
      {/* ── Headline metrics ── */}
      <div style={{
        display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)', gap: 1,
        background: CX.line, border: `1px solid ${CX.line}`,
      }}>
        {[
          ['NAV',                _fmtNum(h.nav, 0) + ' ' + (meta.base_currency || ''), CX.text],
          ['Total return',       _fmtPct(h.total_return, 2), h.total_return == null ? CX.dim : h.total_return >= 0 ? CX.accent : CX.red],
          ['vs benchmark',       _fmtPct(ph.excess_return, 2), ph.excess_return == null ? CX.dim : ph.excess_return >= 0 ? CX.accent : CX.red],
          ['Max drawdown',       _fmtPct(ph.max_drawdown, 2), CX.red],
          ['Cash / positions',   `${_fmtNum(h.cash, 0)} / ${_fmtNum(h.positions_value, 0)}`, CX.text],
        ].map(([label, value, colour], i) => (
          <div key={i} style={{ background: CX.panel, padding: '18px 20px' }}>
            <Mono style={{ fontSize: 10, color: CX.faint, letterSpacing: '0.16em', textTransform: 'uppercase' }}>
              {label}
            </Mono>
            <div style={{ fontFamily: CX.mono, fontSize: 20, color: colour, marginTop: 8, letterSpacing: '-0.01em' }}>
              {value}
            </div>
          </div>
        ))}
      </div>

      {/* ── NAV vs benchmark chart ── */}
      <div style={{ background: CX.panel, border: `1px solid ${CX.line}`, padding: '18px 22px' }}>
        <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 14 }}>
          <Mono style={{ fontSize: 10, color: CX.faint, letterSpacing: '0.16em' }}>
            PERFORMANCE · BENCHMARK = {meta.benchmark || 'NORDIC_SMALL_CAP_EW'} · REBASED TO 100 AT INCEPTION
          </Mono>
          <Mono style={{ fontSize: 11, color: CX.dim }}>
            since {_fmtDate(meta.inception_date)}
          </Mono>
        </div>
        <PerformanceChart perf={perf} height={240} />
      </div>

      {/* ── Positions table ── */}
      <div>
        <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 10 }}>
          <Mono style={{ fontSize: 10, color: CX.faint, letterSpacing: '0.16em' }}>POSITIONS · {positions.length}</Mono>
          <Mono style={{ fontSize: 11, color: CX.dim }}>
            mark-to-market = shares × latest close
          </Mono>
        </div>
        <div style={{ border: `1px solid ${CX.line}`, background: CX.panel, overflow: 'hidden' }}>
          <div style={{
            display: 'grid',
            gridTemplateColumns: '120px 1fr 0.7fr 0.6fr 0.9fr 0.9fr 0.9fr',
            columnGap: 18,
            padding: '10px 14px', borderBottom: `1px solid ${CX.line}`,
            fontFamily: CX.mono, fontSize: 10, color: CX.faint, letterSpacing: '0.1em',
          }}>
            <span>TICKER</span>
            <span>NAME</span>
            <span style={{ textAlign: 'right' }}>SHARES</span>
            <span style={{ textAlign: 'right' }}>WEIGHT</span>
            <span style={{ textAlign: 'right' }}>VALUE</span>
            <span style={{ textAlign: 'right' }}>COST PAID</span>
            <span style={{ textAlign: 'right' }}>LAST TRADED</span>
          </div>
          {positions.length === 0 && (
            <div style={{ padding: '18px 14px', fontFamily: CX.mono, fontSize: 11, color: CX.faint }}>
              no current positions
            </div>
          )}
          {positions.map((p) => <PositionRow key={p.security_id} p={p} />)}
        </div>
      </div>

      {/* ── Transaction log ── */}
      <div>
        <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 10 }}>
          <Mono style={{ fontSize: 10, color: CX.faint, letterSpacing: '0.16em' }}>
            TRANSACTION LOG · {tx.length} EVENTS · NEWEST FIRST
          </Mono>
        </div>
        <div style={{ border: `1px solid ${CX.line}`, background: CX.panel, overflow: 'hidden' }}>
          <div style={{
            display: 'grid',
            gridTemplateColumns: '90px 80px 80px 1fr 0.6fr 0.6fr 0.8fr 0.6fr',
            columnGap: 18,
            padding: '10px 14px', borderBottom: `1px solid ${CX.line}`,
            fontFamily: CX.mono, fontSize: 10, color: CX.faint, letterSpacing: '0.1em',
          }}>
            <span>DATE</span>
            <span>ACTION</span>
            <span>TICKER</span>
            <span>RATIONALE</span>
            <span style={{ textAlign: 'right' }}>QTY</span>
            <span style={{ textAlign: 'right' }}>PRICE</span>
            <span style={{ textAlign: 'right' }}>AMOUNT</span>
            <span>AUTHOR</span>
          </div>
          {tx.length === 0 && (
            <div style={{ padding: '18px 14px', fontFamily: CX.mono, fontSize: 11, color: CX.faint }}>
              no transactions yet
            </div>
          )}
          {tx.map((t) => {
            const colour = ['buy', 'deposit', 'dividend'].includes(t.action) ? CX.accent
                         : ['sell'].includes(t.action) ? CX.amber
                         : CX.red;
            return (
              <div key={t.transaction_id} style={{
                display: 'grid',
                gridTemplateColumns: '90px 80px 80px 1fr 0.6fr 0.6fr 0.8fr 0.6fr',
            columnGap: 18,
                padding: '10px 14px', borderTop: `1px solid ${CX.line}`,
                alignItems: 'center',
              }}>
                <Mono style={{ fontSize: 11, color: CX.dim }}>{_fmtDate(t.transaction_date)}</Mono>
                <Mono style={{ fontSize: 11, color: colour, letterSpacing: '0.04em' }}>{t.action}</Mono>
                <Mono style={{ fontSize: 12, color: CX.text }}>{t.ticker || '—'}</Mono>
                <span style={{ fontFamily: CX.display, fontSize: 12, color: CX.dim }}>{t.rationale || '—'}</span>
                <Mono style={{ fontSize: 11, color: CX.text, textAlign: 'right' }}>{t.quantity != null ? _fmtNum(t.quantity, 0) : '—'}</Mono>
                <Mono style={{ fontSize: 11, color: CX.text, textAlign: 'right' }}>{t.price != null ? _fmtNum(t.price, 2) : '—'}</Mono>
                <Mono style={{ fontSize: 11, color: t.amount >= 0 ? CX.accent : CX.dim, textAlign: 'right' }}>{_fmtNum(t.amount, 0)}</Mono>
                <Mono style={{ fontSize: 11, color: CX.dim }}>{t.author}</Mono>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}


// ─── Top-level page ──────────────────────────────────────────────────────

function PagePortfolios() {
  const live = (typeof window !== 'undefined' && window.CORTEX_DATA) || {};
  const summary = live.PORTFOLIOS_SUMMARY || [];
  const detail = live.PORTFOLIOS_DETAIL || {};

  const initial = summary[0]?.name || null;
  const [selected, setSelected] = React.useState(initial);

  return (
    <div style={{ padding: '32px 32px 64px', overflowY: 'auto', height: '100%' }}>
      {/* Header */}
      <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', marginBottom: 24 }}>
        <div>
          <Mono style={{ fontSize: 10, color: CX.accent, letterSpacing: '0.18em' }}>08 · /Q.PORTFOLIOS</Mono>
          <h1 style={{ fontFamily: CX.display, fontSize: 40, fontWeight: 400, letterSpacing: '-0.02em', margin: '8px 0 4px', color: CX.textHi }}>
            Portfolios<span style={{ color: CX.accent }}>.</span>
          </h1>
          <Mono style={{ fontSize: 11, color: CX.faint, letterSpacing: '0.08em' }}>
            one or more agentic PMs · NAV vs benchmark · all changes logged
          </Mono>
        </div>
        <Mono style={{ fontSize: 11, color: CX.dim, letterSpacing: '0.06em' }}>
          {summary.length} active
        </Mono>
      </div>

      {/* Portfolios list — always visible */}
      <PortfolioList portfolios={summary} selected={selected} onSelect={setSelected} />

      {/* Detail for the selected one */}
      {selected && detail[selected] && (
        <PortfolioDetail detail={detail[selected]} />
      )}
    </div>
  );
}

window.PagePortfolios = PagePortfolios;
