<?php 
 
namespace App\Controller; 
 
use App\Entity\InfoSanteSubscription; 
use App\Entity\InfoSanteTransaction; 
use App\Entity\LabbaikSubscriber; 
use App\Entity\LabbaikSubscription; 
use App\Entity\LabbaikTransaction; 
use App\Entity\SysCloseStatus; 
use App\Entity\SysSmsHistory; 
use App\Entity\SysTransaction; 
use App\Entity\SmartloyerTransaction; 
use App\Message\ServicePayment; 
use Doctrine\ORM\EntityManagerInterface; 
use Doctrine\Persistence\ManagerRegistry; 
use PhpParser\Node\Stmt\TryCatch; 
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; 
use Symfony\Component\HttpClient\HttpClient; 
use Symfony\Component\HttpFoundation\Response; 
use Symfony\Component\Routing\Annotation\Route; 
 
class ServicePaymentController extends AbstractController 
{ 
    /** 
     * @Route("/service/payment", name="service_payment") 
     */ 
    public function index(): Response 
    { 
         
        //$this->dispatchMessage(new ServicePayment(57632,"",$this->getDoctrine())); 
        //$this->payment(57636,"",$this->getDoctrine()); 
        return $this->render('service_payment/index.html.twig', [ 
            'controller_name' => 'ServicePaymentController', 
        ]); 
    } 
 
