<?php

namespace common\modules\orderPayment\WOP\OnlinePayments\Core\Bootstrap\ApiFacades\PaymentProcessor\Proxies\Transformers;

use common\modules\orderPayment\WOP\OnlinePayments\Core\BusinessLogic\Domain\Checkout\Cart\Cart;
use common\modules\orderPayment\WOP\OnlinePayments\Core\BusinessLogic\Domain\GeneralSettings\PaymentAction;
use common\modules\orderPayment\WOP\OnlinePayments\Core\BusinessLogic\Domain\GeneralSettings\PaymentSettings;
use common\modules\orderPayment\WOP\OnlinePayments\Core\BusinessLogic\Domain\HostedTokenization\Token;
use common\modules\orderPayment\WOP\OnlinePayments\Core\BusinessLogic\Domain\PaymentMethod\MethodAdditionalData\ThreeDSSettings\ExemptionType;
use common\modules\orderPayment\WOP\OnlinePayments\Core\BusinessLogic\Domain\PaymentMethod\MethodAdditionalData\ThreeDSSettings\ThreeDSSettings;
use common\modules\orderPayment\WOP\OnlinePayments\Core\BusinessLogic\Domain\PaymentMethod\PaymentMethodCollection;
use common\modules\orderPayment\WOP\OnlinePayments\Core\BusinessLogic\Domain\PaymentMethod\PaymentProductId;
use common\modules\orderPayment\WOP\OnlinePayments\Sdk\Domain\CardPaymentMethodSpecificInput;
use common\modules\orderPayment\WOP\OnlinePayments\Sdk\Domain\PaymentProduct130SpecificInput;
use common\modules\orderPayment\WOP\OnlinePayments\Sdk\Domain\PaymentProduct130SpecificThreeDSecure;
use common\modules\orderPayment\WOP\OnlinePayments\Sdk\Domain\RedirectionData;
use common\modules\orderPayment\WOP\OnlinePayments\Sdk\Domain\ThreeDSecure;
/**
 * Class CardPaymentMethodSpecificInputTransformer.
 *
 * @package OnlinePayments\Core\Bootstrap\ApiFacades\PaymentProcessor\Proxies\Transformers
 */
