import {decimalUnits,type DashboardData} from './dashboard';
import {cashWallet,isCashPosition} from './cash-wallet';

type Position=DashboardData['positions'][number];
export type PortfolioSegment={key:string;symbol:string;value:bigint;start:number;end:number};
type Summary={status:'unavailable'|'incomplete'|'ready';total:bigint|null;segments:PortfolioSegment[]};
const validDecimal=(value:unknown):value is string=>typeof value==='string'&&value.length<=80&&/^\d+(\.\d{1,18})?$/.test(value);

// Amounts stay exact; only bounded chart percentages are converted to Number.
export function portfolioSummary(positions:Position[]|null,currency:'TMN'|'USDT'):Summary{
 if(positions===null)return {status:'unavailable',total:null,segments:[]};
 const unknown:Summary={status:'incomplete',total:null,segments:[]};
 const groups=new Map<string,{key:string;symbol:string;value:bigint}>();
 const add=(key:string,symbol:string,value:bigint)=>{if(value>BigInt(0))groups.set(key,{key,symbol,value:(groups.get(key)?.value||BigInt(0))+value})};
 const cashRows=positions.filter(isCashPosition);
 if(cashRows.length){const cash=cashWallet(cashRows);if(!cash)return unknown;if(currency==='TMN')add('cash','TMN',cash.totalRial)}
 for(const p of positions){
  if(!validDecimal(p.quantity)||!validDecimal(p.locked_quantity)||decimalUnits(p.locked_quantity)>decimalUnits(p.quantity))return unknown;
  if(currency==='TMN'&&isCashPosition(p))continue;
  if(decimalUnits(p.quantity)===BigInt(0))continue;
  let value:bigint;
  if(currency==='TMN'){
   if(typeof p.value_rial!=='string'||!/^\d{1,40}$/.test(p.value_rial))return unknown;
   value=BigInt(p.value_rial);
  }else{
   const usd=p.project_id===null&&p.asset_symbol==='USDT'?p.quantity:p.value_usdt;
   if(!validDecimal(usd))return unknown;
   value=decimalUnits(usd);
  }
  add(isCashPosition(p)?'cash':p.project_id?'project:'+p.project_id:'asset:'+p.asset_symbol,isCashPosition(p)?'TMN':p.asset_symbol,value);
 }
 const sorted=[...groups.values()].sort((a,b)=>a.value>b.value?-1:a.value<b.value?1:a.key.localeCompare(b.key));
 const total=sorted.reduce((sum,row)=>sum+row.value,BigInt(0));
 const visible=sorted.length>5?[...sorted.slice(0,4),{key:'other',symbol:'other',value:sorted.slice(4).reduce((sum,row)=>sum+row.value,BigInt(0))}]:sorted;
 let cumulative=BigInt(0);
 const segments=visible.map(row=>{const start=Number(cumulative*BigInt(10000)/total)/100;cumulative+=row.value;return {...row,start,end:Number(cumulative*BigInt(10000)/total)/100}});
 return {status:'ready',total,segments};
}