    /** 
     * @Route("/service/checkPaymentStatus", name="service_payment_status") 
     */ 
    public function checkPaymentStatus(): Response 
    { 
        $resultReponse = "OK"; 
        $entityManager = $this->getDoctrine()->getManager(); 
        $repoTrans = $entityManager->getRepository(SysTransaction::class); 
        $transactions = $repoTrans->findBy(['clientPayementStatus' => 'PENDING', 'isClosed' => false]); 
         
        foreach($transactions as $transaction){ 
            if($transaction->getIsSuccessTransaction() && !$transaction->getIsClosed()){ 
                $resultReponse = $resultReponse . " " . strval($transaction->getId()); 
                $url = "https://bridgeapi.caurispay.com/payement/requestStatus"; 
                $client = HttpClient::create([ 
                    'headers' => [ 
                    'User-Agent' => 'ReservLine', 
                    'Connection' => 'keep-alive', 
                    //'Content-Length' => strlen($body), 
                    //'Authorization' => $authorization, 
                    //'Content-Type' => 'application/json', 
                    'Content-Type: application/x-www-form-urlencoded' 
                    ], 
                    'verify_peer' => false, 
                    'verify_host' => false, 
                    'body' => ['requestReference' => $transaction->getClientPayementReference()] 
                ]); 
             
                //try{ 
 
                //}catch(){ 
                     
                //} 
                $response = $client->request('POST', $url,['timeout' => 400]); 
                 
                //var_dump( $transaction->getClientPayementReference()); 
                //var_dump($response->getStatusCode()); 
                //var_dump($response->getInfo()); 
                if($response->getStatusCode() == 200 or $response->getStatusCode() ==202){ 
                     
                    $requestResponse = $response->toArray(); 
                    //var_dump( $requestResponse); 
                    if(strcmp($requestResponse["status"],"PENDING") != 0 ){ 
                        $transaction->setClientPayementTime(new \DateTime('now')); 
                        $transaction->setClientPayementStatus($requestResponse["status"]); 
                        $transaction->setClientPayementComment($requestResponse["messageText"]); 
                         
                        $textMessageSMS = ""; 
                        $textMessageSMSGAZADMIN =""; 
                        $repoClosStatus = $entityManager->getRepository(SysCloseStatus::class); 
                         
                        if(strcmp($requestResponse["status"],"SUCCESS") == 0 ){ 
                            $closeStatus = $repoClosStatus->findOneBy(["statusCode" => "PDPROCS"]); //TODO: Add service code in condition 
                            $transaction->setIsClientPaid(true); 
 
                            switch ($transaction->getService()->getCodeService()) { 
                                 
                                case "TTBUS": 
                                    //$textMessageSMS = str_replace("%idResv%", $transaction->getReservationCode() , $transaction->getService()->getTextSuccessPayementSMS()); 
                                    $textMessageSMS = $transaction->getSmsMessage(); 
                                    break; 
                                case "RCHGAZ": 
                                    $textMessageSMS = $transaction->getSmsMessage(); 
                                     
                                    //Send admin notification email 
                                    if($transaction->getEmailNotif() != null){ 
                                        SysNotifController::sendEmailGazNotif($transaction->getReservationCode() . "-" . $transaction->getMsisdn(), $transaction->getEmailNotif()); 
                                        $textMessageSMSGAZADMIN = $transaction->getEmailNotif(); 
                                    } 
                                    break; 
                                case "SLOYER": 
                                    //$textMessageSMS = str_replace("%idResv%", $transaction->getReservationCode() , $transaction->getService()->getTextSuccessPayementSMS()); 
                                    //saction = new SmartloyerTransaction(); 
                                    $sloyerTransactionRepo = $entityManager->getRepository(SmartloyerTransaction::class); 
                                    $sloyerTransaction = $sloyerTransactionRepo->findOneBy(["sysTransaction" => $transaction]); 
                                     
                                    $url = "https://smartloyer.com/apipayement/makePayement"; 
                                    $client = HttpClient::create([ 
                                        'headers' => [ 
                                        'User-Agent' => 'ReservLine', 
                                        'Connection' => 'keep-alive', 
                                        //'Content-Length' => strlen($body), 
                                        //'Authorization' => $authorization, 
                                        //'Content-Type' => 'application/json', 
                                        'Content-Type: application/x-www-form-urlencoded' 
                                    ], 
                                    'verify_peer' => false, 
                                    'verify_host' => false, 
                                    'body' => ['payementId' => $sloyerTransaction->getPayementId(), 
                                            'payementRef' =>  $sloyerTransaction->getPayementRef(), 
                                            'ussdSessionRef' => $transaction->getSessionId(), 
                                            'ussdPayementRef' => $transaction->getClientPayementReference(),  
                                            'ussdSessionPhone' => $transaction->getMsisdn()] 
                                    ]); 
         
                                    $response = $client->request('POST', $url,['timeout' => 400]); 
                                    $result["statusCode"] = $response->getStatusCode(); 
                                    //var_dump($result["statusCode"]); 
                                    if($result["statusCode"] == 200 or $result["statusCode"] ==202){ 
                                        $requestResponse = $response->toArray(); 
                                        //var_dump($requestResponse); 
                                        if($requestResponse["success"]){ 
                                            $sloyerTransaction->setIsPayementUpdate(true); 
                                            $sloyerTransaction->setPayementUpdateTime(new \DateTime('now')); 
                                            $textMessageSMS = $transaction->getSmsMessage(); 
                                            $transaction->setIsClosed(true); 
                                        }//TODO: Add log for the else statement 
                                    }else{ 
                                        $transaction->setIsClosed(false); 
                                    } 
 
                                    break; 
                                case "ESANTE": 
                                    $textMessageSMS = $transaction->getService()->getTextSuccessPayementSMS(); 
                                    $transaction->setIsClosed(true); 
                                    $repoInfoSanteTransaction = $entityManager->getRepository(InfoSanteTransaction::class); 
                                    $infoSanteTransaction = $repoInfoSanteTransaction->findOneBy(["sysTansaction" => $transaction ]); 
                                    $repoSubscription = $entityManager->getRepository(InfoSanteSubscription::class); 
                                    $subscription = $repoSubscription->findOneBy(["msisdn"=>$transaction->getMsisdn(), "categorie" =>$infoSanteTransaction->getCategorie()]); 
                                    $toDay = new \DateTime('now'); 
                                    if($subscription == null){ 
                                        $subscription = new InfoSanteSubscription(); 
                                        $subscription->setMsisdn($transaction->getMsisdn()); 
                                        $subscription->setCreationDate(new \DateTime('now')); 
                                        $subscription->setCategorie($infoSanteTransaction->getCategorie()); 
                                        $subscription->setIsActif(true); 
                                        $subscription->setStartDate(new \DateTime('now')); 
                                        $subscription->setExpiryDate(new \DateTime('now')); 
                                    } 
                                    $subscription->setIsActif(true); 
                                    $subscription->setUpdateDate(new \DateTime('now')); 
                                     
                                    if($subscription->getExpiryDate() < $toDay){ 
                                        $subscription->setStartDate(new \DateTime('now')); 
                                        $subscription->setExpiryDate($toDay); 
                                    } 
                                    $toDay = $subscription->getExpiryDate(); 
                                    $toDay = date_add($toDay,date_interval_create_from_date_string(strval($infoSanteTransaction->getTypeAbonnement()->getNbrJours()) . " DAYS")); 
                                    $subscription->setExpiryDate(date_create(date_format($toDay,"Y-m-d H:i:s")) ); 
                                     
                                    $entityManager->persist($subscription); 
                                    
                                    break; 
                                case "LABBAIK": 
                                    $labbaikTransRepo = $entityManager->getRepository(LabbaikTransaction::class); 
                                    $labbaikSubscriberRepo = $entityManager->getRepository(LabbaikSubscriber::class); 
                                    $labbaikTransaction = $labbaikTransRepo->findOneBy(['sysTransaction' => $transaction]); 
                                    $closeStatus = $repoClosStatus->findOneBy(["statusCode" => "SUCCESS"]); 
                                    $labbaikTransaction->setTransactionStatus($closeStatus); 
                                    if(strcmp(strtolower($labbaikTransaction->getTransactionType()) ,"souscription")==0 or strcmp(strtolower($labbaikTransaction->getTransactionType()) ,"newsouscription")==0){ 
                                        $textMessageSMS = "Merci pour votre nouvelle souscription au service ".$labbaikTransaction->getSubscriptionType()->getLibelle().". Faite vos paiements a tout moment de votre choix en tapant *450*6#"; 
                                         
                                        //$subscription = $labbaikTransaction->getSubscription(); 
                                         
                                        //$subscriber = $labbaikSubscriberRepo->findOneBy(['telephoneNumber' => $transaction->getMsisdn()]); 
                                        //if($subscription == null){ 
                                            //$subscriber = new LabbaikSubscriber(); 
                                            //$subscriber->setTelephoneNumber($transaction->getMsisdn()); 
                                            //$entityManager->persist($subscriber); 
                                            $subscription = new LabbaikSubscription(); 
                                            $subscription->setSubscriber($labbaikTransaction->getSubscriber()); 
                                            $subscription->setSubscribtionType($labbaikTransaction->getSubscriptionType()); 
                                            $subscription->setMsisdn($labbaikTransaction->getMsisdn()); 
                                            $subscription->setFeeSubscriptionPaid(true); 
                                            $subscription->setSubscriptionActivated(false); 
                                            $subscription->setAssPolice1Enable(false); 
                                            $subscription->setAssPolice2Enable(false); 
                                            $subscription->setAssPolice1Number(sprintf("%06d",strval($labbaikTransaction->getId()))); 
                                            $subscription->setFeeSubscriptionPaid(true); 
                                            $subscription->setCreateDate(new \DateTime("Now")); 
                                            $subscription->setUpdateTime(new \DateTime("Now")); 
                                            $subscription->setMainBalance($labbaikTransaction->getSubscriptionType()->getCotisationAmount()); 
                                            $entityManager->persist($subscription); 
                                        //} 
                                        $labbaikTransaction->setPaymentTime(new \DateTime('now')); 
                                        $labbaikTransaction->setPaymentValidated(true); 
                                        $labbaikTransaction->setAffectedPoliceId(1); 
                                        $labbaikTransaction->setBalanceBefore(0); 
                                        $labbaikTransaction->setBalanceAfter($subscription->getMainBalance()); 
                                        $labbaikTransaction->setSubscription($subscription); 
                                        $entityManager->persist($labbaikTransaction); 
 
                                    }elseif(strcmp(strtolower($labbaikTransaction->getTransactionType()) ,"paiement")==0){ 
                                        
                                        //$labbaikSubscriptionRepo = $entityManager->getRepository(LabbaikSubscription::class); 
                                        $subscription = $labbaikTransaction->getSubscription(); 
                                        $labbaikTransaction->setAffectedPoliceId(1); 
                                        $labbaikTransaction->setBalanceBefore($subscription->getMainBalance()); 
                                        $labbaikTransaction->setPaymentTime(new \DateTime('now')); 
                                        $labbaikTransaction->setPaymentValidated(true); 
 
                                        $subscription->setMainBalance($subscription->getMainBalance() + $labbaikTransaction->getTransactionAmount()); 
                                        $entityManager->persist($subscription); 
                                         
                                        $labbaikTransaction->setBalanceAfter($subscription->getMainBalance()); 
                                        $entityManager->persist($labbaikTransaction); 
                                        $textMessageSMS = "Payement de ". strval(intval($labbaikTransaction->getTransactionAmount())) ." au service " . $labbaikTransaction->getSubscriptionType()->getLibelle() ." effectue avec success. votre nouveau solde est de " . strval(intval($subscription->getMainBalance())) . "F" ; 
                                    } 
                                    $transaction->setIsClosed(true); 
                                    //$textMessageSMS = $transaction->getSmsMessage(); 
                                    //Send admin notification email 
                                    if($transaction->getEmailNotif() != null){ 
                                        SysNotifController::sendEmailGazNotif($transaction->getReservationCode() . "-" . $transaction->getMsisdn(), $transaction->getEmailNotif()); 
                                    } 
                                    break; 
                                 
                            } 
                        }else{ 
                            $closeStatus = $repoClosStatus->findOneBy(["statusCode" => "NOTPAID"]); //TODO: Add service code in condition 
                            $transaction->setIsClosed(true); 
                            $transaction->setCloseComment("Client payment fail"); 
                             
                             
                            switch ($transaction->getService()->getCodeService()) { 
                                 
                                case "TTBUS": 
                                    $textMessageSMS = str_replace("%idResv%", $transaction->getReservationCode() , $transaction->getService()->getTextFailedPayementSMS()); 
                                    break; 
                                case "RCHGAZ":                                    
                                    $textMessageSMS = str_replace("%idResv%", $transaction->getReservationCode() , $transaction->getService()->getTextFailedPayementSMS()); 
                                    break; 
                                case "SLOYER": 
                                    //$textMessageSMS = str_replace("%idResv%", $transaction->getReservationCode() , $transaction->getService()->getTextSuccessPayementSMS()); 
                                    $textMessageSMS = str_replace("%idResv%", $transaction->getReservationCode() , $transaction->getService()->getTextFailedPayementSMS()); 
                                    break; 
                                case "ESANTE": 
                                    $textMessageSMS = str_replace("%idResv%", $transaction->getReservationCode() , $transaction->getService()->getTextFailedPayementSMS()); 
                                    break; 
                                case "LABBAIK": 
 
                                    $textMessageSMS =  $transaction->getService()->getTextFailedPayementSMS(); 
                                    $labbaikTransRepo = $entityManager->getRepository(LabbaikTransaction::class); 
                                    $labbaikTransaction = $labbaikTransRepo->findOneBy(['sysTransaction' => $transaction]); 
                                    $labbaikTransaction->setTransactionStatus($closeStatus); 
                                    $entityManager->persist($labbaikTransaction); 
                                    //var_dump($textMessageSMS); 
                                    break; 
                            } 
                        } 
                        $transaction->setCloseStatus($closeStatus); 
                 
                        if(strlen($textMessageSMS) > 0){ 
                            //Send SMS 
                            //Send Message and Record SmsHistoy 
                            //SysSMSController::sendSMS($transaction->getMsisdn(),$textMessageSMS); 
                            //var_dump($textMessageSMS); 
                            SysSMSController::sendSMSWithParm($transaction->getMsisdn(),$textMessageSMS,$transaction->getOperator()->getCodeOperator(), $transaction->getService()->getSmsSenderName() ); 
                            $sysSmsHistory = new SysSmsHistory(); 
                            $sysSmsHistory->setMsisdn($transaction->getMsisdn()); 
                            $sysSmsHistory->setMessageText($textMessageSMS); 
                            //$sysSmsHistory->setMessageText($textMessageSMS); 
                            $sysSmsHistory->setCreateTime(new \DateTime); 
                            $sysSmsHistory->setIsReceived(false); 
                            $sysSmsHistory->setTransaction($transaction); 
                            $sysSmsHistory->setSmsType('PAYMENT_MSG'); 
                            $entityManager->persist($sysSmsHistory); 
                            //$entityManager->flush(); 
                        } 
                         
                        if(strlen($textMessageSMSGAZADMIN) > 0){ 
                            //Send SMS 
                            //Send Message and Record SmsHistoy 
                            SysSMSController::sendSMSWithParm("22995000169",$textMessageSMSGAZADMIN,"MOOVBJ", "RESERVLINE" ); 
                            $sysSmsHistory = new SysSmsHistory(); 
                            $sysSmsHistory->setMsisdn("22995000169"); 
                            $sysSmsHistory->setMessageText($textMessageSMSGAZADMIN); 
                            $sysSmsHistory->setCreateTime(new \DateTime); 
                            $sysSmsHistory->setIsReceived(false); 
                            $sysSmsHistory->setTransaction($transaction); 
                            $sysSmsHistory->setSmsType('ADMIN'); 
                            $entityManager->persist($sysSmsHistory); 
                            //$entityManager->flush(); 
                        } 
                        //$transaction->setPayementReference($result["isSuccess"]); 
                        $entityManager->persist($transaction); 
                        $entityManager->flush(); 
                    } 
                } 
            } 
        } 
        //$this->dispatchMessage(new ServicePayment(56,$this->getDoctrine())); 
        $JResponse = new Response(); 
        $JResponse->headers->set('Content-Type', 'application/json', 'charset=utf-8'); 
        $JResponse->setCharset('UTF-8'); 
        $JResponse->setContent(json_encode($resultReponse)); 
        return $JResponse; 
    } 
 
 
    public function payment(int $transctionId, string $referenceId,ManagerRegistry  $doctrineRes){ 
 
        //var_dump("Start paymenet ===>"); 
        $entityManager = $doctrineRes->getManager(); 
        $repoTrans = $doctrineRes->getRepository(SysTransaction::class); 
        $transaction = $repoTrans->find($transctionId); 
        if($transaction->getIsSuccessTransaction() && !$transaction->getIsClosed()){ 
            //sleep(1); 
            //var_dump("2Start paymenet request ===>"); 
            $operateurCode = ""; 
            $payeReferentId = $transaction->getReferenceId() . '+' . $transaction->getReservationCode() . '+' . strVal(rand(111,999)); 
            $payementAmount = ceil(intval($transaction->getServiceTransactionAmount())); 
            if(strcmp($transaction->getOperator()->getCodeOperator(),"MOOVBJ") == 0){ 
                $operateurCode = "MOOVBENIN"; 
            }     
            if(strcmp($transaction->getOperator()->getCodeOperator(),"MTNBJ") == 0){ 
                $operateurCode = "MTNBENIN"; 
            } 
            //$url = "https://caurispay.ridcode.com:8184/payement/requestPayement"; 
            $url = "https://bridgeapi.caurispay.com/payement/requestPayement"; 
            $client = HttpClient::create([ 
                'headers' => [ 
                'User-Agent' => 'ReservLine', 
                'Connection' => 'keep-alive', 
                //'Content-Length' => strlen($body), 
                //'Authorization' => $authorization, 
                //'Content-Type' => 'application/json', 
                'Content-Type: application/x-www-form-urlencoded' 
                 ], 
                'verify_peer' => false, 
                'verify_host' => false, 
                'body' => ['operatorCode' => $operateurCode, 'accountNumber' =>  $transaction->getMsisdn(), 
                           'payementAmount' => $payementAmount, 
                            'currency' => 'CFA', 'transactionType' => 'DEBIT', 
                             'merchantReference' => $payeReferentId, 
                             'merchantComment' => $transaction->getService()->getLibelle()] 
            ]); 
         
            $response = $client->request('POST', $url,['timeout' => 400]); 
            //var_dump("Response code ===>"); 
            //var_dump($response->getStatusCode()); 
             
            //$result["isSuccess"] = false; 
            $result["statusCode"] = $response->getStatusCode(); 
            //var_dump($response->toArray()); 
            if($result["statusCode"] == 200 or $result["statusCode"] ==202){ 
                $result["requestResponse"] = $response->toArray(); 
                if($result["requestResponse"]["isSuccess"]){ 
                    $repoClosStatus = $entityManager->getRepository(SysCloseStatus::class); 
                    $closeStatus = $repoClosStatus->findOneBy(["statusCode" => "PDPAYE"]); //TODO: Add service code in condition 
                    $transaction->setCloseStatus($closeStatus); 
                    //$transaction->setClientPayementCanal("CAURISPAY"); 
                    $transaction->setClientPayementTelephone($transaction->getMsisdn()); 
                    $transaction->setClientPayementAccount($transaction->getMsisdn()); 
                    $transaction->setClientPayementStatus($result["requestResponse"]["status"]); 
                    $transaction->setClientPayementReference($payeReferentId); 
                    $transaction->setClientPayementAmount($payementAmount); 
                    //$transaction->setPayementReference($result["isSuccess"]); 
                    $entityManager->persist($transaction); 
                    $entityManager->flush(); 
                } 
            } 
            //var_dump("End paymenet ===>"); 
            return $result; 
        } 
 
    } 
 
 
    public function checkPayementStatus(SysTransaction $transaction,ManagerRegistry  $doctrineRes ){ 
        $entityManager = $doctrineRes->getManager(); 
        $repoTrans = $doctrineRes->getRepository(SysTransaction::class); 
    } 
}