class CardPaymentMethodSpecificInputTransformer
{
    public static function transform(Cart $cart, string $getReturnUrl, ThreeDSSettings $cardsSettings, PaymentSettings $paymentSettings, ?PaymentMethodCollection $paymentMethodCollection = null, ?PaymentProductId $paymentProductId = null, ?Token $token = null, ?PaymentAction $paymentAction = null): CardPaymentMethodSpecificInput
    {
        $paymentMethodConfig = $paymentProductId !== null ? $paymentMethodCollection->get($paymentProductId) : null;
        $cardPaymentMethodSpecificInput = new CardPaymentMethodSpecificInput();
        if (null !== $token) {
            $cardPaymentMethodSpecificInput->setToken($token->getTokenId());
        }
        $redirectionData = new RedirectionData();
        $redirectionData->setReturnUrl($getReturnUrl);
        $threeDSecure = new ThreeDSecure();
        $threeDSecure->setRedirectionData($redirectionData);
        $threeDSecure->setSkipAuthentication(!$cardsSettings->isEnable3ds());
        if (null !== $paymentProductId && PaymentProductId::maestro()->equals($paymentProductId)) {
            $threeDSecure->setSkipAuthentication(\false);
        }
        if ($cardsSettings->isEnable3ds() && $cardsSettings->isEnable3dsExemption() && !$cardsSettings->isEnforceStrongAuthentication() && null !== $cart->getTotalInEUR() && null !== $cardsSettings->getExemptionType()) {
            $threeDSecure->setExemptionRequest($cardsSettings->getExemptionType()->getType());
            $threeDSecure->setSkipAuthentication(\false);
            $threeDSecure->setSkipSoftDecline(\false);
        }
        if ($cardsSettings->isEnforceStrongAuthentication()) {
            $threeDSecure->setChallengeIndicator('challenge-required');
        }
        $acquirerExemption = $cardsSettings->isEnable3ds() && $cardsSettings->getExemptionType() && $cardsSettings->getExemptionType()->equals(ExemptionType::transactionRiskAnalysis()) && $cart->getTotal()->getValue() < $cardsSettings->getExemptionLimit()->getValue();
        if ($cardsSettings->getExemptionType() && $cardsSettings->getExemptionType()->equals(ExemptionType::lowValue()) && $cart->getTotal()->getValue() < $cardsSettings->getExemptionLimit()->getValue()) {
            $threeDSecure->setChallengeIndicator('no-challenge-requested');
        }
        if ($cardsSettings->getExemptionType() && $cardsSettings->getExemptionType()->equals(ExemptionType::transactionRiskAnalysis()) && $cart->getTotal()->getValue() < $cardsSettings->getExemptionLimit()->getValue()) {
            $threeDSecure->setChallengeIndicator('no-challenge-requested-risk-analysis-performed');
        }
        if ($cardsSettings->isEnable3ds()) {
            $paymentProduct130SpecificInput = new PaymentProduct130SpecificInput();
            $paymentProduct130ThreeDSecure = new PaymentProduct130SpecificThreeDSecure();
            $paymentProduct130ThreeDSecure->setUsecase('single-amount');
            $paymentProduct130ThreeDSecure->setNumberOfItems(min($cart->getLineItems()->getQuantitySum(), 99));
            $paymentProduct130ThreeDSecure->setAcquirerExemption($acquirerExemption);
            $paymentProduct130SpecificInput->setThreeDSecure($paymentProduct130ThreeDSecure);
            $cardPaymentMethodSpecificInput->setPaymentProduct130SpecificInput($paymentProduct130SpecificInput);
        }
        $cardPaymentMethodSpecificInput->setThreeDSecure($threeDSecure);
        if ($paymentProductId !== null && $paymentProductId->equals(PaymentProductId::illicado()->getId())) {
            return $cardPaymentMethodSpecificInput;
        }
        $cardPaymentMethodSpecificInput->setAuthorizationMode($paymentSettings->getPaymentAction()->getType());
        if ($paymentAction) {
            $cardPaymentMethodSpecificInput->setAuthorizationMode($paymentAction->getType());
        }
        if ($paymentMethodConfig && $paymentMethodConfig->getPaymentAction()) {
            $cardPaymentMethodSpecificInput->setAuthorizationMode($paymentMethodConfig->getPaymentAction()->getType());
        }
        if ($paymentProductId !== null && $paymentProductId->equals(PaymentProductId::mealvouchers()->getId())) {
            $cardPaymentMethodSpecificInput->setAuthorizationMode(PaymentAction::authorizeCapture()->getType());
        }
        if ($paymentProductId !== null && $paymentProductId->equals(PaymentProductId::chequeVacancesConnect()->getId())) {
            $cardPaymentMethodSpecificInput->setAuthorizationMode(PaymentAction::authorizeCapture()->getType());
        }
        if ($paymentProductId !== null && $paymentProductId->isCardType() && !$paymentProductId->equals(PaymentProductId::cards()->getId())) {
            $cardPaymentMethodSpecificInput->setPaymentProductId($paymentProductId->getId());
        }
        if ($paymentProductId !== null && PaymentProductId::intersolve()->equals($paymentProductId->getId())) {
            $cardPaymentMethodSpecificInput->setAuthorizationMode(PaymentAction::authorizeCapture()->getType());
            if ($paymentMethodCollection && $config = $paymentMethodCollection->get(PaymentProductId::intersolve())) {
                $cardPaymentMethodSpecificInput->setPaymentProductId($config->getAdditionalData()->getProductId()->getId());
            }
        }
        return $cardPaymentMethodSpecificInput;
    }
}
