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

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

use CpCreation\VitiCore\Behavior\HasPayment;
use CpCreation\VitiCore\Bridge\Symfony\Bundle\Utils\Mailer;
use CpCreation\VitiCore\Cart\Model\Payment\Sherlock2;
use CpCreation\VitiCore\Cart\Repository\PaymentMethodRepository;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Serializer\SerializerInterface;

class Sherlock2Payment
{
    const METHOD  = 'sherlock2';
    const URL     = 'https://sherlocks-payment-webinit.secure.lcl.fr/paymentInit';
    const URLTest = 'https://sherlocks-payment-webinit-simu.secure.lcl.fr/paymentInit';
    const DEVISE  = '978';

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

    public function __construct(PaymentMethodRepository $paymentMethodRepository,
        SerializerInterface $serializer,
        RouterInterface $router,
        RequestStack $requestStack,
        Mailer $mailer,
        $paths
    ) {
        $this->paymentMethodRepository = $paymentMethodRepository;
        $this->serializer              = $serializer;
        $this->router                  = $router;
        $this->request                 = $requestStack;
        $this->mailer                  = $mailer;
        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 Sherlock2 $config */
        $config = $this->serializer->denormalize($paymentMethod->getConfiguration(), Sherlock2::class);

        if (!$config->isProduction()) {
            $data["URL"] = static::URLTest;
        } else {
            $data["URL"] = static::URL;
        }


        $params["automaticResponseUrl"] = $this->request->getCurrentRequest()->getUriForPath($this->router->generate($this->paths['sherlock2']['response_at'], [], true));
        $params["normalReturnUrl"]      = $this->request->getCurrentRequest()->getUriForPath($this->router->generate($this->paths['sherlock2']['done'], [], true));
        $params["merchantId"]           = $config->getMerchantId();
        $params["amount"]               = $payment->getTotal();
        $params["currencyCode"]         = static::DEVISE;
        $firstIntOfMerchantId = (int)$config->getMerchantId()[0];
        if($firstIntOfMerchantId == 0) {
            if (!$config->isProduction()) {
                $params['transactionReference'] = random_int(100000, 999999);
            } else {
                $params["s10TransactionReference.s10TransactionId"] = random_int(100000, 999999);
            }
        }
        $params["orderId"]               = $payment->getToken();
        $params["keyVersion"]            = $config->getKeyVersion();
        $params["customerContact.email"] = $payment->getEmail();
        $params["orderChannel"]          = 'INTERNET';
        $params["transactionOrigin"]     = 'SITE';

        $data['sealAlgorithm'] = "SHA-256";
        $message               = "";

        foreach ($params as $key => $value) {
            $message .= $key."=".$value."|";
        }
        $message                  = substr($message, 0, -1);
        $data['Data']             = $message;
        $data['interfaceVersion'] = "HP_2.42";
        $data['seal']             = strtolower(hash('sha256', utf8_encode($message.$config->getSecretKey())));

        return $data;
    }

    public function valid($response)
    {
        $paymentMethod = $this->paymentMethodRepository->findOneBy(['method' => static::METHOD]);
        $config        = $this->serializer->denormalize($paymentMethod->getConfiguration(), Sherlock2::class);
        $data          = [];
        if ($response) {
            $responseExplode = explode("|", $response['Data']);

            $seal = strtolower(hash('sha256', utf8_encode($response['Data'].$config->getSecretKey())));

            foreach ($responseExplode as $value) {
                $tmp           = explode("=", $value);
                $data[$tmp[0]] = $tmp[1];
            }
            if (array_key_exists('acquirerResponseCode', $data) && array_key_exists('responseCode', $data) && $data['acquirerResponseCode'] == "00" && $data['responseCode'] == "00" && $seal == $response['Seal']) {
                $data['Valid'] = true;
                return $data;
            }
        }
        $data['Valid'] = false;
        return $data;
    }
}
