src/blackrock/IntelligenceBrief.tsx
import {Badge,Button,Card,Heading,Table} from '@whop/react/components';
import {ArrowUpRight,Star,TrendingUp,Users,Hammer,ChartNoAxesCombined} from 'lucide-react';
import type {EconomyEnvelope,EconomyItem} from '../../shared/economy';
import {economyVerdicts} from '../../shared/economy';
import {number,time,useResource,type Entity} from './api';
import type {ResearchSection} from './navigation';
import type {ResearchActions} from './research-interactions';
import {ItemArt} from './ItemArt';
import {fillStyle} from '../lib/dither/style';
import {researchLeads} from './intelligence-model';
const itemEntity=(i:{id:number;name:string},view:Entity['view']='overview'):Entity=>({kind:'item',key:String(i.id),itemId:i.id,name:i.name,view});
const percent=(v:number|null|undefined)=>v==null?'Not available':`${v>=0?'+':''}${number(v)}%`;
export function IntelligenceBrief({result,active,onEvidence,onNavigate,onSelect,...actions}:ResearchActions&{result:EconomyEnvelope|null;active:boolean;onEvidence:()=>void;onNavigate:(s:ResearchSection)=>void;onSelect:(e:Entity)=>void}){
const demand=useResource(active?'/research/overview?sort=buyValue&days=7&offset=0':null);
const data=result?.data,leader=demand.data?.items?.find((i:any)=>Number.isFinite(i.buyValue)&&i.buyQuantity>0),leads=researchLeads(data?.items??[]);
const scope=data?`${data.basket.label} · completed ${data.periodDays}-day periods`:'Collecting tracked-basket evidence';
return <div className="intelligence-brief">
<div className="intel-scope"><Badge color={result?.delivery.freshness==='fresh'?'green':'amber'}>{result?result.delivery.freshness==='unknown'?'Freshness unknown':`${result.delivery.freshness} evidence`:'Evidence loading'}</Badge><span>{scope}</span><span>{data?`Through ${time(data.current.toExclusive)}`:'No conclusion until evidence arrives'}</span></div>
<div className="intel-question-grid">
<Card className="intel-question"><div className="intel-question-title"><TrendingUp size={18}/><h2>Are prices rising?</h2></div><strong className="intel-answer">{percent(data?.contributions.ordinaryChangePct)}</strong><p>{data?economyVerdicts[data.verdict]:'Waiting for comparable execution periods.'}</p>{data&&<div className="intel-breadth" role="img" aria-label={`${data.breadth.rising} rising, ${data.breadth.falling} falling, ${data.breadth.flat} flat; ${data.breadth.total-data.breadth.eligible} excluded`}>{[['rising','var(--green-11)'],['falling','var(--red-11)'],['flat','var(--gray-9)']].map(([key,color])=><span key={key} style={{flex:data.breadth[key as 'rising'|'falling'|'flat'],...fillStyle(key==='falling'?'hatched':'dotted',{color,cell:1.5})}}/>)}<span style={{flex:data.breadth.total-data.breadth.eligible,background:'var(--gray-a4)'}}/></div>}<small>{data?`${data.breadth.eligible}/${data.breadth.total} goods eligible · not global inflation`:'Basket coverage unknown'}</small><Button variant="ghost" onClick={onEvidence}>Explore price evidence<ArrowUpRight size={14}/></Button></Card>
<Card className="intel-question"><div className="intel-question-title"><ChartNoAxesCombined size={18}/><h2>Where is demand?</h2></div><strong className="intel-answer intel-answer-item">{leader?<><ItemArt id={leader.id} name={leader.name}/>{leader.name}</>:demand.loading?'Loading orders…':'Not available'}</strong><p>{leader?`${number(leader.buyValue)} GP in listed buy orders`:'Open Exchange to inspect bids, asks and completed trades.'}</p><small>{demand.error??(leader?`Current listed buy value · source ${time(demand.data?.sourceUpdatedAt)}. Orders are not completed trades.`:'No demand conclusion from missing quotes.')}</small><Button variant="ghost" onClick={()=>onNavigate('market')}>Explore buy orders<ArrowUpRight size={14}/></Button></Card>
<Card className="intel-question"><div className="intel-question-title"><Users size={18}/><h2>Who holds supply?</h2></div><strong className="intel-answer">Follow the holders</strong><p>Research published banks, then locate an observed holder in the world.</p><small>Partial previews. Total game supply and buyer identities are unknown.</small><Button variant="ghost" onClick={()=>onNavigate('holders')}>Research supply<ArrowUpRight size={14}/></Button></Card>
<Card className="intel-question"><div className="intel-question-title"><Hammer size={18}/><h2>What is worth making?</h2></div><strong className="intel-answer">Price the process</strong><p>Compare inputs, output value and acquisition time before stockpiling.</p><small>Recipe margins depend on fees, timing and available liquidity.</small><Button variant="ghost" onClick={()=>onNavigate('production')}>Explore production<ArrowUpRight size={14}/></Button></Card>
</div>
<Card className="intel-leads"><div className="intel-leads-heading"><div><Heading as="h2" size="5">Research leads</Heading><p>Largest eligible price moves within this basket. Investigate liquidity before acting.</p></div><Button variant="soft" onClick={()=>onNavigate('opportunities')}>Open full screener<ArrowUpRight size={14}/></Button></div>
{leads.length?<div className="intel-table-scroll" tabIndex={0} aria-label="Research leads table"><Table.Root size="2"><Table.Table><Table.Header><Table.Row><Table.ColumnHeaderCell>Item / reason</Table.ColumnHeaderCell><Table.ColumnHeaderCell>Price change</Table.ColumnHeaderCell><Table.ColumnHeaderCell>Executed units</Table.ColumnHeaderCell><Table.ColumnHeaderCell>Evidence</Table.ColumnHeaderCell><Table.ColumnHeaderCell>Research</Table.ColumnHeaderCell></Table.Row></Table.Header><Table.Body>{leads.map(i=><Table.Row key={i.id}><Table.Cell><Button variant="ghost" className="intel-lead-item" onClick={()=>onSelect(itemEntity(i))}><ItemArt id={i.id} name={i.name}/><span><strong>{i.name}</strong><small>{i.eligible?(i.changePct!>0?'Rising executed price':i.changePct!<0?'Falling executed price':'Stable executed price'):'Insufficient trading evidence'}</small></span></Button></Table.Cell><Table.Cell><strong className={i.eligible?(i.changePct!<0?'intel-fall':'intel-rise'):''}>{percent(i.changePct)}</strong></Table.Cell><Table.Cell>{number(i.current?.volume)}<small>{number(i.current?.fills)} fills</small></Table.Cell><Table.Cell><Badge color={i.eligible?'gray':'amber'}>{i.eligible?'Eligible':'Excluded'}</Badge><small>{data?.periodDays}d completed · {result?.delivery.freshness}</small></Table.Cell><Table.Cell><div className="intel-lead-actions"><Button variant="soft" onClick={()=>onSelect(itemEntity(i,'charts'))}>Inspect</Button><Button variant="ghost" aria-label={`${actions.saved(itemEntity(i))?'Unwatch':'Watch'} ${i.name}`} aria-pressed={actions.saved(itemEntity(i))} disabled={actions.busy} onClick={()=>actions.onWatch(itemEntity(i))}><Star size={16} fill={actions.saved(itemEntity(i))?'currentColor':'none'}/></Button></div></Table.Cell></Table.Row>)}</Table.Body></Table.Table></Table.Root></div>:<p>No comparable item evidence yet. You can still explore live orders, holders or production above.</p>}
</Card>
</div>;
}