/* "Trade stories" tab of the strategy ledger: every trade, open and closed, with one plain-English
 * sentence on what happened (never entered, entered and still open, hit the stop, ...). The wording
 * lives in tradestory.js (pure, tested in tests/trade_story.test.js); this only lays it out.
 * Rows come from the same ledger (open) and history (closed) data the other two tabs use. */

const { useState: useStateTS, useMemo: useMemoTS } = React;

const TS_PAGE = 25;
const TS_STATUS = {
  open:    { label: 'Open',          chip: 'gold' },
  waiting: { label: 'Waiting',       chip: 'info' },
  closed:  { label: 'Closed',        chip: 'neutral' },
  never:   { label: 'Never entered', chip: 'neutral' },
  skipped: { label: 'Not taken',     chip: 'neutral' },
};

function TradeStoriesTable({ open, closed, onOpenSpec }) {
  const [status, setStatus] = useStateTS('all');
  const [coin, setCoin] = useStateTS('all');
  const [page, setPage] = useStateTS(0);

  const stories = useMemoTS(() => {
    if (open == null && closed == null) return null;
    const seen = new Set(), out = [];
    // open first, then closed; a signal can be in both while a position is still winding down
    [...(open || []), ...(closed || [])].forEach((r) => {
      if (seen.has(r.id)) return;
      seen.add(r.id);
      let s;
      try { s = window.TradeStory.build(r); } catch (e) { s = { symbol: r.symbol, side: r.side, status: 'skipped', tone: 'neutral', text: 'No story available for this trade.', pnlPct: null, whenMs: 0, basis: 'paper' }; }
      out.push({ id: r.id, ...s });
    });
    return out.sort((a, b) => (b.whenMs || 0) - (a.whenMs || 0));
  }, [open, closed]);

  if (stories == null) {
    return <div style={{ padding: '22px 0', textAlign: 'center', color: 'var(--text-4)', fontSize: 12 }}>Loading…</div>;
  }
  if (!stories.length) {
    return <div style={{ padding: '22px 0', textAlign: 'center', color: 'var(--text-4)', fontSize: 12 }}>No trades to tell a story about yet.</div>;
  }

  const coins = [...new Set(stories.map((s) => s.symbol).filter(Boolean))].sort();
  const count = (k) => stories.filter((s) => s.status === k).length;
  const filtered = stories.filter((s) => (status === 'all' || s.status === status) && (coin === 'all' || s.symbol === coin));
  const pages = Math.max(1, Math.ceil(filtered.length / TS_PAGE));
  const safe = Math.min(page, pages - 1);
  const rows = filtered.slice(safe * TS_PAGE, (safe + 1) * TS_PAGE);

  const sel = { padding: '3px 8px', borderRadius: 6, fontSize: 11, cursor: 'pointer', fontFamily: 'var(--font-sans)',
                background: 'var(--bg-elev)', border: '1px solid var(--border-soft)', color: 'var(--text)' };
  const th = { textAlign: 'left', fontSize: 9.5, color: 'var(--text-4)', letterSpacing: '0.09em', textTransform: 'uppercase', padding: '0 8px 7px', fontWeight: 500 };
  const td = { padding: '9px 8px', borderTop: '1px solid var(--border-soft)', fontSize: 12, verticalAlign: 'top' };
  const toneColor = { bull: 'var(--bull)', bear: 'var(--bear)', gold: 'var(--gold)', neutral: 'var(--text-3)' };

  return (
    <div>
      <div style={{ display: 'flex', gap: 10, alignItems: 'center', flexWrap: 'wrap', marginBottom: 10, padding: '0 2px' }}>
        <select value={status} onChange={(e) => { setStatus(e.target.value); setPage(0); }} style={sel} aria-label="Filter by what happened">
          <option value="all">All trades ({stories.length})</option>
          {Object.keys(TS_STATUS).filter((k) => count(k)).map((k) => <option key={k} value={k}>{TS_STATUS[k].label} ({count(k)})</option>)}
        </select>
        <select value={coin} onChange={(e) => { setCoin(e.target.value); setPage(0); }} style={sel} aria-label="Filter by coin">
          <option value="all">All coins</option>
          {coins.map((c) => <option key={c} value={c}>{c}</option>)}
        </select>
        <span style={{ fontSize: 10.5, color: 'var(--text-4)' }}>{filtered.length} trade{filtered.length === 1 ? '' : 's'}, newest activity first</span>
      </div>

      <div style={{ overflowX: 'auto' }}>
        <table style={{ width: '100%', borderCollapse: 'collapse' }}>
          <thead><tr>
            <th style={th}>coin</th>
            <th style={th}>status</th>
            <th style={{ ...th, minWidth: 280 }}>what happened</th>
            <th style={{ ...th, textAlign: 'right' }} title="Profit or loss on the entry price, before fees">result</th>
          </tr></thead>
          <tbody>
            {rows.map((s) => {
              const st = TS_STATUS[s.status] || TS_STATUS.skipped;
              return (
                <tr key={s.id}>
                  <td style={{ ...td, whiteSpace: 'nowrap' }}>
                    <b>{typeof SpecSymbolLink === 'function' ? <SpecSymbolLink symbol={s.symbol} onOpenSpec={onOpenSpec} /> : s.symbol}</b>
                    <span style={{ marginLeft: 6, color: s.side === 'long' ? 'var(--bull)' : 'var(--bear)' }}>{s.side}</span>
                  </td>
                  <td style={{ ...td, whiteSpace: 'nowrap' }}>
                    <span className={'chip ' + st.chip} style={{ fontSize: 10.5 }}>{st.label}</span>
                    {s.basis === 'paper' && s.status !== 'never' && s.status !== 'skipped' && (
                      <div style={{ fontSize: 9.5, color: 'var(--text-4)', marginTop: 3 }} title="No real position: tracked against price candles only">paper</div>
                    )}
                  </td>
                  <td style={{ ...td, lineHeight: 1.55, color: 'var(--text-2)' }}>{s.text}</td>
                  <td className="mono" style={{ ...td, textAlign: 'right', whiteSpace: 'nowrap', fontWeight: 600, color: toneColor[s.tone] }}>
                    {s.pnlPct == null ? <span style={{ color: 'var(--text-4)', fontWeight: 400 }}>–</span> : (s.pnlPct > 0 ? '+' : s.pnlPct < 0 ? '−' : '') + Math.abs(s.pnlPct).toFixed(2) + '%'}
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>

      {pages > 1 && (
        <div style={{ display: 'flex', gap: 8, alignItems: 'center', justifyContent: 'flex-end', marginTop: 10, fontSize: 11, color: 'var(--text-3)' }}>
          <button disabled={safe === 0} onClick={() => setPage(safe - 1)} style={{ ...sel, opacity: safe === 0 ? 0.4 : 1 }}>‹ Prev</button>
          <span>{safe + 1} / {pages}</span>
          <button disabled={safe >= pages - 1} onClick={() => setPage(safe + 1)} style={{ ...sel, opacity: safe >= pages - 1 ? 0.4 : 1 }}>Next ›</button>
        </div>
      )}
      <div style={{ marginTop: 10, fontSize: 10.5, color: 'var(--text-4)', lineHeight: 1.5 }}>
        "Result" is the move from the entry price to now (open) or to the exit (closed), before fees. "Paper" means no real position was held: it is how the trade would have gone from the candles. History shows the most recent 200 closed trades in the chosen period.
      </div>
    </div>
  );
}

Object.assign(window, { TradeStoriesTable });
