package online.ruemu.franifer.payment.service; import online.ruemu.franifer.payment.transaction.*; import org.springframework.stereotype.*; import org.springframework.transaction.annotation.*; import java.util.*; @Service public class TransactionService{private final TransactionRepository repo; private final IdempotencyService idem; private final PaymentProviderSimulator provider; public TransactionService(TransactionRepository r,IdempotencyService i,PaymentProviderSimulator p){repo=r;idem=i;provider=p;} @Transactional public PaymentTransaction create(String key,CreateTransactionRequest q){var old=idem.get(key).flatMap(repo::findByReference); if(old.isPresent())return old.get(); var t=new PaymentTransaction();t.setCustomerName(q.customerName());t.setProductType(q.productType());t.setProvider(q.provider());t.setDestination(q.destination());t.setAmount(q.amount());t.setStatus(TransactionStatus.QUEUED);t=repo.saveAndFlush(t);idem.put(key,t.getReference());return t;} @Transactional public PaymentTransaction process(String ref){var t=repo.findByReference(ref).orElseThrow(); if(t.getStatus()==TransactionStatus.SUCCESS)return t;t.setStatus(TransactionStatus.PROCESSING);repo.save(t);var x=provider.process();if(x.success()){t.setStatus(TransactionStatus.SUCCESS);t.setProviderReference(x.providerReference());}else{t.setStatus(TransactionStatus.FAILED);t.setFailureReason(x.error());}return repo.save(t);} @Transactional public PaymentTransaction updateStatus(String ref, TransactionStatus status){
 var t=repo.findByReference(ref).orElseThrow();
 t.setStatus(status);
 return repo.save(t);
} public List<PaymentTransaction> list(){return repo.findAll();} public Object dashboard(){long total=repo.count(), ok=repo.countByStatus(TransactionStatus.SUCCESS), fail=repo.countByStatus(TransactionStatus.FAILED);return Map.of("total",total,"success",ok,"failed",fail,"pending",total-ok-fail);}}