<?php
namespace App\Http\Controllers\Api\V1;
use App\Http\Controllers\Controller;
use App\Jobs\CreateSettlementPayoutJob;
use App\Models\{Asset,LedgerEntry,PayoutAddressAllowlist,SettlementBatch};
use App\Support\{ApiResponse,AtomicAmount};
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
final class SettlementController extends Controller {
 public function index(Request $r){$q=SettlementBatch::with(['asset','payoutWallet','payout'])->where('merchant_id',$r->attributes->get('merchant')->id)->where('environment',$r->attributes->get('environment'))->latest('id');return ApiResponse::success($q->paginate(min(max($r->integer('per_page',20),1),100))->through(fn($s)=>$this->resource($s)));}
 public function store(Request $r){$d=$r->validate(['pay_currency'=>['required','string','max:20'],'payout_wallet_id'=>['nullable','string','max:40'],'amount'=>['nullable','string','regex:/^(?:0|[1-9]\d*)(?:\.\d{1,8})?$/'],'metadata'=>['nullable','array']]);$m=$r->attributes->get('merchant');$env=$r->attributes->get('environment');$asset=Asset::where('code',strtoupper($d['pay_currency']))->where('enabled',true)->first();if(!$asset)return ApiResponse::error('UNSUPPORTED_CURRENCY','The requested asset or network is not enabled.',422);$wallet=PayoutAddressAllowlist::where('merchant_id',$m->id)->where('asset_id',$asset->id)->where('environment',$env)->where('status','active')->where('available_at','<=',now())->when(!empty($d['payout_wallet_id']),fn($q)=>$q->where('public_id',$d['payout_wallet_id']),fn($q)=>$q->where('is_default',true))->first();if(!$wallet)return ApiResponse::error('PAYOUT_WALLET_REQUIRED','Add an active default payout wallet first.',409);$available=$this->availableAtomic($m->id,$asset->id);$amount=isset($d['amount'])?AtomicAmount::fromDecimal($d['amount'],$asset->decimals):$available;if(bccomp($amount,'0',0)<=0||bccomp($available,$amount,0)<0)return ApiResponse::error('INSUFFICIENT_BALANCE','There is not enough available balance to settle.',409);$settlement=SettlementBatch::create(['public_id'=>'set_'.Str::ulid(),'merchant_id'=>$m->id,'asset_id'=>$asset->id,'payout_wallet_id'=>$wallet->id,'environment'=>$env,'status'=>'pending','amount_atomic'=>$amount,'fee_atomic'=>config('gateway.tron.default_fee_atomic','1000000'),'metadata'=>$d['metadata']??[]]);CreateSettlementPayoutJob::dispatch($settlement->id)->onQueue('payouts')->afterCommit();return ApiResponse::success($this->resource($settlement->load(['asset','payoutWallet','payout'])),202);}
 public function show(Request $r,string $id){$s=SettlementBatch::with(['asset','payoutWallet','payout'])->where('public_id',$id)->where('merchant_id',$r->attributes->get('merchant')->id)->where('environment',$r->attributes->get('environment'))->first();if(!$s)return ApiResponse::error('SETTLEMENT_NOT_FOUND','The requested settlement does not exist.',404);return ApiResponse::success($this->resource($s));}
 private function availableAtomic(int $merchantId,int $assetId):string{return (string)LedgerEntry::whereHas('account',fn($q)=>$q->where('merchant_id',$merchantId)->where('asset_id',$assetId)->where('type','merchant_available'))->selectRaw("COALESCE(SUM(CASE WHEN direction='credit' THEN amount_atomic ELSE -amount_atomic END),0) as balance")->value('balance');}
 private function resource(SettlementBatch $s):array{return ['id'=>$s->public_id,'status'=>$s->status,'pay_currency'=>$s->asset?->code,'network'=>$s->asset?->network,'amount'=>AtomicAmount::toDecimal((string)$s->amount_atomic,(int)$s->asset->decimals),'fee_estimate'=>AtomicAmount::toDecimal((string)$s->fee_atomic,(int)$s->asset->decimals),'payout_wallet'=>['id'=>$s->payoutWallet?->public_id,'address'=>$s->payoutWallet?->address,'label'=>$s->payoutWallet?->label],'payout_id'=>$s->payout?->public_id,'failure_reason'=>$s->failure_reason,'metadata'=>$s->metadata??new \stdClass(),'created_at'=>$s->created_at?->utc()->toIso8601String(),'completed_at'=>$s->completed_at?->utc()->toIso8601String()];}
}