<?php
/**
 * @author Colinet Julien
 */

namespace CpCreation\VitiCore\Bridge\Symfony\Bundle\Payment;

use CpCreation\VitiCore\Behavior\HasPayment;
use CpCreation\VitiCore\Cart\Model\Payment\Etransactions;
use CpCreation\VitiCore\Cart\Repository\PaymentMethodRepository;
use League\ISO3166\ISO3166;
use megastruktur\PhoneCountryCodes;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Intl\Countries;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Serializer\SerializerInterface;

class EtransactionsPayment
{
    const METHOD     = 'e-transactions';
    const TEST_URL   = 'https://recette-tpeweb.e-transactions.fr/php/';
    const PROD_URL   = 'https://tpeweb.e-transactions.fr/php/';
    const DEVISE     = 978;
    const PBX_RETOUR = 'Mt:M;Ref:R;Auto:A;Appel:T;Abo:B;Erreur:E;Trans:S;Pays:Y;Heure:Q;3DSecureVersion:v;Authentification:c,3DSecure:G;Carte4:j;Signature:K;Ip:I';

    private $paymentMethodRepository;
    private $serializer;
    private $router;
    private $paths;
    private $request;

    public function __construct(PaymentMethodRepository $paymentMethodRepository,
        SerializerInterface $serializer,
        RouterInterface $router,
        RequestStack $requestStack,
        $paths
    ) {
        $this->paymentMethodRepository = $paymentMethodRepository;
        $this->serializer              = $serializer;
        $this->router                  = $router;
        $this->request                 = $requestStack;
        foreach ($paths as $key => $path) {
            if ($path['name'] === static::METHOD) {
                $this->paths[$key] = $path;
            }
        }
    }

    public function createData(HasPayment $payment)
    {
        $paymentMethod = $this->paymentMethodRepository->findOneBy(['method' => static::METHOD]);

        /** @var Etransactions $config */
        $config = $this->serializer->denormalize($paymentMethod->getConfiguration(), Etransactions::class);

        if ($config->isProduction()) {
            $data['URL'] = static::PROD_URL;
        } else {
            $data['URL'] = static::TEST_URL;
        }

        $data['PBX_SITE']        = $config->getSite();
        $data['PBX_RANG']        = $config->getRank();
        $data['PBX_IDENTIFIANT'] = $config->getLogin();
        $data['PBX_TOTAL'] = $payment->getTotal();
        $data['PBX_DEVISE'] = static::DEVISE;
        $data['PBX_CMD'] = strtoupper($payment->getToken());
        $data['PBX_PORTEUR'] = $payment->getEmail();
        $data['PBX_REPONDRE_A'] = $this->request->getCurrentRequest()->getUriForPath($this->router->generate($this->paths['etransactions']['response_at'], [], true));
        $data['PBX_EFFECTUE']   = $this->request->getCurrentRequest()->getUriForPath($this->router->generate($this->paths['etransactions']['done'], [], true));
        $data['PBX_REFUSE']     = $this->request->getCurrentRequest()->getUriForPath($this->router->generate($this->paths['etransactions']['refused'], [], true));
        $data['PBX_ANNULE']     = $this->request->getCurrentRequest()->getUriForPath($this->router->generate($this->paths['etransactions']['canceled'], [], true));
        $data['PBX_RETOUR']     = static::PBX_RETOUR;
        $data['PBX_HASH']       = $config->getHmacAlgo();
        $data['PBX_TIME']       = date("c");
        $pbx_nb_produit = $payment->getQuantity();
        $data['PBX_SHOPPINGCART'] = "<?xml version=\"1.0\" encoding=\"utf-8\"?><shoppingcart><total><totalQuantity>".$pbx_nb_produit."</totalQuantity></total></shoppingcart>";
        $iso = new ISO3166();
        $countryValues = $iso->alpha2($payment->getCountry());
        $country_codes = new PhoneCountryCodes();
        $data['PBX_BILLING'] = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Billing><Address><FirstName>".$payment->getFirstname()."</FirstName><LastName>".$payment->getLastname()."</LastName><Address1>".substr($payment->getStreet(), 0, 50)."</Address1><ZipCode>".$payment->getPostalCode()."</ZipCode><City>".$payment->getCity()."</City><CountryCode>".$countryValues["numeric"]."</CountryCode><CountryCodeMobilePhone>".$country_codes->getCodesList()[$countryValues['alpha2']]."</CountryCodeMobilePhone><MobilePhone>".$payment->getPhone()."</MobilePhone></Address></Billing>";
        $msg = "PBX_SITE=".$data['PBX_SITE'].
               "&PBX_RANG=".$data['PBX_RANG'].
               "&PBX_IDENTIFIANT=".$data['PBX_IDENTIFIANT'].
               "&PBX_TOTAL=".$data['PBX_TOTAL'].
               "&PBX_DEVISE=".$data['PBX_DEVISE'].
               "&PBX_CMD=".strtoupper($data['PBX_CMD']).
               "&PBX_PORTEUR=".$data['PBX_PORTEUR'].
               "&PBX_REPONDRE_A=".$data['PBX_REPONDRE_A'].
               "&PBX_EFFECTUE=".$data['PBX_EFFECTUE'].
               "&PBX_REFUSE=".$data['PBX_REFUSE'].
               "&PBX_ANNULE=".$data['PBX_ANNULE'].
               "&PBX_RETOUR=".$data['PBX_RETOUR'].
               "&PBX_HASH=".$data['PBX_HASH'].
               "&PBX_TIME=".$data['PBX_TIME'].
               "&PBX_SHOPPINGCART=".$data['PBX_SHOPPINGCART'].
               "&PBX_BILLING=".$data['PBX_BILLING'];
        $data['PBX_HMAC'] = strtoupper(hash_hmac($data['PBX_HASH'], $msg, pack("H*", $config->getHmacKey())));

        return $data;
    }
}
