/* ============================================================
   radar-cards.jsx -- AlertCard (+ news/enrichment) and UniverseTable
   Depends on radar-core.jsx globals.
   Exposes: AlertCard, UniverseTable
   ============================================================ */
const { useState: useStateK, useMemo: useMemoK } = React;

const MECH_DISPLAY = { couple: 'COUPLE+', flip: 'FLIP-', watch: 'watch', stable: 'stable' };

/* -- ALERT CARD --------------------------------------------- */
function AlertCard({ row, hl, sig }) {
  const [open, setOpen] = useStateK(false);
  const h = row.hl[hl];
  const m = window.signalMeta(sig);
  const pol = row._pol || window.polarityOf(row.sym, row.cat);
  const pm = window.polarityMeta(pol);
  const mech = row._mech || window.mechanicOf(row, hl, 0.25);
  const agree = row.agree;
  return (
    <div className={`acard ${sig}`}>
      <div className="acard-top">
        <div className="acard-id">
          <div className="acard-sym">{row.sym}</div>
          <div className="acard-nm">{window.tickerName(row.sym, row.name)}</div>
          <span className="acard-cat">{row.cat}</span>
          <span className={`acard-pol pol-${pol}`} title={pm.word}>{pm.label}</span>
        </div>
        <div className="acard-badge">
          <span className={`sig-tag ${sig}`}>{m.label}</span>
          <div className="acard-onset"><span className="o-l">onset Δβ </span>{window.fmtOnset(h.onset)}</div>
          <div className="acard-mech" title="underlying mechanic (COUPLE+/FLIP-)">{MECH_DISPLAY[mech]}</div>
        </div>
      </div>

      <div className="acard-body">
        <div className="beta-block">
          <div className="bb-l">β · {hl}-day half-life</div>
          <div className="bb-flow">
            <span className="bb-then">{window.fmtB(h.ago5)}</span>
            <span className="bb-arrow">→</span>
            <span className="bb-now">{window.fmtB(h.now)}</span>
          </div>
        </div>
        <div className="spark-block">
          <div className="bb-l"><span>25-day β trend</span></div>
          <window.Sparkline series={h.series} color={m.color} height={38} />
        </div>
      </div>

      <div className="acard-move">
        <div className="move-pair">
          <div className="move-item">
            <div className="mi-l">{row.sym} · 5d</div>
            <div className={`mi-v ${row.amove >= 0 ? 'pos' : 'neg'}`}>{window.fmtPct(row.amove)}</div>
          </div>
          <div className="move-item">
            <div className="mi-l">QQQ · 5d</div>
            <div className={`mi-v ${row.qmove >= 0 ? 'pos' : 'neg'}`}>{window.fmtPct(row.qmove)}</div>
          </div>
        </div>
        <span className={`agree-badge ${agree ? 'agree' : 'diverge'}`}>{agree ? '↗ agree' : '↘ diverge'}</span>
      </div>

      {row.enrich && (
        <React.Fragment>
          <button className={`enrich-toggle${open ? ' open' : ''}`} onClick={() => setOpen((o) => !o)}>
            <span className="et-ar">▸</span> News &amp; QQQ impact
            <span className="et-n">{row.enrich.headlines ? row.enrich.headlines.length : 0} headlines</span>
          </button>
          {open && (
            <div className="enrich-body">
              {row.enrich.headlines && row.enrich.headlines.length > 0 && (
                <div className="enrich-hl">
                  {row.enrich.headlines.map((hd, i) => (
                    <a className="enrich-link" key={i} href={hd.url} target="_blank" rel="noopener noreferrer">
                      <div className="el-title">{hd.title}</div>
                      <div className="el-meta"><span className="src">{hd.source}</span> · {hd.when}</div>
                    </a>
                  ))}
                </div>
              )}
              {row.enrich.interpretation && (
                <React.Fragment>
                  <div className="enrich-read">How it reads for QQQ</div>
                  <div className="enrich-interp">{row.enrich.interpretation}</div>
                </React.Fragment>
              )}
            </div>
          )}
        </React.Fragment>
      )}
    </div>
  );
}

/* -- UNIVERSE TABLE ----------------------------------------- */
const COLS = [
  { key: 'sym', label: 'Symbol', l: true, num: false },
  { key: 'cat', label: 'Class', l: true, num: false, cls: 'u-cat-col' },
  { key: 'pol', label: 'Polarity', l: true, num: false, cls: 'u-pol-col' },
  { key: 'sig', label: 'Signal', l: true, num: false },
  { key: 'ago', label: 'β 5d ago', num: true },
  { key: 'now', label: 'β now', num: true },
  { key: 'onset', label: 'onset Δ', num: true },
  { key: 'trend', label: '25-day trend', num: false },
  { key: 'amove', label: '5d move', num: true },
  { key: 'agree', label: 'vs QQQ', num: true },
  { key: 'news', label: 'news', num: false, cls: 'u-news-col' },
];

