<?php
namespace App\Application\Services\Payouts;
use App\Application\Services\LedgerService;use App\Models\{Payout,SettlementBatch};use Illuminate\Support\Facades\DB;
final class PayoutSettlementService {public function __construct(private LedgerService $ledger){}
 public function release(Payout $p,string $reason):void{DB::transaction(function()use($p,$reason){$p=Payout::lockForUpdate()->findOrFail($p->id);if($p->release_ledger_transaction_id||$p->broadcast_at)return;$reserved=$this->ledger->account($p->merchant_id,$p->asset_id,'merchant_reserved');$available=$this->ledger->account($p->merchant_id,$p->asset_id,'merchant_available');$tx=$this->ledger->post('payout_release',(string)$p->id,"payout-release:{$p->id}",[['account_id'=>$reserved->id,'direction'=>'debit','amount_atomic'=>(string)$p->amount_atomic],['account_id'=>$available->id,'direction'=>'credit','amount_atomic'=>(string)$p->amount_atomic]]);$p->update(['release_ledger_transaction_id'=>$tx->id,'failed_at'=>now(),'failure_reason'=>$reason,'status'=>'failed']);SettlementBatch::where('payout_id',$p->id)->update(['status'=>'failed','failure_reason'=>$reason]);});}
 public function complete(Payout $p):void{DB::transaction(function()use($p){$p=Payout::lockForUpdate()->findOrFail($p->id);if($p->settlement_ledger_transaction_id)return;$reserved=$this->ledger->account($p->merchant_id,$p->asset_id,'merchant_reserved');$clearing=$this->ledger->account(null,$p->asset_id,'blockchain_clearing');$network=$this->ledger->account(null,$p->asset_id,'network_fee_expense');$entries=[['account_id'=>$reserved->id,'direction'=>'debit','amount_atomic'=>(string)$p->amount_atomic],['account_id'=>$clearing->id,'direction'=>'credit','amount_atomic'=>(string)$p->amount_atomic]];if(bccomp((string)$p->fee_atomic,'0',0)>0){$entries[]=['account_id'=>$network->id,'direction'=>'debit','amount_atomic'=>(string)$p->fee_atomic];$entries[]=['account_id'=>$clearing->id,'direction'=>'credit','amount_atomic'=>(string)$p->fee_atomic];}$tx=$this->ledger->post('payout_settlement',(string)$p->id,"payout-settle:{$p->id}",$entries);$p->update(['settlement_ledger_transaction_id'=>$tx->id,'status'=>'completed','completed_at'=>now()]);SettlementBatch::where('payout_id',$p->id)->update(['status'=>'completed','completed_at'=>now()]);});}}
