<?php
namespace App\Application\Services;
use App\Domain\Payments\PaymentStatus;
use App\Models\Invoice;
use DomainException;
final class PaymentStateMachine {
 private const ALLOWED=[
  'waiting'=>['confirming','expired','manual_review','failed','cancelled'],
  'confirming'=>['confirming','confirmed','underpaid','overpaid','manual_review','failed'],
  'underpaid'=>['confirming','confirmed','manual_review','expired'],
  'overpaid'=>['confirmed','manual_review'],
  'confirmed'=>['finished','manual_review'],
  'finished'=>[],'expired'=>['manual_review'],'failed'=>[],'manual_review'=>['confirming','confirmed','finished','failed'],'cancelled'=>[],
 ];
 public function transition(Invoice $invoice,PaymentStatus $to):Invoice {$from=$invoice->status;if($from===$to->value)return $invoice;if(!in_array($to->value,self::ALLOWED[$from]??[],true))throw new DomainException("Invalid payment transition: {$from} -> {$to->value}");$invoice->update(['status'=>$to->value]);return $invoice->refresh();}
}
