(function(root,factory){const node=typeof module==='object'&&module.exports,api=factory(node?require('./portfolio-ledger.js'):root.LwPortfolioLedger,node?require('./portfolio-backup.js'):root.LWPortfolioBackup);if(node)module.exports=api;else root.LwPortfolioIO=api;})(typeof globalThis!=='undefined'?globalThis:this,(L,B)=>{
'use strict';
const headers=['Transaction ID','Date','Type','Amount LTC','Account ID','Account','Destination ID','Destination','Network fee LTC','Currency','Price','Fee','Valuation price','FX date','FX source','EUR per USD','GBP per USD','PLN per USD','Notes'];
const safe=s=>/^[=+\-@\t\r]/.test(String(s??''))?"'"+s:String(s??''),uns=s=>/^'[=+\-@\t\r]/.test(s)?s.slice(1):s,cell=v=>'"'+String(v??'').replaceAll('"','""')+'"';
function csv(state){state=L.normalize(state);const names=new Map(state.accounts.map(a=>[a.id,a.name]));return [headers,...state.transactions.map(r=>[safe(r.id),r.date,r.type,r.amount,r.accountId,safe(names.get(r.accountId)),r.toAccountId,safe(names.get(r.toAccountId)||''),r.networkFee,r.currency,r.price,r.fee,r.valuationPrice,r.fxDate,r.fxSource,r.fx.EUR,r.fx.GBP,r.fx.PLN,safe(r.notes)])].map(row=>row.map(cell).join(',')).join('\r\n');}
function backup(state){return JSON.stringify({format:'litecoin.watch.portfolio',exportedAt:new Date().toISOString(),...L.normalize(state)},null,2);}
function parse(text){
 if(typeof text!=='string'||text.length>2000000)throw Error('Maximum import size is 2 MB.');text=text.replace(/^\uFEFF/,'').trim();if(!text)throw Error('The backup is empty.');
 if(text.startsWith('{')){const v=JSON.parse(text);if(v?.format==='litecoin.watch.portfolio'&&[2,3,4].includes(v.version)){if(v.version===2&&v.currency!=='USD')throw Error('Version 2 backups must use USD.');return L.normalize(v);}return L.normalize({version:2,transactions:B.parse(text)});}
 const rows=B.csvRows(text),head=rows.shift()||[],modern=['Date','Type','Amount LTC','Currency','Price','Fee','FX date','FX source','EUR per USD','GBP per USD','PLN per USD','Notes'].every(k=>head.includes(k)),legacy=['Date','Type','Amount LTC','Price USD','Fee USD','Notes'].every(k=>head.includes(k));
 if(!modern&&!legacy)return L.normalize({version:2,transactions:B.parse(text)});
 if(new Set(head).size!==head.length)throw Error('Duplicate CSV headers.');const full=headers.every(k=>head.includes(k));if(head.includes('Account ID')&&!full)throw Error('Use a complete account-aware CSV export.');const accounts=new Map(full?[]:[['main',L.DEFAULT]]);
 const transactions=rows.map((r,i)=>{if(r.length!==head.length)throw Error('A CSV row has missing or extra columns.');const v=k=>head.includes(k)?r[head.indexOf(k)]:'';
  if(full){for(const [idKey,nameKey]of [['Account ID','Account'],['Destination ID','Destination']])if(v(idKey)){const a=L.account({id:v(idKey),name:uns(v(nameKey))}),old=accounts.get(a.id);if(old&&old.name!==a.name)throw Error('Inconsistent account names in the CSV.');accounts.set(a.id,a);}}
  return L.transaction({id:uns(v('Transaction ID'))||'csv-'+crypto.randomUUID(),date:v('Date'),type:v('Type'),amount:v('Amount LTC'),price:v(modern?'Price':'Price USD'),fee:v(modern?'Fee':'Fee USD'),notes:uns(v('Notes')),accountId:full?v('Account ID'):'main',toAccountId:full?v('Destination ID'):null,networkFee:full?v('Network fee LTC'):0,valuationPrice:full?v('Valuation price'):null,...(modern?{currency:v('Currency'),fx:{USD:1,EUR:v('EUR per USD'),GBP:v('GBP per USD'),PLN:v('PLN per USD')},fxDate:v('FX date')||null,fxSource:v('FX source')}:{})},i);
 });if(!accounts.size)accounts.set('main',L.DEFAULT);return L.normalize({version:4,accounts:[...accounts.values()],transactions,reconciliations:[]});
}
return {csv,backup,parse,headers,cell};
});
