// Vantage — Build 4: Research (the dossier).
// Zero-to-informed on one company: type a symbol, walk six questions a real
// investor asks, each ending in a plain-language takeaway — then drop into
// the decision journal with the dossier's facts prefilled as assumptions and
// risks. The spine is SEC EDGAR (official, keyless); Yahoo garnish is labeled
// and optional. Every section degrades to absence, never to invention.

const VG_DOSSIER_STEPS = [
  ['business', '1 · what does this company do?'],
  ['earnings', '2 · what do the official numbers say?'],
  ['filings', '3 · what have they filed?'],
  ['targets', '4 · do they hit their targets?'],
  ['context', '5 · how does it sit vs its sector?'],
  ['price', '6 · what does price history say?'],
];

function VgDossierMoney(v) {
  if (v == null) return '—';
  const a = Math.abs(v);
  return a >= 1e12 ? `$${(v / 1e12).toFixed(2)}T` : a >= 1e9 ? `$${(v / 1e9).toFixed(1)}B`
    : a >= 1e6 ? `$${(v / 1e6).toFixed(0)}M` : `$${Math.round(v).toLocaleString()}`;
}

// Tiny column chart for XBRL series — hand-rolled like every chart here.
function VgFactBars({ rows, label }) {
  if (!rows?.length) return null;
  const vals = rows.map(r => r.val);
  const max = Math.max(...vals.map(Math.abs));
  if (!max) return null;
  return (
    <div style={{ minWidth: 0 }}>
      <div style={{ ...vgS.caps, marginBottom: 5 }}>{label}</div>
      <div style={{ display: 'flex', gap: 4, alignItems: 'flex-end', height: 54 }}>
        {rows.map(r => (
          <div key={r.end} title={`${r.end} · ${VgDossierMoney(r.val)}`} style={{
            flex: 1, minWidth: 8, borderRadius: 3,
            height: `${Math.max(5, Math.abs(r.val) / max * 100)}%`,
            background: r.val >= 0 ? VG.accent + '99' : VG.down + '99',
            alignSelf: r.val >= 0 ? 'flex-end' : 'flex-end',
          }} />
        ))}
      </div>
      <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 9.5, color: VG.ink4, marginTop: 3 }}>
        <span>{rows[0].end.slice(0, 7)}</span>
        <span>{rows[rows.length - 1].end.slice(0, 7)} · {VgDossierMoney(rows[rows.length - 1].val)}</span>
      </div>
    </div>
  );
}

function VgDossierSection({ step, title, section, children }) {
  if (!section) return null;
  return (
    <section style={{ background: VG.tile, borderRadius: 18, padding: '15px 18px', marginBottom: 10 }}>
      <div style={{ ...vgS.caps, marginBottom: 8 }}>{title}</div>
      {children}
      {section.takeaway && <VgBlurb text={section.takeaway} />}
    </section>
  );
}

