// TickerContext — single-glance "what does the team think about $X" modal.
//
// Opens whenever a ticker chip is clicked anywhere in the app. Aggregates:
//   - Position info (if held — qty, mark, P&L, sizing)
//   - Last 5 persona memos mentioning the ticker (verdict + role chips)
//   - Last 5 twitter signals about it (matched keywords + handle)
//   - Inline "Fire <persona>" buttons to wake the team on this name
//   - Link to the deep dive note in 4-Stocks/Deep Dives/$XXX.md
//
// Designed for the info-bias trader: when a tweet pops about NVDA, this
// is the one click that surfaces "what's the standing read, and is what
// I'm seeing news or noise the team has already chewed on?".

const { useState: tcUseState, useEffect: tcUseEffect, useCallback: tcUseCallback } = React;

const TC_ROLE_META = {
  'phd-researcher':                { label: 'PhD',           color: '#8db4d8' },
  'hedging-specialist':            { label: 'Hedging',       color: '#d96a6a' },
  'framework-portfolio-modeling':  { label: 'Sizing',        color: '#5fb37c' },
  'framework-fundamentals':        { label: 'Fundamentals',  color: '#d9a85f' },
  'framework-value-investing':     { label: 'Value',         color: '#b48dd8' },
  'framework-growth-investing':    { label: 'Growth',        color: '#7fc7d9' },
  'framework-mental-models':       { label: 'Mental',        color: '#d8a07f' },
  'managing-director':             { label: 'MD',            color: '#ffffff' },
  'jarvis':                        { label: 'Tibeb',         color: 'var(--accent)' },
  'editor-jarvis':                 { label: 'Editor',        color: 'var(--accent)' },
  'regime-watcher':                { label: 'Regime',        color: '#ff9c5e' },
  'promotion-proposer':            { label: 'Promote',       color: '#5fd9b3' },
};

// Personas worth firing-on-demand for a ticker question
const TC_FIRE_TARGETS = [
  { role: 'phd-researcher',                label: 'PhD scan' },
  { role: 'framework-portfolio-modeling',  label: 'Sizing read' },
  { role: 'hedging-specialist',            label: 'Hedge check' },
  { role: 'framework-fundamentals',        label: 'Fundamentals' },
];

