import {latinDigits} from './auth-input';

export type FundingNetwork='ethereum'|'tron';
export type DemoWallet={enabled:boolean;balance_rial:string;balance_usdt:string;history:{id:string;currency:'IRR'|'USDT';amount:string;created_at:string;status:'pending'|'approved'|'rejected'|'problem'|null;review_id:string|null;review_note:string}[];limits:{max_amount_toman:string;max_amount_usdt:string}};
export type UsdtIntent={id:string;network:FundingNetwork;address:string;amount_micro:string;requested_micro:string;status:string;created_at:string;expires_at:string;candidate_tx_hash:string|null;tx_hash:string|null;log_index:number|null;verification_status:'unverified'|'verified';chain_verified_at:string|null;review_required:boolean;review_decision:'pending'|'approved'|'rejected'|'problem'|null;review_id:string|null;review_note:string};
export type UsdtState={networks:{network:FundingNetwork;address:string;enabled:boolean}[];intents:UsdtIntent[]};
export const fundingId=(value:unknown):value is string=>typeof value==='string'&&/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
export const fundingNetwork=(value:unknown):value is FundingNetwork=>value==='ethereum'||value==='tron';
const object=(value:unknown):Record<string,unknown>=>{if(!value||typeof value!=='object'||Array.isArray(value))throw new Error('invalid_funding_input');return value as Record<string,unknown>};
export function fundingAmount(value:unknown,decimals:number,max:string):string{
 if(typeof value!=='string'||value.length>60)throw new Error('invalid_amount');
 const normalized=latinDigits(value).replace(/[,٬\s]/g,'').replace(/٫/g,'.');
 if(!new RegExp(`^\\d{1,12}${decimals?'(?:\\.\\d{1,'+decimals+'})?':''}$`).test(normalized))throw new Error('invalid_amount');
 const [whole,fraction='']=normalized.split('.'),scale=BigInt(10)**BigInt(decimals),units=BigInt(whole)*scale+BigInt(fraction.padEnd(decimals,'0')||'0');
 if(units<=BigInt(0)||units>BigInt(max)*scale)throw new Error('invalid_amount');
 return units.toString();
}
export function microUsdt(value:string){const units=BigInt(value);return `${units/BigInt(1000000)}${units%BigInt(1000000)?'.'+(units%BigInt(1000000)).toString().padStart(6,'0').replace(/0+$/,''):''}`;}
export function demoCreditInput(value:unknown){
 const body=object(value);
 if(Object.keys(body).some(k=>!['request_id','currency','amount'].includes(k))||!fundingId(body.request_id)||!['TMN','USDT'].includes(String(body.currency)))throw new Error('invalid_funding_input');
 const currency=body.currency==='TMN'?'IRR':'USDT';
 const amount=currency==='IRR'?(BigInt(fundingAmount(body.amount,0,'100000000'))*BigInt(10)).toString():microUsdt(fundingAmount(body.amount,6,'100000'));
 return {p_request:body.request_id,p_currency:currency,p_amount:amount};
}
export function usdtInput(value:unknown){
 const body=object(value);
 if(body.action==='create'&&Object.keys(body).every(k=>['action','request_id','network','amount'].includes(k))&&fundingId(body.request_id)&&fundingNetwork(body.network))return {action:'create' as const,p_request:body.request_id,p_network:body.network,p_amount_micro:fundingAmount(body.amount,6,'100000')};
 if(body.action==='verify'&&Object.keys(body).every(k=>['action','intent_id','transaction_hash'].includes(k))&&fundingId(body.intent_id)&&(body.transaction_hash===undefined||typeof body.transaction_hash==='string'&&/^(?:0x)?[a-fA-F0-9]{64}$/.test(body.transaction_hash)))return {action:'verify' as const,intentId:body.intent_id,...(body.transaction_hash?{transactionHash:body.transaction_hash}: {})};
 throw new Error('invalid_funding_input');
}
const decimal=(value:unknown)=>typeof value==='string'&&/^\d{1,30}(?:\.\d{1,18})?$/.test(value);
export function demoWalletView(value:unknown):DemoWallet{
 const d=object(value),limits=object(d.limits);
 if(typeof d.enabled!=='boolean'||!decimal(d.balance_rial)||!decimal(d.balance_usdt)||!Array.isArray(d.history)||!decimal(limits.max_amount_toman)||!decimal(limits.max_amount_usdt))throw new Error('invalid_funding_response');
 return {enabled:d.enabled,balance_rial:d.balance_rial as string,balance_usdt:d.balance_usdt as string,limits:{max_amount_toman:limits.max_amount_toman as string,max_amount_usdt:limits.max_amount_usdt as string},history:d.history.map(item=>{
  const row=object(item),status=row.status??null,reviewId=row.review_id??null,reviewNote=row.review_note===undefined?'':row.review_note;
  if(!fundingId(row.id)||!['IRR','USDT'].includes(String(row.currency))||!decimal(row.amount)||typeof row.created_at!=='string'||!Number.isFinite(Date.parse(row.created_at))||!(status===null||typeof status==='string'&&['pending','approved','rejected','problem'].includes(status))||!(reviewId===null||fundingId(reviewId))||typeof reviewNote!=='string'||reviewNote.length>2000)throw new Error('invalid_funding_response');
  // Missing review metadata in older responses is unknown, never proof of credit.
  return {id:row.id,currency:row.currency as 'IRR'|'USDT',amount:row.amount as string,created_at:row.created_at,status:status as DemoWallet['history'][number]['status'],review_id:reviewId,review_note:reviewNote};
 })};
}
export function usdtIntentView(value:unknown):UsdtIntent{
 const d=object(value);
 if(!fundingId(d.id)||!fundingNetwork(d.network)||typeof d.address!=='string'||d.address.length>64||typeof d.amount_micro!=='string'||!/^\d{1,16}$/.test(d.amount_micro)||typeof d.requested_micro!=='string'||!/^\d{1,16}$/.test(d.requested_micro)||typeof d.status!=='string'||!['pending','credited','expired','review'].includes(d.status)||typeof d.created_at!=='string'||!Number.isFinite(Date.parse(d.created_at))||typeof d.expires_at!=='string'||!Number.isFinite(Date.parse(d.expires_at)))throw new Error('invalid_funding_response');
 const hash=(v:unknown)=>typeof v==='string'&&/^(?:0x)?[a-fA-F0-9]{64}$/.test(v)?v:null;
 if(!['unverified','verified'].includes(String(d.verification_status))||typeof d.review_required!=='boolean'||!(d.review_decision===null||['pending','approved','rejected','problem'].includes(String(d.review_decision)))||!(d.review_id===null||fundingId(d.review_id)))throw new Error('invalid_funding_response');
 return {id:d.id,network:d.network,address:d.address,amount_micro:d.amount_micro,requested_micro:d.requested_micro,status:d.status,created_at:d.created_at,expires_at:d.expires_at,candidate_tx_hash:hash(d.candidate_tx_hash),tx_hash:hash(d.tx_hash),log_index:typeof d.log_index==='number'&&Number.isSafeInteger(d.log_index)&&d.log_index>=0?d.log_index:null,verification_status:d.verification_status as 'unverified'|'verified',chain_verified_at:typeof d.chain_verified_at==='string'&&Number.isFinite(Date.parse(d.chain_verified_at))?d.chain_verified_at:null,review_required:d.review_required,review_decision:d.review_decision as UsdtIntent['review_decision'],review_id:d.review_id as string|null,review_note:typeof d.review_note==='string'?d.review_note.slice(0,2000):''};
}
export function usdtStateView(value:unknown):UsdtState{
 const d=object(value);if(!Array.isArray(d.networks)||!Array.isArray(d.intents))throw new Error('invalid_funding_response');
 return {networks:d.networks.map(value=>{const row=object(value);if(!fundingNetwork(row.network)||typeof row.enabled!=='boolean'||typeof row.address!=='string'||row.address.length>64)throw new Error('invalid_funding_response');return {network:row.network,address:row.address,enabled:row.enabled};}),intents:d.intents.map(usdtIntentView)};
}
export function fundingError(code:unknown):[string,number]{
 const errors:Record<string,[string,number]>={wallet_identity_required:['احراز هویت شما کامل نیست. برای برداشت و معامله، ابتدا احراز هویت را تکمیل کنید.',403],withdrawal_insufficient_balance:['موجودی واقعی در دسترس برای این برداشت کافی نیست.',422],withdrawal_verified_bank_required:['یک حساب بانکی تأییدشده و متعلق به خودتان انتخاب کنید.',422],withdrawal_request_conflict:['این درخواست قبلاً با اطلاعات دیگری ثبت شده است؛ همان درخواست را پیگیری کنید.',409],withdrawal_rate_limit:['تعداد درخواست‌های برداشت زیاد است؛ کمی بعد تلاش کنید.',429],invalid_withdrawal:['اطلاعات برداشت معتبر نیست.',400],invalid_withdrawal_amount:['مبلغ برداشت باید عدد صحیح مثبت و در محدوده مجاز باشد.',400],withdrawals_disabled:['برداشت برای این حساب غیرفعال است.',403],invalid_amount:['مبلغ معتبر و در محدودهٔ مجاز وارد کنید.',400],invalid_funding_input:['اطلاعات درخواست معتبر نیست.',400],demo_disabled:['شارژ آزمایشی غیرفعال است.',409],demo_limit:['سقف موجودی آزمایشی این حساب تکمیل شده است.',409],demo_rate_limit:['تعداد شارژهای آزمایشی زیاد است؛ کمی بعد تلاش کنید.',429],demo_request_conflict:['این درخواست قبلاً با مبلغ دیگری ثبت شده است.',409],usdt_not_configured:['شبکهٔ واریز هنوز توسط مدیریت فعال نشده است.',503],usdt_intent_exists:['یک درخواست باز دارید؛ ابتدا همان درخواست را تکمیل کنید.',409],usdt_rate_limit:['تعداد درخواست‌ها زیاد است؛ کمی بعد تلاش کنید.',429],usdt_request_conflict:['مشخصات این درخواست با نسخهٔ ثبت‌شده متفاوت است.',409],usdt_intent_not_found:['درخواست واریز پیدا نشد.',404],usdt_intent_expired:['مهلت واریز تمام شده است؛ پرداخت تازه انجام ندهید. واریز قبلی را می‌توانید پیگیری کنید.',409],invalid_tx:['شناسهٔ تراکنش یا شبکه معتبر نیست.',400],transfer_mismatch:['این تراکنش با شبکه، آدرس، مبلغ دقیق یا زمان درخواست مطابقت ندارد؛ حساب شارژ نشد.',422],ambiguous_transfer:['این تراکنش نیاز به بررسی پشتیبانی دارد؛ حساب خودکار شارژ نشد.',409],provider_unavailable:['ارتباط با شبکه برقرار نشد؛ کمی بعد دوباره بررسی کنید.',503],not_authenticated:['ابتدا وارد حساب شوید.',401],not_authorized:['دسترسی به این درخواست مجاز نیست.',403],customer_account_suspended:['حساب شما تعلیق شده است.',403],customer_account_closed:['حساب بسته شده است.',403],PGRST202:['این بخش هنوز در پایگاه داده فعال نشده است.',503]};
 const aliases:Record<string,string>={invalid_demo_amount:'invalid_amount',invalid_usdt_amount:'invalid_amount',demo_balance_limit:'demo_limit',usdt_network_unavailable:'usdt_not_configured',usdt_intent_pending:'usdt_intent_exists',invalid_usdt_hash:'invalid_tx',usdt_verification_mismatch:'transfer_mismatch',usdt_provider_unavailable:'provider_unavailable',usdt_receipt_conflict:'transfer_mismatch',usdt_transfer_used:'transfer_mismatch',usdt_asset_conflict:'ambiguous_transfer',usdt_amount_unavailable:'usdt_rate_limit',account_suspended:'customer_account_suspended',account_closed:'customer_account_closed'};
 const key=typeof code==='string'?aliases[code]||code:'';
 return errors[key]?errors[key]:['دریافت یا ثبت اطلاعات انجام نشد. دوباره تلاش کنید.',503];
}