function VantageResearch({ quotes, onRefresh, initialSymbol, onConsumedInitial, watchlist = [], onWatchChanged }) {
  const [input, setInput] = React.useState(initialSymbol || '');
  const [symbol, setSymbol] = React.useState(null);
  const [state, setState] = React.useState('idle'); // idle | loading | done | error
  const [data, setData] = React.useState(null);
  const [chart, setChart] = React.useState(null);    // { closes } for the price line — own-price-layer, degrades to null
  const [deciding, setDeciding] = React.useState(false);
  const [reader, setReader] = React.useState(null);  // the filing reader: {loading}|{error}|{items,text,…}
  const [crowd, setCrowd] = React.useState(null);    // positioning — its own layer, degrades alone

  const openFiling = f => {
    setReader({ loading: true, form: f.form, date: f.date });
    vgGet(`/vantage/api/filing-doc?url=${encodeURIComponent(f.url)}`)
      .then(d => setReader({ ...d, form: f.form, date: f.date }))
      .catch(e => setReader({ error: e.message, form: f.form, date: f.date }));
  };

  const lookUp = sym => {
    const s = String(sym || '').toUpperCase().trim();
    if (!/^[A-Z0-9.-]{1,12}$/.test(s)) return;
    setSymbol(s); setState('loading'); setData(null); setChart(null); setReader(null); setCrowd(null);
    vgGet(`/vantage/api/dossier?symbol=${encodeURIComponent(s)}`)
      .then(d => { setData(d); setState('done'); })
      .catch(() => setState('error'));
    // The price line rides the owned price layer independently — a dark dossier
    // arm doesn't blank the chart, and a dark chart doesn't blank the dossier.
    vgGet(`/vantage/api/chart?symbol=${encodeURIComponent(s)}&range=6mo`)
      .then(setChart).catch(() => setChart(null));
    vgGet(`/vantage/api/crowding?symbol=${encodeURIComponent(s)}`)
      .then(setCrowd).catch(() => setCrowd(null));
  };

  // The globe (or any other tab) can hand a symbol in.
  React.useEffect(() => {
    if (initialSymbol) { setInput(initialSymbol); lookUp(initialSymbol); onConsumedInitial?.(); }
  }, [initialSymbol]);

  const d = data?.dossier;
  const s = d?.sections;

  return (
    <React.Fragment>
      <section style={{ background: VG.tile, borderRadius: 18, padding: '16px 18px', marginBottom: 12 }}>
        <div style={{ ...vgS.caps, marginBottom: 8 }}>research · zero to informed on one company</div>
        <form onSubmit={e => { e.preventDefault(); lookUp(input); }} style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
          <VgInput value={input} onChange={e => setInput(e.target.value)} placeholder="type a symbol — NVDA, KO, DE…"
            style={{ width: 220, textTransform: 'uppercase' }} autoFocus />
          <VgBtn kind="primary" type="submit" disabled={!input.trim() || state === 'loading'}>open the dossier</VgBtn>
          {state === 'done' && d && !d.complete && (
            <span style={{ fontSize: 11.5, color: VG.ink3, alignSelf: 'center' }}>partial dossier — some arms unreachable</span>
          )}
        </form>
        {state === 'idle' && (
          <div style={{ fontSize: 12.5, color: VG.ink3, marginTop: 10, lineHeight: 1.55 }}>
            six questions, each with an honest answer from official filings where possible:
            what they do → the real numbers → the filing trail → the beat record → sector context → price character.
            It ends where research should: a recorded, reviewable decision.
          </div>
        )}
      </section>

      {state === 'loading' && <div style={{ ...vgS.serif, color: VG.ink3, fontSize: 15, padding: '8px 2px' }}>pulling the filings for {symbol}…</div>}
      {state === 'error' && <div style={{ color: VG.ink3, fontSize: 12.5 }}>dossier service unreachable — it returns when the network does.</div>}

      {state === 'done' && d && (
        <React.Fragment>
          <div style={{ display: 'flex', gap: 10, alignItems: 'baseline', flexWrap: 'wrap', margin: '2px 2px 12px' }}>
            <span style={{ ...vgS.serif, fontSize: 24, color: VG.ink }}>{d.name}</span>
            <span style={{ ...vgS.num, fontSize: 12, color: VG.ink3 }}>{d.symbol}</span>
            {!data.cikFound && <VgTag color={VG.accent2}>no SEC filings found — foreign listing or fund?</VgTag>}
            {d.sources.note && <span style={{ fontSize: 11.5, color: '#fb923c' }}>{d.sources.note}</span>}
          </div>

          {[s.business, s.earnings, s.filings, s.targets, s.context, s.price].every(x => !x) && (
            <div style={{ color: VG.ink3, fontSize: 12.5, padding: '12px 2px' }}>
              nothing reachable for {d.symbol} right now — EDGAR and Yahoo both came back empty. Try again shortly.
            </div>
          )}

          <VgDossierSection title={VG_DOSSIER_STEPS[0][1]} section={s.business}>
            {s.business?.summary && (
              <p style={{ fontSize: 12.5, color: VG.ink2, lineHeight: 1.6, margin: '0 0 4px' }}>{s.business.summary}</p>
            )}
            <div style={{ display: 'flex', gap: 14, flexWrap: 'wrap', fontSize: 11.5, color: VG.ink3 }}>
              {s.business?.exchange && <span>{s.business.exchange}</span>}
              {s.business?.sic && <span>SEC class: {s.business.sic}</span>}
              {s.business?.website && <a href={s.business.website} target="_blank" rel="noreferrer" style={{ color: VG.ink3 }}>{s.business.website.replace(/^https?:\/\//, '')}</a>}
            </div>
          </VgDossierSection>

          <VgDossierSection title={VG_DOSSIER_STEPS[1][1]} section={s.earnings}>
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: 16, marginBottom: 4 }}>
              <VgFactBars rows={s.earnings?.revenue?.annual} label={`revenue by fiscal year · xbrl ${s.earnings?.revenue?.tag || ''}`} />
              <VgFactBars rows={s.earnings?.revenue?.quarterly} label="revenue by quarter" />
              <VgFactBars rows={s.earnings?.netIncome?.annual} label="net income by fiscal year" />
            </div>
          </VgDossierSection>

          <VgDossierSection title={VG_DOSSIER_STEPS[2][1]} section={s.filings}>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 4, marginBottom: 4 }}>
              {(s.filings?.list || []).slice(0, 8).map((f, i) => (
                <div key={i} style={{ display: 'grid', gridTemplateColumns: '70px 90px 1fr auto', gap: 10, fontSize: 12, alignItems: 'baseline' }}>
                  <span style={{ fontWeight: 600, color: VG.ink }}>{f.form}</span>
                  <span style={{ ...vgS.num, color: VG.ink4 }}>{f.date}</span>
                  {f.url
                    ? <a href={f.url} target="_blank" rel="noreferrer" style={{ color: VG.ink3, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                        {f.items ? `items ${f.items}` : 'document'} ↗</a>
                    : <span style={{ color: VG.ink4 }}>{f.items ? `items ${f.items}` : ''}</span>}
                  {f.url ? (
                    <button className="vg-chip" onClick={() => openFiling(f)} style={{
                      appearance: 'none', border: 0, cursor: 'pointer', borderRadius: 999,
                      padding: '2px 11px', fontSize: 10.5, fontWeight: 600, background: VG.chip, color: VG.ink2,
                    }}>read here</button>
                  ) : <span />}
                </div>
              ))}
            </div>
            {reader && (
              <div style={{ borderTop: `1px solid ${VG.rule}`, marginTop: 10, paddingTop: 10 }}>
                <div style={{ display: 'flex', alignItems: 'baseline', gap: 10, marginBottom: 8 }}>
                  <span style={{ ...vgS.caps, color: VG.accent2 }}>reading · {reader.form} · {reader.date}{reader.pdf ? ' · pdf' : ''}</span>
                  <span style={{ flex: 1 }} />
                  <VgBtn small onClick={() => setReader(null)}>close</VgBtn>
                </div>
                {reader.loading && <div style={{ ...vgS.serif, color: VG.ink3, fontSize: 14 }}>pulling the document from EDGAR…</div>}
                {reader.error && <div style={{ color: VG.ink3, fontSize: 12.5 }}>document unreadable — {reader.error}</div>}
                {reader.items?.length > 0 && (
                  <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                    {reader.items.map((it, i) => (
                      <div key={i}>
                        <div style={{ ...vgS.caps, color: VG.accent2, marginBottom: 3 }}>
                          item {it.code}{it.meaning ? ` · ${it.meaning}` : ''}
                        </div>
                        <div style={{ fontSize: 12, color: VG.ink2, lineHeight: 1.55 }}>{it.excerpt}</div>
                      </div>
                    ))}
                  </div>
                )}
                {reader.items && reader.items.length === 0 && reader.text && (
                  <div style={{ maxHeight: 320, overflow: 'auto', whiteSpace: 'pre-wrap', fontSize: 12, color: VG.ink2, lineHeight: 1.55, background: VG.chip, borderRadius: 10, padding: '10px 12px' }}>
                    {reader.text}
                  </div>
                )}
                {reader.chars > 16000 && (
                  <div style={{ fontSize: 10.5, color: VG.ink4, marginTop: 6 }}>
                    showing the structure and first ~16k characters of {reader.chars.toLocaleString()} — the full document is one click up.
                  </div>
                )}
              </div>
            )}
          </VgDossierSection>

          <VgDossierSection title={VG_DOSSIER_STEPS[3][1]} section={s.targets}>
            <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginBottom: 4 }}>
              {(s.targets?.rows || []).map((r, i) => (
                <span key={i} style={{
                  background: VG.chip, borderRadius: 999, padding: '4px 11px', fontSize: 11.5,
                  color: r.actual > r.estimate ? VG.up : r.actual < r.estimate ? VG.down : VG.ink3,
                }} title={`actual ${r.actual} vs est ${r.estimate}`}>
                  {r.period || 'q'} · {r.actual > r.estimate ? 'beat' : r.actual < r.estimate ? 'miss' : 'inline'}
                  {r.surprisePct != null ? ` ${(r.surprisePct * 100).toFixed(0)}%` : ''}
                </span>
              ))}
            </div>
          </VgDossierSection>

          <VgDossierSection title={VG_DOSSIER_STEPS[4][1]} section={s.context}>
            {s.context?.symPct != null && (
              <div style={{ display: 'flex', gap: 14, flexWrap: 'wrap', fontSize: 12, color: VG.ink2, marginBottom: 4 }}>
                <span>{d.symbol} <b style={{ color: vgDelta(s.context.symPct) }}>{vgPct(s.context.symPct)}</b></span>
                <span>{s.context.etf} <b style={{ color: vgDelta(s.context.etfPct) }}>{vgPct(s.context.etfPct)}</b></span>
                {s.context.spyPct != null && <span>S&P <b style={{ color: vgDelta(s.context.spyPct) }}>{vgPct(s.context.spyPct)}</b></span>}
                <span style={{ color: VG.ink4 }}>6 months</span>
              </div>
            )}
          </VgDossierSection>

          {data.yourNotes?.length > 0 && (
            <section style={{ background: VG.tile, borderRadius: 18, padding: '15px 18px', marginBottom: 10, borderLeft: `2px solid ${VG.accent2}` }}>
              <div style={{ ...vgS.caps, marginBottom: 8 }}>in your own words · from your vault</div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                {data.yourNotes.map((n, i) => (
                  <div key={i}>
                    <div style={{ display: 'flex', gap: 10, alignItems: 'baseline', marginBottom: 3 }}>
                      <span style={{ fontSize: 12.5, color: VG.ink, fontWeight: 600 }}>{n.title}</span>
                      {n.linked && <span style={{ ...vgS.caps, color: VG.accent2 }} title={`this note wikilinks [[${d.symbol}]]`}>linked</span>}
                      <span style={{ ...vgS.num, fontSize: 10.5, color: VG.ink4 }}>{String(n.at).slice(0, 10)}</span>
                    </div>
                    <div style={{ fontSize: 12, color: VG.ink2, lineHeight: 1.55, whiteSpace: 'pre-wrap' }}>{n.excerpt}</div>
                  </div>
                ))}
              </div>
              <div style={{ fontSize: 10.5, color: VG.ink4, marginTop: 8 }}>
                research starts from what you already thought — reread yourself before the market rereads you.
              </div>
            </section>
          )}

          {(s.price || chart?.closes?.length > 1) && (
            <section style={{ background: VG.tile, borderRadius: 18, padding: '15px 18px', marginBottom: 10 }}>
              <div style={{ ...vgS.caps, marginBottom: 8 }}>{VG_DOSSIER_STEPS[5][1]}</div>
              {chart?.closes?.length > 1 ? (
                <div style={{ marginBottom: s.price ? 12 : 2 }}>
                  <VgLine series={[chart.closes]} colors={[VG.accent]} w={560} h={92} />
                  <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 10, color: VG.ink4, marginTop: 2 }}>
                    <span>{chart.closes.length} sessions · {chart.range || '6mo'}</span>
                    <span style={vgS.num}>{vgMoney(chart.closes[chart.closes.length - 1])}</span>
                  </div>
                </div>
              ) : (
                s.price && <div style={{ fontSize: 10.5, color: VG.ink4, marginBottom: 8 }}>price history unreachable — the read below stands on its own.</div>
              )}
              <div style={{ display: 'flex', flexDirection: 'column', gap: 4, fontSize: 12, color: VG.ink2, lineHeight: 1.5 }}>
                {s.price?.character && <span>{s.price.character}</span>}
                {s.price?.seasonal && <span>{s.price.seasonal}</span>}
                {s.price?.expectedMove && <span>{s.price.expectedMove}</span>}
              </div>
              {s.price?.takeaway && <VgBlurb text={s.price.takeaway} />}
            </section>
          )}

          {/* The crowd: is this trade already everyone's trade? Positioning is
              its own layer — either side can be dark without taking the other. */}
          {crowd && (crowd.shorts || crowd.skew) && (
            <section style={{ background: VG.tile, borderRadius: 18, padding: '15px 18px', marginBottom: 10 }}>
              <div style={{ ...vgS.caps, marginBottom: 8 }}>the crowd · positioning around this name</div>
              {crowd.read && (
                <p style={{ ...vgS.serif, fontSize: 14.5, color: VG.ink2, lineHeight: 1.55, margin: '0 0 8px' }}>{crowd.read}.</p>
              )}
              <div style={{ display: 'flex', gap: 14, flexWrap: 'wrap', fontSize: 11.5, color: VG.ink3 }}>
                {crowd.shorts ? (
                  <span>
                    short interest{crowd.shorts.pctFloat != null ? ` ${(crowd.shorts.pctFloat * 100).toFixed(1)}% of float` : ''}
                    {crowd.shorts.band ? ` (${crowd.shorts.band})` : ''}
                    <span style={{ color: VG.ink4 }}> · twice-monthly settlement data</span>
                  </span>
                ) : (
                  <span style={{ color: VG.ink4 }}>short interest unreachable for this name.</span>
                )}
                {crowd.skew ? (
                  <span style={vgS.num}>
                    wings: put {crowd.skew.put.strike} iv {(crowd.skew.put.iv * 100).toFixed(0)}% · call {crowd.skew.call.strike} iv {(crowd.skew.call.iv * 100).toFixed(0)}%
                  </span>
                ) : (
                  <span style={{ color: VG.ink4 }}>options chain dark — skew unknown.</span>
                )}
              </div>
            </section>
          )}

          <section style={{
            background: VG.tile, borderRadius: 18, padding: '15px 18px', marginBottom: 14,
            borderLeft: `2px solid ${VG.accent}`,
          }}>
            <div style={{ ...vgS.caps, marginBottom: 6 }}>the verdict is yours</div>
            <div style={{ fontSize: 12.5, color: VG.ink2, lineHeight: 1.55, marginBottom: 10 }}>
              You've seen what they do, the official numbers, the filing trail, the beat record, the sector
              context, and the price character. Research that doesn't end in a falsifiable position is trivia —
              record the call and Vantage will hold you to it at 30/60/90 days.
            </div>
            <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap' }}>
              <VgBtn kind="primary" onClick={() => setDeciding(true)}>record a decision on {d.symbol} →</VgBtn>
              {watchlist.some(w => w.symbol === d.symbol) ? (
                <VgBtn onClick={() => vgSend(`/vantage/api/watchlist/${d.symbol}`, 'DELETE').then(onWatchChanged).catch(() => {})}>
                  ✓ watching — stop
                </VgBtn>
              ) : (
                <VgBtn onClick={() => vgSend('/vantage/api/watchlist', 'POST', { symbol: d.symbol, note: 'from dossier' }).then(onWatchChanged).catch(() => {})}>
                  ☆ track without buying
                </VgBtn>
              )}
            </div>
            {(d.journalPrefill.assumptions.length > 0 || d.journalPrefill.risks.length > 0) && (
              <div style={{ fontSize: 10.5, color: VG.ink4, marginTop: 8 }}>
                the form arrives with the dossier's facts prefilled as editable assumptions & risks — delete what you don't believe.
              </div>
            )}
          </section>

          {deciding && (
            <VgModal title={`Record a decision · ${d.symbol}`} onClose={() => setDeciding(false)} width={560}>
              <VgDecisionForm quotes={quotes}
                initial={{ symbol: d.symbol, assumptions: d.journalPrefill.assumptions, risks: d.journalPrefill.risks }}
                onClose={() => setDeciding(false)}
                onDone={() => { setDeciding(false); onRefresh(); }} />
            </VgModal>
          )}
        </React.Fragment>
      )}
    </React.Fragment>
  );
}

window.VantageResearch = VantageResearch;