function TickerContext({ ticker, onClose }) {
  if (!ticker) return null;
  const T = ticker.replace(/^\$/, '').toUpperCase();
  const [memos, setMemos] = tcUseState([]);
  const [signals, setSignals] = tcUseState([]);
  const [position, setPosition] = tcUseState(null);
  const [loading, setLoading] = tcUseState(true);
  const [err, setErr] = tcUseState('');
  const [firing, setFiring] = tcUseState({});  // role → bool
  const [fireMsg, setFireMsg] = tcUseState({}); // role → string

  const load = tcUseCallback(async () => {
    setLoading(true);
    setErr('');
    try {
      const [memosR, sigR, pfR] = await Promise.all([
        fetch(`/api/personas/memos?ticker=${encodeURIComponent(T)}&limit=8`).catch(() => null),
        fetch(`/api/twitter/signals?limit=50`).catch(() => null),
        fetch(`/api/portfolio`).catch(() => null),
      ]);
      if (memosR?.ok) {
        const j = await memosR.json();
        setMemos(j.memos || []);
      }
      if (sigR?.ok) {
        const j = await sigR.json();
        // Filter signals to those mentioning the ticker (case-insensitive
        // text scan; the server's tweet text is what the user wants)
        const tickerRe = new RegExp(`\\b\\$?${T}\\b`, 'i');
        const filtered = (j.signals || []).filter(s => tickerRe.test(s.text || ''));
        setSignals(filtered.slice(0, 8));
      }
      if (pfR?.ok) {
        const j = await pfR.json();
        const pos = (j.equities || []).concat(j.options || []).find(p =>
          (p.ticker || '').toUpperCase() === T
        );
        setPosition(pos || null);
      }
    } catch (e) {
      setErr(String(e.message || e));
    } finally {
      setLoading(false);
    }
  }, [T]);

  tcUseEffect(() => { load(); }, [load]);

  const fire = tcUseCallback(async (role) => {
    if (firing[role]) return;
    setFiring(f => ({ ...f, [role]: true }));
    setFireMsg(m => ({ ...m, [role]: 'firing…' }));
    try {
      const r = await fetch(`/api/personas/${encodeURIComponent(role)}/fire`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          topic: `Quick read on $${T}: what's the standing thesis, what's changed in the last week, and what's the one trigger I should watch for next?`,
          trigger: 'ticker-drilldown',
          user_data: { ticker: T },
        }),
      });
      if (!r.ok) {
        const t = await r.text();
        throw new Error(`HTTP ${r.status}: ${t.slice(0, 80)}`);
      }
      setFireMsg(m => ({ ...m, [role]: 'queued · 30-60s' }));
      // Re-load after 35s + 70s to catch the new memo
      setTimeout(load, 35_000);
      setTimeout(load, 70_000);
    } catch (e) {
      setFireMsg(m => ({ ...m, [role]: `failed: ${e.message}` }));
    } finally {
      setFiring(f => ({ ...f, [role]: false }));
      setTimeout(() => setFireMsg(m => ({ ...m, [role]: '' })), 8000);
    }
  }, [firing, T, load]);

  return (
    <div style={{
      position: 'fixed', inset: 0, zIndex: 110,
      background: 'rgba(10,10,12,0.85)', backdropFilter: 'blur(8px)',
      display: 'flex', alignItems: 'flex-start', justifyContent: 'center',
      padding: '40px 20px',
    }} onClick={onClose}>
      <div onClick={e => e.stopPropagation()} style={{
        width: '100%', maxWidth: 800, maxHeight: 'calc(100vh - 80px)', overflowY: 'auto',
        background: 'var(--bg)', border: '1px solid var(--line-2)',
        borderRadius: 6, padding: 20, fontFamily: 'var(--font-body)',
      }}>
        {/* Header */}
        <div style={{
          display: 'flex', alignItems: 'baseline', gap: 12,
          paddingBottom: 12, marginBottom: 14, borderBottom: '1px solid var(--line)',
        }}>
          <span style={{
            fontFamily: "'JetBrains Mono', monospace",
            fontSize: 26, fontWeight: 700, color: 'var(--accent)',
          }}>${T}</span>
          <span style={{
            fontSize: 11, letterSpacing: '0.18em', textTransform: 'uppercase',
            color: 'var(--text-dim)',
          }}>
            team context
          </span>
          <button onClick={load} disabled={loading} style={{
            marginLeft: 'auto',
            padding: '4px 10px', fontSize: 10, fontFamily: "'JetBrains Mono', monospace",
            background: 'transparent', color: 'var(--text-2)',
            border: '1px solid var(--line)', borderRadius: 3, cursor: 'pointer',
          }}>↻</button>
          <button onClick={onClose} style={{
            padding: '4px 10px', fontSize: 10, fontFamily: "'JetBrains Mono', monospace",
            background: 'transparent', color: 'var(--text-dim)',
            border: '1px solid var(--line)', borderRadius: 3, cursor: 'pointer',
          }}>close</button>
        </div>

        {err && (
          <div style={{
            padding: 10, marginBottom: 12, fontSize: 11,
            background: 'rgba(217,106,106,0.12)', color: '#d96a6a',
            border: '1px solid rgba(217,106,106,0.4)', borderRadius: 4,
          }}>{err}</div>
        )}

        {/* Position summary */}
        {position && (
          <div style={{
            marginBottom: 14, padding: '10px 12px',
            background: 'var(--bg-2)', border: '1px solid var(--line)',
            borderRadius: 3,
          }}>
            <div style={{
              fontSize: 9, letterSpacing: '0.18em', textTransform: 'uppercase',
              color: 'var(--text-dim)', marginBottom: 6, fontWeight: 700,
            }}>position · in book</div>
            <div style={{
              display: 'flex', gap: 16, alignItems: 'baseline',
              fontFamily: "'JetBrains Mono', monospace", fontSize: 12,
            }}>
              <span><span style={{ color: 'var(--text-dim)' }}>qty</span> {position.qty}</span>
              <span><span style={{ color: 'var(--text-dim)' }}>cost</span> ${position.avg_cost?.toFixed?.(2)}</span>
              <span><span style={{ color: 'var(--text-dim)' }}>mark</span> ${position.last_price?.toFixed?.(2)}</span>
              <span style={{
                color: (position.unrealized_pnl ?? 0) >= 0 ? '#5fb37c' : '#d96a6a',
                fontWeight: 700,
              }}>
                {(position.unrealized_pnl ?? 0) >= 0 ? '+' : ''}
                ${(position.unrealized_pnl ?? 0).toLocaleString()}
                {position.unrealized_pct != null && (
                  <span style={{ marginLeft: 4, opacity: 0.85 }}>
                    ({position.unrealized_pct >= 0 ? '+' : ''}{position.unrealized_pct.toFixed(1)}%)
                  </span>
                )}
              </span>
              <span style={{ marginLeft: 'auto', color: 'var(--text-dim)' }}>
                MV ${position.market_value?.toLocaleString?.()}
              </span>
            </div>
          </div>
        )}
        {!position && !loading && (
          <div style={{
            marginBottom: 14, padding: '8px 12px', fontSize: 11,
            color: 'var(--text-dim)', fontStyle: 'italic',
            background: 'var(--bg-3)', border: '1px dashed var(--line)',
            borderRadius: 3,
          }}>
            Not in the book. View as research target.
          </div>
        )}

        {/* Fire actions */}
        <div style={{
          marginBottom: 14, padding: '10px 12px',
          background: 'var(--bg-2)', border: '1px solid var(--line)',
          borderRadius: 3,
        }}>
          <div style={{
            fontSize: 9, letterSpacing: '0.18em', textTransform: 'uppercase',
            color: 'var(--text-dim)', marginBottom: 6, fontWeight: 700,
          }}>ask the team</div>
          <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
            {TC_FIRE_TARGETS.map(t => {
              const meta = TC_ROLE_META[t.role];
              const f = firing[t.role];
              const msg = fireMsg[t.role];
              return (
                <div key={t.role} style={{ display: 'inline-flex', flexDirection: 'column' }}>
                  <button
                    onClick={() => fire(t.role)}
                    disabled={f}
                    title={`Fires ${meta?.label || t.role} on a ${T}-specific question. Memo lands in 30-60s.`}
                    style={{
                      padding: '4px 10px', fontSize: 10,
                      fontFamily: "'JetBrains Mono', monospace",
                      background: f ? 'transparent' : (meta?.color + '22' || 'transparent'),
                      color: meta?.color || 'var(--text)',
                      border: '1px solid ' + (meta?.color + '55' || 'var(--line)'),
                      borderRadius: 3,
                      cursor: f ? 'wait' : 'pointer',
                    }}
                  >
                    {f ? '… ' : '↻ '}{t.label}
                  </button>
                  {msg && (
                    <span style={{
                      fontSize: 8, color: msg.startsWith('failed') ? '#d96a6a' : '#5fb37c',
                      marginTop: 2, fontFamily: "'JetBrains Mono', monospace",
                    }}>{msg}</span>
                  )}
                </div>
              );
            })}
          </div>
        </div>

        {/* Memos — newest first */}
        <div style={{ marginBottom: 14 }}>
          <div style={{
            fontSize: 9, letterSpacing: '0.18em', textTransform: 'uppercase',
            color: 'var(--accent)', marginBottom: 8, fontWeight: 700,
          }}>
            team's recent reads · {memos.length}
          </div>
          {memos.length === 0 && !loading && (
            <div style={{ fontSize: 11, color: 'var(--text-dim)', fontStyle: 'italic', padding: 8 }}>
              No memos mention ${T} yet. Fire one of the team above.
            </div>
          )}
          {memos.map(m => {
            const roleMeta = TC_ROLE_META[m.role] || { label: m.role, color: 'var(--text)' };
            const ts = new Date(m.ts).toLocaleString(undefined, {
              month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit',
            });
            return (
              <div key={m.path} style={{
                marginBottom: 6, padding: '8px 10px',
                background: 'var(--bg-2)',
                borderLeft: `3px solid ${roleMeta.color}`,
                border: '1px solid var(--line)',
                borderRadius: 3,
              }}>
                <div style={{ display: 'flex', gap: 8, alignItems: 'baseline', marginBottom: 3 }}>
                  <span style={{
                    fontSize: 9, letterSpacing: '0.14em', color: roleMeta.color,
                    fontWeight: 700, fontFamily: "'JetBrains Mono', monospace",
                    textTransform: 'uppercase',
                  }}>{roleMeta.label}</span>
                  <span style={{
                    fontSize: 8, padding: '1px 6px',
                    color: 'var(--text-dim)',
                    background: 'rgba(255,255,255,0.04)',
                    border: '1px solid var(--line)', borderRadius: 2,
                    letterSpacing: '0.14em', textTransform: 'uppercase',
                    fontFamily: "'JetBrains Mono', monospace",
                  }}>{m.source || 'cron'}</span>
                  {m.verdict && (
                    <span style={{
                      fontSize: 9, padding: '1px 6px',
                      color: 'var(--text)',
                      background: 'rgba(255,255,255,0.06)',
                      border: '1px solid var(--line-2)', borderRadius: 2,
                      fontFamily: "'JetBrains Mono', monospace", fontWeight: 600,
                    }}>verdict: {m.verdict}</span>
                  )}
                  <span style={{
                    marginLeft: 'auto', fontSize: 9, color: 'var(--text-dim)',
                    fontFamily: "'JetBrains Mono', monospace",
                  }}>{ts}</span>
                </div>
                <div style={{ fontSize: 11, color: 'var(--text)', lineHeight: 1.4, marginBottom: 4 }}>
                  {m.topic}
                </div>
                {m.excerpt && (
                  <div style={{
                    fontSize: 10, color: 'var(--text-2)', lineHeight: 1.5,
                    fontStyle: 'italic',
                  }}>
                    {m.excerpt}
                  </div>
                )}
              </div>
            );
          })}
        </div>

        {/* Twitter signals */}
        {signals.length > 0 && (
          <div>
            <div style={{
              fontSize: 9, letterSpacing: '0.18em', textTransform: 'uppercase',
              color: '#5fb3d9', marginBottom: 8, fontWeight: 700,
            }}>
              twitter mentions · {signals.length}
            </div>
            {signals.map(s => {
              const ts = new Date(s.created || s.fired_at || s.posted_at).toLocaleString(undefined, {
                month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit',
              });
              return (
                <div key={s.tweet_id} style={{
                  marginBottom: 6, padding: '8px 10px',
                  background: 'rgba(95,179,217,0.04)',
                  borderLeft: `3px solid #5fb3d9`,
                  border: '1px solid var(--line)',
                  borderRadius: 3,
                }}>
                  <div style={{ display: 'flex', gap: 8, alignItems: 'baseline', marginBottom: 3 }}>
                    <span style={{
                      fontSize: 10, color: '#5fb3d9', fontWeight: 700,
                      fontFamily: "'JetBrains Mono', monospace",
                    }}>@{s.handle}</span>
                    <span style={{ fontSize: 9, color: 'var(--text-dim)' }}>♥ {s.engagement}</span>
                    <span style={{
                      marginLeft: 'auto', fontSize: 9, color: 'var(--text-dim)',
                      fontFamily: "'JetBrains Mono', monospace",
                    }}>{ts}</span>
                  </div>
                  <div style={{
                    fontSize: 10, color: 'var(--text-2)', lineHeight: 1.4,
                    fontStyle: 'italic',
                  }}>
                    {(s.text || '').slice(0, 240)}{(s.text || '').length > 240 ? '…' : ''}
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </div>
    </div>
  );
}

window.TickerContext = TickerContext;

// Global open helper — anything that wants to surface a ticker can call
// window.openTickerContext("NVDA"). The app.jsx mounts the modal once
// and listens for the event. Avoids prop-drilling through the tree.
window.openTickerContext = function (ticker) {
  if (!ticker) return;
  window.dispatchEvent(new CustomEvent('tibeb:ticker', { detail: { ticker } }));
};
