<?php
namespace App\Jobs;
use App\Application\Services\Payouts\{PayoutPolicyService,PayoutStateMachine,PayoutSettlementService};
use App\Application\Services\Risk\ManualRiskScreeningService;
use App\Models\Payout;
use Illuminate\Bus\Queueable;use Illuminate\Contracts\Queue\ShouldQueue;use Illuminate\Foundation\Bus\Dispatchable;use Illuminate\Queue\InteractsWithQueue;use Illuminate\Queue\SerializesModels;use Illuminate\Support\Facades\Cache;
final class ScreenPayoutJob implements ShouldQueue {
 use Dispatchable,InteractsWithQueue,Queueable,SerializesModels; public int $tries=3;
 public function __construct(public int $payoutId){$this->onQueue('payouts');}
 public function backoff():array{return [30,120,600];}
 public function handle(PayoutPolicyService $policy,PayoutStateMachine $sm,PayoutSettlementService $settle,ManualRiskScreeningService $risk):void{
  $p=null;$lock=Cache::lock("payout:{$this->payoutId}",120);if(!$lock->get())return;
  try{$p=Payout::with('asset')->findOrFail($this->payoutId);if($p->status!=='pending_screening')return;$policy->assertNoKillSwitch($p);$policy->assertAllowlisted($p);
   try{$screen=$risk->screen('payout',(string)$p->public_id,$p->to_address,$p->asset->network,$p->merchant_id);}catch(\RuntimeException $e){$p->update(['screening_status'=>'manual_review','screening_result'=>['provider'=>'manual','reason'=>$e->getMessage()]]);$sm->transition($p,'manual_review');return;}
   if($screen->status!=='passed'){$p->update(['screening_status'=>'manual_review','screening_result'=>$screen->toArray()]);$sm->transition($p,'manual_review');return;}
   $p->update(['screening_status'=>'passed','screening_result'=>$screen->toArray()]);$sm->transition($p,'pending_approval');
  }catch(\DomainException $e){$p?->update(['screening_status'=>'rejected','screening_result'=>['reason'=>$e->getMessage()]]);if($p)$settle->release($p,$e->getMessage());}finally{$lock->release();}
 }
}