function UniverseTable({ rows, hl, thr }) {
  const [sortKey, setSortKey] = useStateK('onset');
  const [sortDir, setSortDir] = useStateK('desc');
  const [q, setQ] = useStateK('');

  const data = useMemoK(() => rows.map((r) => {
    const h = r.hl[hl];
    return { ...r,
      _now: h.now, _ago: h.ago5, _onset: h.onset, _series: h.series,
      _sig: r._sig || window.classify(r, hl, thr),
      _pol: r._pol || window.polarityOf(r.sym, r.cat),
      _mech: r._mech || window.mechanicOf(r, hl, thr),
    };
  }), [rows, hl, thr]);

  const filtered = useMemoK(() => {
    const needle = q.trim().toLowerCase();
    let out = data;
    if (needle) out = out.filter((d) => d.sym.toLowerCase().includes(needle) || (d.name || '').toLowerCase().includes(needle) || (d.cat || '').toLowerCase().includes(needle));
    const dir = sortDir === 'asc' ? 1 : -1;
    const val = (d) => {
      switch (sortKey) {
        case 'sym': return d.sym;
        case 'cat': return d.cat;
        case 'pol': return d._pol;
        case 'sig': return ['bull', 'bear', 'watch', 'stable'].indexOf(d._sig);
        case 'ago': return d._ago;
        case 'now': return d._now;
        case 'onset': return Math.abs(d._onset);
        case 'amove': return d.amove;
        case 'agree': return d.agree ? 1 : 0;
        default: return Math.abs(d._onset);
      }
    };
    return [...out].sort((a, b) => {
      const va = val(a), vb = val(b);
      if (typeof va === 'string') return va.localeCompare(vb) * dir;
      return (va - vb) * dir;
    });
  }, [data, q, sortKey, sortDir]);

  const onSort = (k) => {
    if (k === 'trend') return;
    if (k === sortKey) setSortDir((d) => (d === 'asc' ? 'desc' : 'asc'));
    else { setSortKey(k); setSortDir(k === 'sym' || k === 'cat' || k === 'pol' ? 'asc' : 'desc'); }
  };

  return (
    <div className="uni-wrap">
      <div className="uni-tools">
        <input className="uni-search" placeholder="Filter by symbol, name, or class..." value={q} onChange={(e) => setQ(e.target.value)} />
        <span className="uni-count">{filtered.length} of {rows.length} instruments</span>
      </div>
      <div className="uni-scroll">
        <table className="uni">
          <thead>
            <tr>
              {COLS.map((c) => (
                <th key={c.key} className={`${c.l ? 'l' : ''} ${c.cls || ''}`} onClick={() => onSort(c.key)}>
                  {c.label}{sortKey === c.key && <span className="sort-ar">{sortDir === 'asc' ? '▲' : '▼'}</span>}
                </th>
              ))}
            </tr>
          </thead>
          <tbody>
            {filtered.map((d) => {
              const m = window.signalMeta(d._sig);
              const pm = window.polarityMeta(d._pol);
              return (
                <tr key={d.sym} className={d._sig}>
                  <td className="l"><span className="u-sym">{d.sym}</span> <span className="u-nm">{window.tickerName(d.sym, d.name)}</span></td>
                  <td className="l u-cat-col"><span className="u-cat">{d.cat}</span></td>
                  <td className="l u-pol-col"><span className={`u-pol pol-${d._pol}`}>{pm.label}</span></td>
                  <td className="l"><span className={`u-sig ${d._sig}`}>{m.label}</span></td>
                  <td>{window.fmtB(d._ago)}</td>
                  <td style={{ fontWeight: 700 }}>{window.fmtB(d._now)}</td>
                  <td className={d._onset >= 0 ? 'u-pos' : 'u-neg'} style={{ fontWeight: 700 }}>{window.fmtOnset(d._onset)}</td>
                  <td><window.Sparkline series={d._series} color={m.color} height={22} showDot={false} strokeW={1.6} /></td>
                  <td className={d.amove >= 0 ? 'u-pos' : 'u-neg'}>{window.fmtPct(d.amove)}</td>
                  <td>{d.agree ? '↗' : '↘'}</td>
                  <td className="u-news-col">{d.enrich ? <span className="u-news" title="Has news context">●</span> : ''}</td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    </div>
  );
}

Object.assign(window, { AlertCard, UniverseTable });
